Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

짱이 될거야

2022-09-21: pyspark dataframe에서 okt 사용하기, PicklingError 본문

Today I Learned

2022-09-21: pyspark dataframe에서 okt 사용하기, PicklingError

jeong57 2022. 9. 21. 22:09

Python에서 형태소를 분석할 수 있는 라이브러리로 Konlpy가 있다.

Konlpy 안에서도 여러 방법이 있는데, 그 중에서 특히 Okt는 형태소 분석에 사용되는 사전을 커스터마이징할 수 있고 오타도 대략적으로 잡아줘서 이번에 사용해보게 되었다.

 

환경은 다음과 같다.

우선 hadoop 위에서 spark를 돌리고 spark에서는 pyspark를 활용한다.

spark로 schema을 만들고, 해당 schema에 맞게 csv를 가져와서 dataframe을 만든다.

그 다음에는 dataframe에서 한 행씩 돌려서, 특정 열에 있는 값을 형태소분석 한 값으로 교체한다.

 

여기서 문제는 크게 두 가지였다.

1. dataframe에서 값을 어떻게 변경하는가(기존 값에서 형태소 분석을 한 값으로 바꾸기)

2. PicklingError

 

먼저 첫 번째 문제를 보자.

구글에 나와있는 코드들은 대부분 dataframe에서 특정 열 전체 값을 한 번에 "같은 값"으로 바꾸는 것들이었는데, 나는 각 행의 특정 열 값을 모두 "다른 값"으로 바꿔야 했다.

만약 전자의 경우에는 withColumn을 활용하면 된다.

후자의 경우에 사용할 만한 것으로 foreach와 map을 찾았는데, 나는 값 자체를 교체해야 하기 때문에 map이 더 맞다고 판단했다. 따라서 아래와 같은 코드를 사용하면 된다.

# dataframe -> rdd -> dataframe
df2 = df.rdd.map(lambda x:	# for example, x is a row (x=[1, '나는', 2022-09-21 00:00:00])
	(x[0], morpheme_analysis(x[1]), x[2])	# 1, ['나', '는'], 2022-09-21 00:00:00
    )
df3 = df2.toDF(["index", "content", "date"])
df3.show()

map 함수는 기존 것에서 하나씩 빼면서 다른 곳에다가 집어넣는 방식이기 때문에, 기존 행에서는 열이 10개가 있었다 하더라도 새로운 곳에는 2개나 3개 등 더 적은 열을 넣을 수 있다.

여기서 morpheme_analysis는 값을 넣으면 형태소 분석된 값으로 바꿔주는 함수를 의미한다. 해당 함수 안에서 Okt를 활용하면 된다.

 

 

두 번째 문제, PicklingError

위의 코드를 사용했을 때 문법상 아무 문제가 없는데 계속해서 "PicklingError"가 뜨면서 코드가 실행되지 않았다.

난생 처음 본 에러였는데, 찾아봐도 무슨 말인지 이해가 잘 되지 않았지만 한 가지 분명한 것은 파이썬 코드 내에서 참조가 잘못돼서 그렇다는 것이었다.

찾아본 결과 대부분의 사람들이 아래와 같이 내장변수 __name__으로 해결했다.

if __name__ == "__main__": pass

 

 

내장변수 __name__이 생소해서 찾아본 결과는 다음과 같다.

__name__은 "현재 모듈의 이름"을 담고 있는 python 내장 변수이다.

a.py 파일 안에 __name__이 들어있다고 가정해보자.

만약 python a.py를 함으로써 a 파일을 실행시킨다면 __name__ == __main__ 이다.

만약 b.py에서 a.py를 import 시킴으로써 a 파일이 실행된다면 __name__ == a 이다.

내장변수를 사용하는 이유는, 한 파일에서 다른 파일을 import 해서 거기에 있는 함수를 쓸 경우 여러 번 중복 실행되는 것을 막기 위해 사용하는 것 같다.

(하지만 이게 왜 지금 여기서 필요한지는 잘 모르겠다..)

어쨌든 그래서 나도 내장변수를 사용하기로 했고, 아래와 같이 코드를 바꿨더니 바로 해결됐다.

# 가져온 csv로 dataframe 만들기
def make_df():
	pass

# 형태소 분석기
def check_correct(text):
	pass
    
# if __name__ == "__main__"일 때 실행시킬 함수
def main():
	pass
    
if __name__ == "__main__"
	main()

 

결론

pyspark에서 dataframe을 다루면서 모르는 것들이 정말 많았는데, 구글링을 해봐도 정작 내가 원하는 건 찾을 수가 없었다.

나와 같은 사람들이 구글링을 하다가 내가 정리해둔 것을 보고 많은 도움이 되었으면 좋겠다.

Comments