<목차> 1. Word Cloud 예제 2. 코드 분석 |
이전 글인 Treform-4에서는 Word Cloud가 무엇인지를 살펴보았습니다. 또한, Word Cloud를 활용한 논문을 통하여 향후 활용 방안과 한계점을 제시했습니다. 이번 글에서는 Word Cloud 예제를 실제로 구동해보고자 합니다. github에 업로드 되어있는 Treform 코드의 일부를 개수하였기에, 원본 코드와는 일부 차이가 있으므로 최종 생성되는 이미지가 다르다고 의아하게 여기지 않으시길 부탁드립니다.
1. Word Cloud 예제
#_*_ coding:utf-8 _*_
import pyTextMiner as ptm
import stylecloud as styl
from wordcloud import WordCloud
kiwi=ptm.tokenizer.Kiwi(path='./BeautyUserdic.txt')
mecab_ko = ptm.tokenizer.MeCab('C:/mecab/mecab-ko-dic') # Mecab can initialize it's dictionary path
pipeline = ptm.Pipeline(ptm.splitter.NLTK(),
#mecab_ko,
kiwi,
ptm.helper.POSFilter('NN*'), # NN->noun SH->kanji, Sl->foreign language
ptm.helper.SelectWordOnly(),
ptm.helper.StopwordFilter(file='./stopwordsKor.txt'),
ptm.counter.WordCounter())
#corpus = ptm.CorpusFromFile('./test.txt')
corpus=ptm.CorpusFromCSVFile('./naver_blog_content.csv',index=3)#파일 경로 입력
result = pipeline.processCorpus(corpus)
print(result)
print()
doc_collection = []
term_counts = {}
for doc in result:
for sent in doc:
for _str in sent:
doc_collection.append(_str[0])
if _str[0] not in term_counts:
term_counts[_str[0]] = 0
else:
term_counts[_str[0]] = int(term_counts.get(_str[0])) + int(_str[1])
#print(doc_collection)
doc_collection = ' '.join(doc_collection)#making list as str
#print(doc_collection)
word_freq = []
for key, value in term_counts.items():
word_freq.append((value, key))
word_freq.sort(reverse=True)
print(word_freq)
f = open("demo_result.txt", "w", encoding='utf8')
for pair in word_freq:
f.write(pair[1] + '\t' + str(pair[0]) + '\n')
f.close()
# Generate a word cloud image
# the matplotlib way:
import matplotlib.pyplot as plt
# Window's font path
# font_path = 'C:/Windows/Fonts/malgun.ttf'
wordcloud = styl.gen_stylecloud(icon_name='fas fa-circle', font_path='C:/Windows/Fonts/malgun.ttf' ,output_name="styleCloudResult.png",text=doc_collection)
#fontawesome.min.css -> this file contains drawing structure
# Display the generated image:
plt.figure()
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.margins(x=0, y=0)
plt.imshow()
2. 코드 분석
1) import와 각 클래스 객체 생성
import pyTextMiner as ptm
import stylecloud as styl
from wordcloud import WordCloud
kiwi=ptm.tokenizer.Kiwi(path='./BeautyUserdic.txt')
mecab_ko = ptm.tokenizer.MeCab('C:/mecab/mecab-ko-dic') # Mecab can initialize it's dictionary path
pipeline = ptm.Pipeline(ptm.splitter.NLTK(),
#mecab_ko,
kiwi,
ptm.helper.POSFilter('NN*'), # NN->noun SH->kanji, Sl->foreign language
ptm.helper.SelectWordOnly(),
ptm.helper.StopwordFilter(file='./stopwordsKor.txt'),
ptm.counter.WordCounter())
#corpus = ptm.CorpusFromFile('./test.txt')
corpus=ptm.CorpusFromCSVFile('./naver_blog_content.csv',index=3)#파일 경로 입력
result = pipeline.processCorpus(corpus)
앞으로도 이 부분에 있어서는 큰 변화는 없이, 각 예제에서 별도로 사용하는 라이브러리 또는 프레임워크를 불러들일(Import) 예정입니다. 워드 클라우드 예제에서는 pyTextminer와 stylecloud, wodcloud를 불러들였습니다. 하지만 실질적으로는 stylecloud를 활용하고자 합니다. 예제로 활용하는 코드는 Wordcloud가 Masked Worldcloud를 적용한 1.5 버전 이전부터 사용되어왔습니다. 이전에는 Wordcloud에서는 원하는 이미지를 활용하여 하단처럼 생성할 수 없어서 해당 라이브러리의 사용이 빈번하였습니다. 하지만 1.5버전부터는 Wordcloud 라이브러리 자체로도 충분히 해결할 수 있습니다.
예제에서는 형태소 분석기는 Kiwi를 활용하였습니다. 데이터는 네이버 블로그에서 '피부 고민'으로 설정하여 2023-11~2023.1 간의 데이터를 수집하였습니다. 다만, 여기서 주목할 점은 이전의 형태소 분석기 예제들과는 달리 CorpusFromCSVFile을 활용하여 데이터를 불러옵니다. Trform에는 총 8개의 파일을 불러들이는 Class가 있습니다. 이들 중에서 CorpusFromCSVFil은 CSV 형태로 된 파일에서 분석할 데이터가 있는 열(Column)의 데이터를 불러들입니다.
2) 형태소 분석결과 확인과 단어 빈도 추출
doc_collection = []
term_counts = {}
for doc in result:
for sent in doc:
for _str in sent:
doc_collection.append(_str[0])
if _str[0] not in term_counts:
term_counts[_str[0]] = 0
else:
term_counts[_str[0]] = int(term_counts.get(_str[0])) + int(_str[1])
#print(doc_collection)
doc_collection = ' '.join(doc_collection)
단어를 저장할 doc_collection 딕셔너리와 개별 단어 빈도 횟수를 저장할 temr_counts 리스트를 선언하였습니다. 이후 반복문으로 통하여서 개별 단어들의 횟수로 아래와 같이 단위를 좁혀 나아갑니다.
전체 데이터(result) -> 개별 데이터(doc) -> 하나의 문장(sent)->하나의 형태소(_str)
이렇게 개별로 분리한 단어를 term_counts에 저장하여 빈도 수를 분석합니다.
doc_collection = ' '.join(doc_collection)#making list as str
위의 코드 부분에서 의문이 생기실 수 있습니다. 왜 리스트로 만들었던 것을 다시 공백을 포함한 string 형태로 변환을 할까? 라는 의문이 드실 수 있습니다. 해당 부분은 Stylecloud의 method를 보시면, 아래와 같이 정의되어 있습니다.
if isinstance(text, str):
wc.generate_from_text(text)
else: # i.e. a dict of word:value from a CSV
if stopwords: # manually remove stopwords since otherwise ignored
text = {k: v for k, v in text.items() if k not in custom_stopwords}
wc.generate_from_frequencies(text)
wc.recolor(color_func=pal_colors, random_state=random_state)
wc.to_file(output_name)
입력 데이터의 자료형에 따라서, if-else 조건문을 통하여 해당하는 Class의 객체를 생성하고 있습니다.
3) 단어 빈도수 저장
word_freq = []
for key, value in term_counts.items():
word_freq.append((value, key))
word_freq.sort(reverse=True)
print(word_freq)
f = open("demo_result.txt", "w", encoding='utf8')
for pair in word_freq:
f.write(pair[1] + '\t' + str(pair[0]) + '\n')
f.close()
word_freq 딕셔너리(Dictionary)를 선언해주고, 단어와 빈도수를 각각 key와 value로 저장해줍니다. 또한, key값을 기준으로해서 빈도 수에 따라서 sort 함수를 활용하여 정렬했습니다. 필요에 따라서 저와 같이 txt 파일로 저장할 수 있습니다.
4) 이미지 생성
# Generate a word cloud image
# the matplotlib way:
import matplotlib.pyplot as plt
# Window's font path
# font_path = 'C:/Windows/Fonts/malgun.ttf'
wordcloud = styl.gen_stylecloud(icon_name='fas fa-circle', font_path='C:/Windows/Fonts/malgun.ttf' ,output_name="styleCloudResult.png",text=doc_collection)
#fontawesome.min.css -> this file contains drawing structure
# Display the generated image:
plt.figure()
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.margins(x=0, y=0)
plt.imshow()
최종 단계인 이미지 생성입니다. 저는 Stylecloud를 당시에는 활용했으나, 현재는 Wordcloud로도 동일한 결과값을 추출할 수 있습니다. 또한, 현재의 1.7 이상 버전부터는 원하는 이미지를 갖고와서 mask 처리를 통하여 다양한 이미지를 활용하여 워드 클라우드 생성이 가능합니다.
마무리.
1. Wordcloud 이미지를 생성할 수 있다.
2. Wordcloud 라이브러리의 다양한 기능과 원하는 이미지 형태로 추출할 수 있다.
다음 글부터는 동시출현 분석을 진행하고자 합니다.
이번 예제 글은 장학금 지원서 작성으로 약 2주의 간격을 두고서야 게시하게 되었습니다.
현재 계획으로는 동시출현 분석 개념과 zipf's law를 다루는 하나의 차시와 이를 활용한 논문들로 차시를 계획하고 있습니다. 그리고 추가적으로 동시출현 단어 분석에서 주로 사용되는 Gphi의 간단한 사용법을 다루고서는 예제를 다루는 총 4차시로 계획중입니다.