Artificial Intelligence/[파이썬 머신러닝 완벽가이드]
[파이썬 머신러닝 완벽가이드] Chap08-6. 토픽 모델링(Topic Modeling) - 20 뉴스그룹
aiclaudev
2022. 1. 22. 17:58
In [1]:
# - 본 글은 파이썬 머신러닝 완벽 가이드 (권철민 지음)을 공부하며 내용을 추가한 정리글입니다.
# 개인 공부를 위해 만들었으며, 만약 문제가 발생할 시 글을 비공개로 전환함을 알립니다.
In [2]:
# Topic Modeling : 숨어있는 중요 주제를 효과적으로 찾아낼 수 있는 모델을 만드는 과정
# 중심단어를 함축적으로 추출
In [3]:
# Topic Modeling에 자주 사용되는 기법은 LSA(Latent Sematic Analysis)와 LDA(Latent Dirichlet Allocation)
# 이번 챕터에선 LDA를 이용할 것
In [4]:
# 20 뉴스그룹은 20가지의 주제를 가진 뉴스 그룹의 데이터를 가짐
# 이 중 모토사이클, 야구, 그래픽스, 윈도우, 중동, 기독교, 전자공학, 의학의 8개 주제를 추출하고
# 이 텍스트들에 LDA 기반 토픽모델링 적용
In [10]:
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
# 모토사이클, 야구, 그래픽스, 윈도우, 중동, 기독교, 전자공학, 의학 8개의 주제를 추출하기 위한 cats
cats = ['rec.motorcycles', 'rec.sport.baseball', 'comp.graphics', 'comp.windows.x',
'talk.politics.mideast', 'soc.religion.christian', 'sci.electronics', 'sci.med']
# 위에서 cats 변수로 기재된 카테고리만 추출. fetch_20newsgroups()의 categories에 cats 입력
news_df = fetch_20newsgroups(subset = 'all', remove = ('headers', 'footers', 'quotes'),
categories = cats, random_state = 0)
# LDA는 Count기반의 벡터화만 사용
count_vect = CountVectorizer(max_df = 0.95, max_features = 1000, min_df = 2, stop_words = 'english',
ngram_range = (1, 2))
feat_vect = count_vect.fit_transform(news_df.data)
print('CountVectorizer Shape : ', feat_vect.shape)
CountVectorizer Shape : (7862, 1000)
In [11]:
# n_components를 이용하여 토픽 개수를 조절한다
lda = LatentDirichletAllocation(n_components = 8, random_state = 0)
lda.fit(feat_vect)
Out[11]:
LatentDirichletAllocation(n_components=8, random_state=0)
In [12]:
# LatentDirichletAllocation(데이터 세트) 수행 시 LatentDirichletAllocation 객체는 components_ 속성을 가짐
# components_는 개별 토픽별로 각 word 피처가 얼마나 많이 그 토픽에 할당됐는지에 대한 수치(연관도)를 가지고 있음
# 높은 값일수록 해당 word 피처는 그 토픽의 중심 word가 됨
print(lda.components_.shape)
lda.components_
(8, 1000)
Out[12]:
array([[3.60992018e+01, 1.35626798e+02, 2.15751867e+01, ..., 3.02911688e+01, 8.66830093e+01, 6.79285199e+01], [1.25199920e-01, 1.44401815e+01, 1.25045596e-01, ..., 1.81506995e+02, 1.25097844e-01, 9.39593286e+01], [3.34762663e+02, 1.25176265e-01, 1.46743299e+02, ..., 1.25105772e-01, 3.63689741e+01, 1.25025218e-01], ..., [3.60204965e+01, 2.08640688e+01, 4.29606813e+00, ..., 1.45056650e+01, 8.33854413e+00, 1.55690009e+01], [1.25128711e-01, 1.25247756e-01, 1.25005143e-01, ..., 9.17278769e+01, 1.25177668e-01, 3.74575887e+01], [5.49258690e+01, 4.47009532e+00, 9.88524814e+00, ..., 4.87048440e+01, 1.25034678e-01, 1.25074632e-01]])
In [13]:
# components_는 array[8, 4000]으로 구성되어 있음
# 8개의 토픽별로 1000개의 word 피처가 해당토픽별로 연관도 값을 가지고 있음
# 즉, components_array의 0번째 row, 10번째 col에 있는 값은 Topic#0에 대해 피처 벡터화된 행렬에서 10번째 컬럼에
# 해당하는 피처가 Topic #0에 연관되는 수치값을 가지고 있음
In [19]:
# lda_model.components_ 값만으로는 각 토픽별 word 연관도를 보기 어려움
# display_topics()함수를 만들어서 각 토픽별로 연관도가 높은 순으로 Word를 나열해보자.
def display_topics(model, feature_names, no_top_words) :
for topic_index, topic in enumerate(model.components_) :
print('Topic #', topic_index)
# components_array 에서 가장 값이 큰 순으로 정렬했을 때, 그 값의 array 인덱스를 반환
topic_word_indexes = topic.argsort()[::-1]
top_indexes = topic_word_indexes[:no_top_words]
# top_indexes대상인 인덱스별로 feature_names에 해당하는 word feature 추출 후 join으로 concat
feature_concat = ' '.join([feature_names[i] for i in top_indexes])
print(feature_concat)
# CountVectorizer객체 내의 전체 word의 명칭을 get_feature_names()를 통해 추출
feature_names = count_vect.get_feature_names() # 1000개의 word 명칭
# 토픽별 가장 연관도가 높은 word를 15개만 추출
display_topics(lda, feature_names, 15)
Topic # 0 year 10 game medical health team 12 20 disease cancer 1993 games years patients good Topic # 1 don just like know people said think time ve didn right going say ll way Topic # 2 image file jpeg program gif images output format files color entry 00 use bit 03 Topic # 3 like know don think use does just good time book read information people used post Topic # 4 armenian israel armenians jews turkish people israeli jewish government war dos dos turkey arab armenia 000 Topic # 5 edu com available graphics ftp data pub motif mail widget software mit information version sun Topic # 6 god people jesus church believe christ does christian say think christians bible faith sin life Topic # 7 use dos thanks windows using window does display help like problem server need know run
In [20]:
# Topic0 : 명확하지 않고 일반적인 단어가 주를 이룸
# Topic1 : 명확하게 컴퓨터 그래픽스 영역의 주제어 추출
# Topic2 : 기독교에 관련된 주제어 추출
# Topic3 : 의학에 관련된 주제어 추출
# Topic4 : 윈도우 운영체제와 관련된 주제어 추출
# Topic5 : 일반적인 단어로 주제어 추출
# Topic6 : 중동 분쟁 등에 관련된 주제어 추출
# Topic7 : 애매하지만 윈도우 운영체제 관련 주제어 일부 추출
In [ ]:
# - 본 글은 파이썬 머신러닝 완벽 가이드 (권철민 지음)을 공부하며 내용을 추가한 정리글입니다.
# 개인 공부를 위해 만들었으며, 만약 문제가 발생할 시 글을 비공개로 전환함을 알립니다.