본문 바로가기
machine learning

Jupyter에서 Matplotlib 한글 적용하기

by 유주원 2016. 10. 19.

word2vec을 통해 word 들을 vector로 변환하였고, 이를 그래프로 표현해주어야 한다.

(word 간의 분포도를 보고 싶으니깐..)


vector는 3차원만 넘어가도 표현하는데 어려움이 많다. 그래서 이를 위해 tsne라는 것을 사용했다.


tsne는 vector의 차원을 줄여주는 기법 중의 하나로, 가령 예를 들어 3차원의 벡터 공간에 있는 데이터 들을 2차원으로 옮기지만 그들간의 거리는 충분히 유지하면서 옮겨주는 방법이다.


보다 상세한 설명은 아래 슬라이드 참조..


http://sssslide.com/www.slideshare.net/ssuserb667a8/visualization-data-using-tsne


tsne로 좌표 변환하는 python code는 아래와 같이 하면 된다.


import numpy as np

import sklearn.manifold import TSNE


model = TSNE(n_components=2, random_state=0)

np.set_printoptions(suppress=True)

two_d_embeddings = model.fit_transform(arr)



sklearn이 없다는 에러 메시지가 나오면, pip를 통해 sklearn을 설치하자.

numpy가 없다면 numpy도 pip로 설치하자.


$> pip install sklearn


model.fit_transform에서 파라미터로 받는 arr는 np.array 타입이다. 하지만 나같은 경우에는 하나의 word를 200차원의 vector로 만들었고, 200차원짜리가 n 개 저장되어 있는 리스트 형태의 변수를 가지고 있다. 리스트를 np.array로 바꿔주기 위해 아래와 같이 변환하자. 아래와 같이 변환한 후 model.fit_transform에 해당 변수를 집어넣으면 된다.


arr = np.array(vec_list)


이제 tsne로 x,y를 가진 2차원 좌표로 변환이 완료되었다면 ( two_d_embeddings 이 2차원 좌표를 가진 변수이다.) 이제는 matplot을 통해 그림을 그려주자.




import matplotlib.pyplot as plt

import pylab as Plot

%matplotlib inline


Plot.figure(figsize=(30,30), dpi=20)

plt.scatter(two_d_embeddings[:,0], two_d_embeddings[:,1], 10)


for row_id in range(0, len(labels)):

    target_word = labels[row_id]

    x = two_d_embeddings[row_id, 0]

    y = two_d_embeddings[row_id, 1]

    Plot.annotate(target_word, (x,y))


plt.show()


위와 같이 입력하고 실행하면 ascii_code 에러가 발생할 것이다. unicode로 바꿔주자. 처음 import 하는 부분에 아래의 구문을 추가해 주고,


import sys

reload(sys)

sys.setdefaultencoding('utf-8')


Plot.annotate 부분을 아래와 같이 수정하자.


Plt.annotate(str(unicode(target_word)), (x,y))


이렇게 하면 그림은 나오는데 글자들이 깨져서 알아보기가 힘들다.


이유는 matplot에서 한글을 표현해 주는 폰트가 없기 때문인데, 이를 해결하기 위해 matplot에 폰트를 추가할 것이다.


우선 matplot에 어떤 폰트가 적용 가능한지 확인해 보자.


from matplotlib import font_manager, rc


font_manager.get_fontconfig_fonts()


사용 가능한 ttf 목록이 나타날 것이다. 이제 이 목록 리스트에 한글 표현이 가능한 폰트를 추가해 주어야 한다.


ttf 파일은 구했다 가정하고 (나 같은 경우에는 c:\Windows\Fonts에 있는 폰트들을 이용했음.) 이 ttf 파일을 /usr/share/fonts/에 복사해준다. (우분투 기준)


다시 한번 get_fontconfig_fonts()를 실행시켜서 목록을 확인해 보자. 목록이 갱신되지 않았으면 matplot cache를 삭제해 준다.


$> cd ~/.cache/matplotlib

$> rm -rf *


jupyter 커널을 restart 해주고 다시 matplot을 import 한 후 get_fontconfig_fonts()를 호출하면 목록이 갱신되는 것을 확인 할 수 있다.





목록에 추가 되었으면 아래와 같이 입력해서 matplot에 폰트를 추가해 준다.


font_name = font_manager.FontProperties(fname="/usr/share/fonts/HMKMMAG.ttf").get_name()

rc('font', family=font_name)


폰트가 추가되었으면, 이제 다시 위에 그림 그려주는 구문을 실행시켜보자.



위와 같이 나온다면 성공!!!

matplot으로 좌표를 보기 어렵다면 아래와 같이 그림파일로 저장해서 볼 수도 있다. 

위에 그림 그리는 구문의 show 전에 savefig를 시켜주고, show 이후에 close를 시켜주면 된다.


plt.savefig("fig1.png")

plt.show()

plt.close()


<추가> 윈도우 환경에서는 아래의 링크를 따라하자.

https://github.com/zeran4/TrialAndError/blob/master/matplotlib_hangul_display_on_windows10_OK.ipynb