1. 단어구름을 만들어보자.
요즘은 무료로 만들어주는 홈페이지가 많이 있는데, 워터마크가 붙어있고, 라이브러리에 자동게시되고 하는게 마음에 안들어서 직접 만들어 보기로 했어요.
이번에도 시놀로지 도커의 Jupyter Notebook 컨테이너에서 했는데, 그냥 로컬호스트에서 Visual Studio Code등으로 했다면 에러를 만나는 횟수가 좀 더 적었을 수 있어요. 근데 그걸 구지 시놀로지를 써보겠다면서 고집부리느라 완성까지 시간이 걸렸습니다. 그런 시간이 살이되고 피가 됬을것이라 생각하면서 기록으로 남겨봐요.
2. wordcloud와 마스킹 이미지
"단어"모음을 "구름"으로 만들려면 기본적으로 필요한 것들 입니다. 텍스트에서 자주쓰이는 단어들을 추출해서, 구름모양 이미지를 이용해서 배치해 주는것이죠. 일단, 예시 코드가 공식홈에 있으니 그대~로 써보는 것에서 출발 했습니다. 이것을 적용하는데 있어서 해결했던 문제들에 대해서 적어보겠습니다.
1) 한국어 폰트가 필요하다.
이건, 진짜 시놀로지에서 구지 하겠다고 고집안하면 안해도 될 걱정이었습니다. 워낙 여러곳에서 정보제공이 많아서.
wc = WordCloud(
font_path='폰트경로',
).generate(text)
이런식으로 워드 클라우드를 생성할때, 폰트 경로를 끊어주어야 하는데, 컨테이너 안에 어떻게 폰트를 넣지??라고 처음에 생각했습니다. 왜냐하면, wordcloud쓰기 전에 Mecab이라는 형태소분석 라이브러리를 쓰는 방법을 맨 처음 살펴봤었는데요, 결국 컨테이너의 루트계정에 접근을 못해서 사전을 업로드 못해 좌절됬었거든요.
터미널로 열어보면 로그인된 유저가 jovyan라고 나오는데, 아니 도대체 jovyan가 누구냐고.(근데 검색해보니 같은 소리 하시는 분들이 수두룩빽빽) sudo가 안되니 apt커맨드도 안먹히고 Mecab을 포기했었습니다. 그런데 이번에도?! 라고 생각했는데, 의외로 겁나 간단하게 해결됬어요. 그냥...Jupyter Notebook의 tree화면에서 upload 버튼 눌러줘서 폰트 업로드 해주면 됩니다. 그리고 경로 잡아주면 됩니다. 좀 허탈하기도하고...?
어쨋든 폰트가 없으면, 글자가 깨져서 사각형만 나옵니다. 꼭 잡아주세요. 아, 폰트는 구글 폰트에서 다운로드 했습니다. 구글 사랑해요.
2) 마스킹 이미지
단어배치의 틀이 될 저 검고 하얀 마스킹이미지를 찾거나 만들거나 해야합니다. 처음엔 찾으려고 했는데, 도~저히 구미에 맞는게 나오질 않아서, 그냥 만들기로 했습니다. 쭉 둘러보니 Openvc라는 라이브러리가 있다고 하고, 관련 게시물도 많이 보여서 가볍게 도전했는데, 비트연산이랑 선형대수가 저를 싫어하다보니...금방 이해할 수는 없었습니다. 뭐 그거 백퍼 이해해야 만들 수 있는 건 아니니까 어찌저찌 만들수는 있었는데 여기서는 자세한 사항 생략하고 다음에 따로 쓸께요.(어떻게 보면 opencv가 더 어려웠던 것 같은)
3. 완성
일단 완성품은 이렇구요...
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from wordcloud import WordCloud, STOPWORDS
with open('./text.txt', mode='r', encoding='UTF-8') as data:
text = data.read()
NGwords = ['A','B','C']
stopwords = set(STOPWORDS)
for NGword in NGwords:
stopwords.add(NGword)
img_mask = np.array(Image.open('/home/jovyan/input/mask.png'))
wc = WordCloud(background_color="black",
max_words=1000,
mask=img_mask,
font_path='/home/jovyan/input/NotoSansKR-Bold.otf',
stopwords=stopwords,
contour_width=5,
contour_color='#282828',
max_font_size=200).generate(text)
# show
plt.figure(figsize=(10,10))
plt.imshow(wc, interpolation='bilinear')
plt.axis("off")
plt.show()
# store to file
wc.to_file("/home/jovyan/output/Done_wordcloud.png")
-with open으로 시작하는 부분에서, 폰트업로드 했던 것 처럼 text파일을 하나 올려놓고, 경로를 끊어줘서 텍스트를 공급합니다.
-stopwords 는 구름에 안들어갔으면 하는 단어들을 넣어줍니다. 이것을 자유자재로 쓰고 싶어 손수 만들었다 해도 과언이 아님.
-저는 테두리 선을 넣었는데요, contour_width로 두께조절이 가능하고, contour_color로 색상조절이 가능한데, 저런 HEX코드뿐만 아니라, 간단하게 black, white이런 단어로도 지정 가능합니다.
-원문은 저번과 똑같이, 제 블로그 글인 블로그, 어디서 만드는게 좋을까? 의 내용을 재료로 만든것입니다. 위에가 마스킹 이미지 없는버젼, 아래가 마스킹 이미지(구름) 씌운 버젼
결론. 데이터분석
요즘에는 채용시장에서 지원자의 서류를 이런식으로 단어추출해서 그 사람이 어떤 특성인 사람인지 좀더 쉽게 파악하려한다고 합니다. 이제까진 python을 주로 웹파싱이나 크롤링을 목적으로 사용했었고 간혹 정말 전통적인 어플리케이션 제작측면에서만 접근하고 했었는데, 이번에 이미지처리등에 있어서의 쓰임새도 살펴볼수 있는 계기가 되었습니다. 피사체를 좌표화해서, 그냥 합쳐버리면 되니 합성도 너무 쉽고해서 놀랐습니다. 이런 구현은 실생활과 엄청 밀접한 것들인 것 같아요. 저는 그냥 따분한 행렬계산용인줄 알았는데...Numpy의 새로운 발견이었습니다.