728x90
06. 토픽 모델링(Topic Modeling) - 20 뉴스그룹¶
- 토픽 모델링이란 문서 집합에 숨어 있는 주제를 찾아내는 것
- 사람이 수행하는 토픽 모델링은 더 함축적인 의미로 문장을 요약하는 것에 반해, 머신러닝 기반의 토픽 모델은 숨겨진 주제를 효과적으로 표현할 수 있는 중심 단어를 함축적으로 추출
- 머신러닝 기반의 토픽 모델링에 사용되는 기법은 LSA(Latent Semantic Analysis)와 LDA(Latent Dirichlet Allocation)
In [1]:
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
# 모토사이클, 야구, 그래픽스, 윈도우즈, 중동, 기독교, 의학, 우주 주제를 추출.
cats = ['rec.motorcycles', 'rec.sport.baseball', 'comp.graphics', 'comp.windows.x',
'talk.politics.mideast', 'soc.religion.christian', 'sci.electronics', 'sci.med' ]
# 위에서 cats 변수로 기재된 category만 추출. featch_20newsgroups( )의 categories에 cats 입력
news_df= fetch_20newsgroups(subset='all',remove=('headers', 'footers', 'quotes'),
categories=cats, random_state=0)
#LDA 는 Count기반의 Vectorizer만 적용합니다.
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)
#LDA 적용 코드
lda = LatentDirichletAllocation(n_components=8, random_state=0)
lda.fit(feat_vect)
def display_topics(model, feature_names, no_top_words):
for topic_index, topic in enumerate(model.components_):
print('Topic #',topic_index)
# components_ array에서 가장 값이 큰 순으로 정렬했을 때, 그 값의 array index를 반환.
topic_word_indexes = topic.argsort()[::-1]
top_indexes=topic_word_indexes[:no_top_words]
# top_indexes대상인 index별로 feature_names에 해당하는 word feature 추출 후 join으로 concat
feature_concat = ' '.join([feature_names[i] for i in top_indexes])
print(feature_concat)
# CountVectorizer객체내의 전체 word들의 명칭을 get_features_names( )를 통해 추출
feature_names = count_vect.get_feature_names()
# Topic별 가장 연관도가 높은 word를 15개만 추출
display_topics(lda, feature_names, 15)
CountVectorizer Shape: (7862, 1000)
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 [ ]:
# 데이터 전처리
from nltk.stem import WordNetLemmatizer
import nltk
import string
remove_punct_dict = dict((ord(punct), None) for punct in string.punctuation)
lemmar = WordNetLemmatizer()
def LemTokens(tokens):
return [lemmar.lemmatize(token) for token in tokens]
def LemNormalize(text):
return LemTokens(nltk.word_tokenize(text.lower().translate(remove_punct_dict)))
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vect = TfidfVectorizer(tokenizer=LemNormalize, stop_words='english' , \
ngram_range=(1,2), min_df=0.05, max_df=0.85 )
#opinion_text 컬럼값으로 feature vectorization 수행
feature_vect = tfidf_vect.fit_transform(document_df['opinion_text'])
=========================================================================
# 군집화
from sklearn.cluster import KMeans
# 3개의 집합으로 군집화
km_cluster = KMeans(n_clusters=3, max_iter=10000, random_state=0)
km_cluster.fit(feature_vect)
cluster_label = km_cluster.labels_
# 소속 클러스터를 cluster_label 컬럼으로 할당하고 cluster_label 값으로 정렬
document_df['cluster_label'] = cluster_label
document_df.sort_values(by='cluster_label')
◎ 군집별 핵심 단어 추출하기¶
- Clusters_centers_라는 속성은 군집의 중심(Centroid)을 기준으로 얼마나 가깝게 위치해 있는지 파악
In [ ]:
# 군집별 top n 핵심단어, 그 단어의 중심 위치 상대값, 대상 파일명들을 반환함.
def get_cluster_details(cluster_model, cluster_data, feature_names, clusters_num, top_n_features=10):
cluster_details = {}
# cluster_centers array 의 값이 큰 순으로 정렬된 index 값을 반환
# 군집 중심점(centroid)별 할당된 word 피처들의 거리값이 큰 순으로 값을 구하기 위함.
centroid_feature_ordered_ind = cluster_model.cluster_centers_.argsort()[:,::-1]
#개별 군집별로 iteration하면서 핵심단어, 그 단어의 중심 위치 상대값, 대상 파일명 입력
for cluster_num in range(clusters_num):
# 개별 군집별 정보를 담을 데이터 초기화.
cluster_details[cluster_num] = {}
cluster_details[cluster_num]['cluster'] = cluster_num
# cluster_centers_.argsort()[:,::-1] 로 구한 index 를 이용하여 top n 피처 단어를 구함.
top_feature_indexes = centroid_feature_ordered_ind[cluster_num, :top_n_features]
top_features = [ feature_names[ind] for ind in top_feature_indexes ]
# top_feature_indexes를 이용해 해당 피처 단어의 중심 위치 상댓값 구함
top_feature_values = cluster_model.cluster_centers_[cluster_num, top_feature_indexes].tolist()
# cluster_details 딕셔너리 객체에 개별 군집별 핵심 단어와 중심위치 상대값, 그리고 해당 파일명 입력
cluster_details[cluster_num]['top_features'] = top_features
cluster_details[cluster_num]['top_features_value'] = top_feature_values
filenames = cluster_data[cluster_data['cluster_label'] == cluster_num]['filename']
filenames = filenames.values.tolist()
cluster_details[cluster_num]['filenames'] = filenames
return cluster_details
def print_cluster_details(cluster_details):
for cluster_num, cluster_detail in cluster_details.items():
print('####### Cluster {0}'.format(cluster_num))
print('Top features:', cluster_detail['top_features'])
print('Reviews 파일명 :',cluster_detail['filenames'][:7])
print('==================================================')
feature_names = tfidf_vect.get_feature_names()
# 각 군집별 중요한 단어 TOP 10 추출
cluster_details = get_cluster_details(cluster_model=km_cluster, cluster_data=document_df,\
feature_names=feature_names, clusters_num=3, top_n_features=10 )
08. 문서 유사도¶
◎ 문서 유사도 측정 방법¶
- 문서와 문서 간의 유사도 비교는 일반적으로 코사인 유사도(Cosine Similarity)를 사용
- 코사인 유사도는 벡터와 벡터 간의 유사도를 비교할 때 벡터의 크기보다는 벡터의 상호 방향성이 얼마나 유사한지에 기반함
- 유사도는 cos는 두 벡터의 내적을 총 벡터 크기의 합으로 나눈 것(즉, 내적 결과를 총 벡터 크기로 정규화(L2 Norm)한 것)
- 문서를 피처 벡터화 변환하면 차원이 매우 많은 희소 행렬이 되기 쉬우며 문서 벡터간의 크기에 기반한 유사도 지표(예를 들어 유클리드 거리 기반 지표)는 정확도가 떨어짐 따라서 cos(코사인)을 사용
In [2]:
import numpy as np
def cos_similarity(v1, v2):
dot_product = np.dot(v1, v2)
l2_norm = (np.sqrt(sum(np.square(v1))) * np.sqrt(sum(np.square(v2))))
similarity = dot_product / l2_norm
return similarity
from sklearn.feature_extraction.text import TfidfVectorizer
doc_list = ['if you take the blue pill, the story ends' ,
'if you take the red pill, you stay in Wonderland',
'if you take the red pill, I show you how deep the rabbit hole goes']
tfidf_vect_simple = TfidfVectorizer()
feature_vect_simple = tfidf_vect_simple.fit_transform(doc_list)
print(feature_vect_simple.shape)
(3, 18)
In [3]:
# TFidfVectorizer로 transform()한 결과는 Sparse Matrix이므로 Dense Matrix로 변환.
feature_vect_dense = feature_vect_simple.todense()
#첫번째 문장과 두번째 문장의 feature vector 추출
vect1 = np.array(feature_vect_dense[0]).reshape(-1,)
vect2 = np.array(feature_vect_dense[1]).reshape(-1,)
#첫번째 문장과 두번째 문장의 feature vector로 두개 문장의 Cosine 유사도 추출
similarity_simple = cos_similarity(vect1, vect2 )
print('문장 1, 문장 2 Cosine 유사도: {0:.3f}'.format(similarity_simple))
vect1 = np.array(feature_vect_dense[0]).reshape(-1,)
vect3 = np.array(feature_vect_dense[2]).reshape(-1,)
similarity_simple = cos_similarity(vect1, vect3 )
print('문장 1, 문장 3 Cosine 유사도: {0:.3f}'.format(similarity_simple))
vect2 = np.array(feature_vect_dense[1]).reshape(-1,)
vect3 = np.array(feature_vect_dense[2]).reshape(-1,)
similarity_simple = cos_similarity(vect2, vect3 )
print('문장 2, 문장 3 Cosine 유사도: {0:.3f}'.format(similarity_simple))
문장 1, 문장 2 Cosine 유사도: 0.402
문장 1, 문장 3 Cosine 유사도: 0.404
문장 2, 문장 3 Cosine 유사도: 0.456
In [ ]:
# 사이킷런에서 제공하는 함수 활용
from sklearn.metrics.pairwise import cosine_similarity
similarity_simple_pair = cosine_similarity(feature_vect_simple , feature_vect_simple)
print(similarity_simple_pair)
print('shape:',similarity_simple_pair.shape)
◎ Opinion Review 데이터 세트를 이용한 문서 유사도 측정¶
09. 한글 텍스트 처리 - 네이버 영화 평점 감성 분석¶
- 대표적인 파이썬 기반 한글 형태소 패키지 KoNLPy를 소개
◎ 한글 NLP 처리의 어려움¶
- 한글 언어 처리는 띄어쓰기와 다양한 조사 때문에 다른 언어보다 어려움
◎ KoNLPy 소개¶
- 대표적인 한글 형태소 패키지
- 형태소의 사전적 의미는 단어로서 의미를 가지는 최소 단위로 정의
10. 텍스트 분석 실습 - 캐글 Mercari Price Suggestion Challenge¶
- 생략
11. 정리¶
- 머신러닝 기반의 텍스트 분석 프로세스
1. 사전 정제 작업 등의 텍스트 정규화 작업 수행 2. 이들 단어들을 픽처 벡터화 변환 3. 생성된 피처 벡터 데이터 세트에 머신러닝 모델을 학습, 예측, 평가
- 텍스트 정규화 작업은 텍스트 클렌징 및 대소문자 변경, 단어 토큰화, 의미 없는 단어 필터링, 어근 추출 등 피처 벡터화를 진행하기 이전에 수행하는 다양한 사전 작업
- 텍스트 분류에서는 문서들을 피처 벡터화한 후 로지스틱 회귀를 적용해 문서를 지도학습 방식으로 예측 분류 진행
- 감성 분석에서는 지도학습 기반 긍정/부정 이진 분류 방식과 SentiWordNet, VADER와 같은 감성 사전 Lexicon을 이용한 방식 두 가지를 살펴봄
- LDA를 이용해 공통적으로 토픽을 추출하는 토픽 모델링 진행
- 텍스트 군집화는 K-평균 군집화 기법을 이용해 비슷한 문서끼리 군집화했으며 텍스트 유사도 측정에서는 코사인 유사도를 이용해 문서들끼리 얼마나 비슷한지 측정
- KoNLPy 패키지를 이용해 영화 리뷰에 긍정/부정 이진 분류 진행
In [4]:
from IPython.core.display import display, HTML
display(HTML("<style>.container {width:80% !important;}</style>"))
728x90
'Book report > 파이썬 머신러닝 완벽가이드' 카테고리의 다른 글
[파이썬 머신러닝 완벽가이드] 08. 텍스트 분석(1) (0) | 2023.06.06 |
---|---|
[파이썬 머신러닝 완벽가이드] 07. 군집화 (0) | 2022.09.18 |
[파이썬 머신러닝 완벽가이드] 06. 차원 축소 (0) | 2022.09.12 |
[파이썬 머신러닝 완벽가이드] 05. 회귀 (0) | 2022.09.11 |
[파이썬 머신러닝 완벽가이드] 04. 분류 (0) | 2022.04.24 |