본문 바로가기
Study

[NLP] 2. Keyword Analysis

by Hwanin99 2024. 8. 19.

키워드 분석

  • 핵심어(keyword)란 텍스트 자료의 중요한 내용을 압축적으로 제시하는 단어 또는 문구이다.
  • 키워드 분석이란 불용어 제거와 어간 추출 및 형태소 분석 등의 자연어 처리를 시행한 후 텍스트에서 많이 등장하는 형태소의 등장 빈도를 분석함으로써 핵심어를 추출하는 것이다.
    • 특정 텍스트 자료에 많이 나타나는 형태소가 그 텍스트 주제를 표출할 가능성이 높다는 가정에 기초한다.
    • 빈도 분석에서 영어의 전치사나 한국어의 조사와 같이 의미를 별로 담고 있지 않은 불용어는 제외하는 것이 좋다.
    • 키워드 분석은 텍스트의 주제 추정, 텍스트 유사도, 검색 엔진의 검색 결과 우선 순위 측정 등 다양하게 사용될 수 있다.

네이버 영화 리뷰 데이터

  • 데이터를 확인해 보면 모두 바이트로 이루어져 있으며, 리뷰 외의 다른 데이터도 존재한다.
import urllib.request

raw = urllib.request.urlopen('https://raw.githubusercontent.com/e9t/nsmc/master/ratings.txt').readlines()
print(raw[:5])
-------------------------------------------
[b'id\tdocument\tlabel\n', b'8112052\t\xec\x96\xb4\xeb\xa6\xb4\xeb\x95\x8c\xeb\xb3\xb4\xea\xb3\xa0 \xec\xa7\x80\xea\xb8\x88\xeb\x8b\xa4\xec\x8b\x9c\xeb\xb4\x90\xeb\x8f\x84 \xec\x9e\xac\xeb\xb0\x8c\xec\x96\xb4\xec\x9a\x94\xe3\x85\x8b\xe3\x85\x8b\t1\n', b'8132799\t\xeb\x94\x94\xec\x9e\x90\xec\x9d\xb8\xec\x9d\x84 \xeb\xb0\xb0\xec\x9a\xb0\xeb\x8a\x94 \xed\x95\x99\xec\x83\x9d\xec\x9c\xbc\xeb\xa1\x9c, \xec\x99\xb8\xea\xb5\xad\xeb\x94\x94\xec\x9e\x90\xec\x9d\xb4\xeb\x84\x88\xec\x99\x80 \xea\xb7\xb8\xeb\x93\xa4\xec\x9d\xb4 \xec\x9d\xbc\xea\xb5\xb0 \xec\xa0\x84\xed\x86\xb5\xec\x9d\x84 \xed\x86\xb5\xed\x95\xb4 \xeb\xb0\x9c\xec\xa0\x84\xed\x95\xb4\xea\xb0\x80\xeb\x8a\x94 \xeb\xac\xb8\xed\x99\x94\xec\x82\xb0\xec\x97\x85\xec\x9d\xb4 \xeb\xb6\x80\xeb\x9f\xac\xec\x9b\xa0\xeb\x8a\x94\xeb\x8d\xb0. \xec\x82\xac\xec\x8b\xa4 \xec\x9a\xb0\xeb\xa6\xac\xeb\x82\x98\xeb\x9d\xbc\xec\x97\x90\xec\x84\x9c\xeb\x8f\x84 \xea\xb7\xb8 \xec\x96\xb4\xeb\xa0\xa4\xec\x9a\xb4\xec\x8b\x9c\xec\xa0\x88\xec\x97\x90 \xeb\x81\x9d\xea\xb9\x8c\xec\xa7\x80 \xec\x97\xb4\xec\xa0\x95\xec\x9d\x84 \xec\xa7\x80\xed\x82\xa8 \xeb\x85\xb8\xeb\x9d\xbc\xeb\x85\xb8 \xea\xb0\x99\xec\x9d\x80 \xec\xa0\x84\xed\x86\xb5\xec\x9d\xb4\xec\x9e\x88\xec\x96\xb4 \xec\xa0\x80\xec\x99\x80 \xea\xb0\x99\xec\x9d\x80 \xec\x82\xac\xeb\x9e\x8c\xeb\x93\xa4\xec\x9d\xb4 \xea\xbf\x88\xec\x9d\x84 \xea\xbe\xb8\xea\xb3\xa0 \xec\x9d\xb4\xeb\xa4\x84\xeb\x82\x98\xea\xb0\x88 \xec\x88\x98 \xec\x9e\x88\xeb\x8b\xa4\xeb\x8a\x94 \xea\xb2\x83\xec\x97\x90 \xea\xb0\x90\xec\x82\xac\xed\x95\xa9\xeb\x8b\x88\xeb\x8b\xa4.\t1\n', b'4655635\t\xed\x8f\xb4\xeb\xa6\xac\xec\x8a\xa4\xec\x8a\xa4\xed\x86\xa0\xeb\xa6\xac \xec\x8b\x9c\xeb\xa6\xac\xec\xa6\x88\xeb\x8a\x94 1\xeb\xb6\x80\xed\x84\xb0 \xeb\x89\xb4\xea\xb9\x8c\xec\xa7\x80 \xeb\xb2\x84\xeb\xa6\xb4\xea\xbb\x98 \xed\x95\x98\xeb\x82\x98\xeb\x8f\x84 \xec\x97\x86\xec\x9d\x8c.. \xec\xb5\x9c\xea\xb3\xa0.\t1\n', b'9251303\t\xec\x99\x80.. \xec\x97\xb0\xea\xb8\xb0\xea\xb0\x80 \xec\xa7\x84\xec\xa7\x9c \xea\xb0\x9c\xec\xa9\x94\xea\xb5\xac\xeb\x82\x98.. \xec\xa7\x80\xeb\xa3\xa8\xed\x95\xa0\xea\xb1\xb0\xeb\x9d\xbc\xea\xb3\xa0 \xec\x83\x9d\xea\xb0\x81\xed\x96\x88\xeb\x8a\x94\xeb\x8d\xb0 \xeb\xaa\xb0\xec\x9e\x85\xed\x95\xb4\xec\x84\x9c \xeb\xb4\xa4\xeb\x8b\xa4.. \xea\xb7\xb8\xeb\x9e\x98 \xec\x9d\xb4\xeb\x9f\xb0\xea\xb2\x8c \xec\xa7\x84\xec\xa7\x9c \xec\x98\x81\xed\x99\x94\xec\xa7\x80\t1\n']

 

  • 데이터를 문자열로 변환하고 리뷰만 추출한다.
