텍스트 데이터를 분석하고 이를 바탕으로 다양한 기계학습 알고리즘을 적용시킬 경우 역설적으로 텍스트 데이터를 시각화하는 요구도 커지게 된다. 이를 위해서 많이 사용되는 텍스트 데이터 시각화 방법을 살펴보자.
from nltk.corpus import inaugural
from wordcloud import WordCloud
import matplotlib.pyplot as plt
text = inaugural.raw()
wordcloud = WordCloud(max_font_size=60).generate(text)
plt.figure(figsize=(12,9))
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()
국문 단어구름을 제작하려면 우선 텍스트에서 단어를 생성시킨 후에 각 단어별 빈도수를 생성시켜야 한다. 이를 위해서 형태소 분석기를 통해서 명사를 추출한 후에 빈도를 구한 후에 이를 wordcloud에 넣어 시각화하는 단계를 거치게 된다.
아래와 같이 단어 빈도를 딕셔너리로 제작한 후에 WordCloud()
에 넣는데 한글을 제대로 표현시키려면 한글폰트를 별도 지정하면 한글이 깨지는 문제를 풀 수 있다.
word_freq = {'아이언맨':10, '닥터 스트레인지':7, '캡틴 아메리카':3, '블랙 위도우':2}
wordcloud = WordCloud(font_path='/Library/Fonts/AppleGothic.ttf')
wordcloud = wordcloud.generate_from_frequencies(word_freq)
plt.figure(figsize=(12,9))
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()
nltk.book
을 다음 명령어를 통해서 다운로드 받는다. 그런후에 dispersion plot
을 통해 관심있는 단어가 취임선서 어느 부분에 위치하는지를 파악해본자.
nltk.download('genesis')
nltk.download('nps_chat')
nltk.download('webtext')
nltk.download('treebank')
import nltk
from nltk.book import text4 as inaugural_speeches
plt.figure(figsize=(16,5))
topics = ['citizens', 'democracy', 'freedom', 'duties', 'America','principle','people', 'Government']
inaugural_speeches.dispersion_plot(topics)
Frequency distribution plot은 말뭉치에 포함된 단어 빈도를 뽑아내서 문서 전반을 이해하는데 도움을 준다.
이를 위해서 nltk.FreqDist()
메쏘드를 사용한다. 이 작업과정을 기술하면 다음과 같다.
brown
말뭉치에서 추출할 토픽을 리스트로 정의한다.nltk.FreqDist()
메쏘드를 통해서 가장 빈도수가 많은 단어를 튜플 리스트로 (단어, 빈도수) 형태로 뽑아낸다..most_common()
, .plot()
메쏘드로 고빈도 단어를 뽑아내고 시각화한다.brown
말뭉치가 없는 경우 nltk.download('brown')
명령어로 다운로드 받는다.
from nltk.corpus import brown
from nltk.corpus import stopwords
topics = ['government', 'news', 'religion', 'adventure', 'hobbies']
stop_words = set(stopwords.words('english'))
for topic in topics:
words = [word for word in brown.words(categories=topic)
if word.lower() not in stop_words and word.isalpha() ]
freqdist = nltk.FreqDist(words)
print(topic,'more :', ' , '.join([ word.lower() for word, count in freqdist.most_common(5)]))
freqdist.plot(10)
말뭉치에 포함된 단어를 기준으로 유일무이한 단어 갯수가 얼마인지를 나타내는 지표로 Lexical Diversity(LD)
를 사용한다. 수식으로 표현하면 다음과 같다.
$$\text{Lexical Diversity(LD)} = \frac{\text{유일무이한 단어 갯수}}{\text{총 단어갯수}}$$
만약 특정 말뭉치의 총단어 갯수가 100이고 이를 구성하는 유일무이한 단어가 20이면 Lexical Diversity는 0.2가 된다.
def lexical_diversity(text):
return round(len(set(text)) / len(text),2)
def get_brown_corpus_words(category, include_stop_words=False):
'''helper method to get word array for a particular category
of brown corpus which may/may not include the stopwords that can be toggled
with the include_stop_words flag in the function parameter'''
if include_stop_words:
words = [word.lower() for word in brown.words(categories=category) if word.isalpha() ]
else:
words = [word.lower() for word in brown.words(categories=category)
if word.lower() not in stop_words and word.isalpha() ]
return words
# calculate and print lexical diversity for each genre of the brown corpus
for genre in brown.categories():
lex_div_with_stop = lexical_diversity(get_brown_corpus_words(genre, True))
lex_div = lexical_diversity(get_brown_corpus_words(genre, False))
print(f'{genre:<17}: \t {lex_div:<10} \t {lex_div_with_stop}')
brown 말뭉치 각 쟝르별로 단어 길이를 nltk.ConditionalFreqDist()
메쏘드로 시각화한다.
cfd = nltk.ConditionalFreqDist(
(genre, len(word))
for genre in brown.categories()
for word in get_brown_corpus_words(genre))
plt.figure(figsize=(16,8))
cfd.plot()
N-gram frequency distribution plot은 Word length distribution plot을 확장한 개념이다.
from nltk.util import ngrams
import numpy as np
plt.figure(figsize=(16,8))
for genre in brown.categories():
sol = []
for i in range(1,6):
count = 0
fdist = nltk.FreqDist(ngrams(get_brown_corpus_words(genre), i))
sol.append(len([cnt for ng,cnt in fdist.most_common() if cnt > 1]))
plt.plot(np.arange(1,6), sol, label=genre)
plt.legend()
plt.show()