Word2Vec을 이용한 한국어 관련어 추출과 평가

Posted by 적분 ∫2tdt=t²+c
2017.01.15 21:53 그냥 공부

저번달에 라틴어 관련어를 추출하는데, Word2Vec 기술을 사용해봤는데요, 몇 가지 아쉬운 점들이 있었습니다. 먼저 학습과 관련된 파라메터들을 어떻게 설정하는게 좋을지, 그리고 해당 파라메터가 과연 적절한지 아닐지를 어떻게 판단할지 등에 대한 고민이 전혀 없는 상태에서 단순히 공기어 통계와 비교하는 작업만을 했기 때문이었습니다. 그래서 이를 어떻게 하면 체계화해서 제대로 평가하고 적절한 파라메터를 골라낼 수 있을까 고민을 하다가 전에 사용했던 라틴어 코퍼스보다 크기도 크고, 태깅도 잘된 21세기 세종계획 말뭉치를 이용하기로 결심했어요.

절차는 다음과 같았습니다.

  1. 세종계획 말뭉치에서 불필요한 단어를 골라낸다. (주로, 조사, 어미, 기호 등을 제거하여 명사/동사/형용사/관형사 정도만 남겼습니다)
  2. 다양한 파라메터로 Word2Vec 학습을 시킨다.
  3. 수작업으로 만들어진 한국어 관련 단어 목록을 이용하여 평가한다.
  4. 평가 점수를 바탕으로 도표를 그리면 특정 파라메터가 어떤 값일때에 성능이 더 좋은지 알아낼 수 있다.

평가 방법 고안

제가 궁금했던 점은 과연 Word2Vec 학습 파라메터 중 Window(어떤 단어의 좌우 문맥을 어디까지 살펴볼 것인가)와 Size(단어를 몇 차원에 매핑할 것인가)가 성능에 어떤 영향을 미치는지였습니다.  기본적으로 Word2Vec은 비지도학습의 일종이기 때문에 지도학습에 사용하는것처럼 전체 데이터셋 중 90%는 학습용, 10%는 평가용으로 나누어 사용하는것이 적절하지 않습니다. 그러기 때문에 평가 데이터셋을 만들어야 했죠. 저의 목표는 관련어를 가장 잘 매칭할 수 있는 모델을 찾는 것이었기 때문에 수작업으로 사전을 찾아가면서 한국어 관련어 목록을 약 100개 정도 만들었습니다. (크롤러를 짜서 돌리면 더 큰 평가셋을 얻을 수 있었겠지만 귀찮았던 관계로...)

사랑/NNG 친애

관련/NNG 연관

나타나/VV 출현 등장

발전/NNG 향상 개화 번영

시민/NNG 백성 국민

몸/NNG 몸통

덥/VA 뜨겁 무덥

빠르/VA 잽싸 날쌔 기민하

크/VA 광대하

싫/VA 역겹

울/VV 곡하 통곡 흐느끼

<평가셋 일부 예시> 제일 왼쪽의 단어가 문제가 되고, 오른쪽의 단어들이 답이 되는 식입니다.

Word2Vec 모델에서 어떤 단어의 관련어를 뽑았을때, 원하는 관련어가 꼭 1순위로 나올 일은 적다고 판단하여 단순히 1순위에 있는 단어를 가지고 평가하지 않고, 상위 100개의 관련어를 뽑고, 제가 원하는 관련어의 순위를 보는 식으로 평가방식을 정했습니다.

평가문제) 시민/NNG 백성 국민

모델이 내놓은 답안) >> model.similar_by_word('시민/NNG', 100)

1. 혁명

2. 백성

3. 국민

4. 의원

...

-> 점수 : 0.556

예를 들어 위와 같이 문제에 대한 답이 나왔다고 하면, 우리가 원하는 답이었던 백성, 국민이 2위, 3위에 나왔으므로, 해당 문제에 대한 점수는 순위의 역수를 합한 방식 1/2 + 1/3 = 0.833 으로 매겼습니다. 단, 이 경우 답안의 갯수에 따라 전체 점수의 범위가 움직일 수 있으므로, 해당 문제에서 받을 수 있는 최대의 점수로 나누어서 점수 범위를 정규화시켜주었죠. 위의 예시에서는 1,2위에 답이 나와서 1/1 + 1/2 = 1.5 점을 얻는것이 최대이므로, 0.833 / 1.5를 하여 0.556으로 점수를 정규화하는 식이죠.

이렇게 모든 문제에 대한 점수 평균을 구하여 해당 파라메터가 관련어를 추출하는데 적합한지 아닌지를 판별하기로 했습니다. 평가문제는 고빈도어/중빈도어/저빈도어를 모두 섞어서 만들었지요.


다양한 파라메터로 학습 진행

window는 1, 3, 5, 7, 9 총 5가지 경우를, size는 250부터 450까지를 12.5 구간으로 분할했습니다. 총 85가지 경우를 학습하는데 거의 하루가 걸린듯합니다. 나머지 파라메터는 다음과 같이 고정했습니다.
iteration: 10
alpha: 0.025
min_alpha: 0.0001
seed: 1
method: CBOW
negative: 5

그리고 만들어진 모델들을 평가하여 점수를 뽑아내고 그래프로 그려보았습니다. 긴 시간을 쏟아부었는데 생각보다 결과는 실망스럽더군요.

붉은색: 평균(약 30점), 푸른색: 평균보다 낮음(약 26점), 녹색: 평균보다 높음(약 34점)

Window크기나 Size는 모델의 성능과는 선형적인 관계가 없는듯합니다. 중간중간에 섬이 떠있는것처럼 보여요. 무조건 크기를 키우는것도 답이 아니고, 줄이는것도 답이 아니에요. 사용하는 코퍼스에 따라 어떤 지점에서 성능이 높은지가 달라지는거 같네요. Size:400, Window:5 모델을 사용하기로 결정하고, 관련어를 뽑아보았습니다.


어떤 관련어가 뽑혔나

시민


춥다


남자

(더 많은 예시는 이 페이지에 올려두었으니 살펴보실 수 있습니다.)


어떻게 더 개선할까

다른 Word2Vec 예제에서처럼 남학생 - 남자 + 여자 = 여학생 과 같은 대수 연산도 수행이 가능한 걸 확인했는데, 세종 말뭉치에 포함된 어휘수가 많지는 않아서 유용하게 쓸 정도까지는 안되는듯합니다. 모델 평가 결과에서 볼 수 있듯 파라메터 간 성능차이는 생각보다 극적이지는 않고, 입력하는 학습 데이터가 더 중요한듯합니다. 파라메터를 조절해서 성능을 높이는데에는 한계가 있는 법이죠. 역시나 잘 정제된 대량의 코퍼스를 얻는게 관건이라는걸 다시 한 번 확인해 볼 수 있었습니다.

한국어에도 영어에서처럼 방대한 코퍼스가 있으면 참 좋겠어요. 

저작자 표시 비영리 동일 조건 변경 허락
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
이 댓글을 비밀 댓글로

티스토리 툴바