raw = [x.decode() for x in raw[1:]]

reviews = []

for i in raw:
  reviews.append(i.split('\t')[1]) # \t는 간격을 탭만큼 띄움.

print(reviews[:5])
------------------------------------------------------------
['어릴때보고 지금다시봐도 재밌어요ㅋㅋ', '디자인을 배우는 학생으로, 외국디자이너와 그들이 일군 전통을 통해 발전해가는 문화산업이 부러웠는데. 사실 우리나라에서도 그 어려운시절에 끝까지 열정을 지킨 노라노 같은 전통이있어 저와 같은 사람들이 꿈을 꾸고 이뤄나갈 수 있다는 것에 감사합니다.', '폴리스스토리 시리즈는 1부터 뉴까지 버릴께 하나도 없음.. 최고.', '와.. 연기가 진짜 개쩔구나.. 지루할거라고 생각했는데 몰입해서 봤다.. 그래 이런게 진짜 영화지', '안개 자욱한 밤하늘에 떠 있는 초승달 같은 영화.']

1. 형태소 분석을 이용한 명사 추출

  • 형태소 분석기 MeCab으로 명사만 추출한다.
from konlpy.tag import Mecab

tagger = Mecab()

nouns = []

for review in reviews:
  for noun in tagger.nouns(review):
    nouns.append(noun)

nouns[:10]
------------------------------------
['때', '디자인', '학생', '외국', '디자이너', '그', '전통', '발전', '문화', '산업']

불용어 사전 만들기

  • 한국어는 명사에서도 상당히 많은 불필요한 단어들이 포함된다.
    • ex) 전 난 일 걸 뭐 줄 만 건 분 개 끝 잼 이거 번 중 듯 때 게 내 말 나 수 거 점 것…
  • 빈도가 너무 커서 분석에 방해되는 단어도 제거가 필요하다.
    • ex) 영화
stop_words = '영화 전 난 일 걸 뭐 줄 만 건 분 개 끝 잼 이거 번 중 듯 때 게 내 말 나 수 거 점 것'
stop_words = stop_words.split(' ')

불용어를 제외하여 형태소 분석 수행

  • 한글 텍스트에 대해서 형태소 분석을 수행한다.
  • 분석으로 추출하는 명사 중에서 불용어에 포함되지 않는 텍스트만 추출하여 저장한다.
nouns = []

for review in reviews:
  for noun in tagger.nouns(review):
    if noun not in stop_words:
      nouns.append(noun)
      
nouns[:10]
-----------------------------------
['디자인', '학생', '외국', '디자이너', '그', '전통', '발전', '문화', '산업', '우리']

2. 단어 빈도수 측정

  • 단어 빈도수 측정에는 collections 라이브러리의 Counter 함수를 이용한다.
  • Counter를 이용하면 각 단어와 그의 빈도수를 딕셔너리로 편리하게 생성이 가능하다.
from collections import Counter

nouns_counter = Counter(nouns)
top_nouns = dict(nouns_counter.most_common(50))
top_nouns

{'연기': 9175,
 '최고': 8813,
 '평점': 8514,
 '스토리': 7163,
 '생각': 6943,
 '드라마': 6896,
 '사람': 6742,
 '감동': 6489,
 '배우': 5893,
 '내용': 5731,
 '감독': 5629,
 '재미': 5479,
 '시간': 5320,
 '년': 4936,
 '사랑': 4741,
 '쓰레기': 4585,
 '작품': 3985,
 '하나': 3923,
 '정도': 3656,
 '이건': 3650,
 '마지막': 3647,
 '액션': 3568,
 '기대': 3465,
 '장면': 3262,
 '이게': 3046,
 '편': 3044,
 '최악': 3019,
 '돈': 2980,
 '이야기': 2947,
 '이해': 2745,
 '애': 2730,
 '명작': 2685,
 '여자': 2678,
 '이상': 2676,
 '처음': 2673,
 '한국': 2640,
 '주인공': 2553,
 '우리': 2531,
 '연출': 2376,
 '때문': 2371,
 '기억': 2364,
 '현실': 2193,
 '마음': 2128,
 '굿': 2110,
 '남자': 2078,
 '결말': 2066,
 '인생': 2060,
 '공포': 2048,
 '전개': 2035,
 '짜증': 2011}

3. 단어 빈도 시각화

막대 그래프

import numpy as np

y_pos = np.arange(len(top_nouns))

plt.figure(figsize = (10,10))
plt.barh(y_pos,top_nouns.values())
plt.title('Word Count')
plt.yticks(y_pos,top_nouns.keys())

plt.show()

단어 빈도 막대 그래프


WordCloud

  • 텍스트에 담겨있는 여러 형태소들의 등장 빈도를 가장 직관적으로 시각화하는 방법이다.
  • 텍스트에 등장하는 단어를 그 등장 빈도에 따라 서로 크기가 다르게 구름 형태로 표현함으로써, 단어의 빈도수를 한번에 알 수 있다.
  • 빈도수만을 시각적으로 표현한 것이기 때문에, 단어들 사이의 연관성이나 의미 구조 등을 분석하는 데는 한계가 있다.

 

  • WordCloud를 이용해 객체를 생성한다.
  • generate_from_frequencies() 함수로 빈도수에 따라 워드클라우드를 생성한다.
from wordcloud import WordCloud

wc = WordCloud(background_color = 'white',font_path = './font/NanumBarunGothic.ttf')
wc.generate_from_frequencies(top_nouns)

 

  • 워드클라우드를 시각화할 때는 imshow() 함수를 사용해야 한다.
figure = plt.figure(figsize = (12,12))
ax = figure.add_subplot(1,1,1)
ax.axis('off')
ax.imshow(wc)

plt.show()

단어 빈도 워드클라우드


Squarify 트리맵 시각화

  • Squarify 라이브러리를 이용해 키워드와 키워드 빈도수를 트리맵으로 나타낸다.
import squarify

norm = mpl.colors.Normalize(vmin = min(top_nouns.values()),
                          vmax = max(top_nouns.values()))
colors=[mpl.cm.Blues(norm(value)) for value in top_nouns.values()]

squarify.plot(label = top_nouns.keys(),
              sizes = top_nouns.values(),
              color = colors,
              alpha = .7)

단어 빈도 트리맵

'Study' 카테고리의 다른 글

[NLP] 6. Topic Modeling  (0) 2024.08.21
[NLP] 5. Semantic Network Analysis  (0) 2024.08.20
[NLP] 4. Document Classification  (0) 2024.08.20
[NLP] 3. Cluster Analysis  (0) 2024.08.19
[NLP] 1. National Language Processing  (0) 2024.08.19