*앞 부분은 #8-1글을 참고해주세요.
**Python 언어를 사용한 웹 크롤링 + 형태소 분석 + LDA 토픽모델링 툴을 만듭니다. Python 언어를 안다는 전제 하에 간단한 설명만 덧붙였습니다. 지금 올리는 코드는 '호불호'의 구글 검색결과 상위 300개 이미지의 제목을 분석하게끔 설계했습니다.
#외부 라이브러리 받아오기
from tqdm import tqdm
import time
from selenium import webdriver
from bs4 import BeautifulSoup
from selenium.webdriver.common.keys import Keys
import konlpy
from konlpy.tag import Komoran #코모란 형태소분석기, 제목을 모은 다음 그것을 형태소 단위로 쪼개어 토픽 모델링합니다.
komoran=Komoran(userdic='user_dic.txt') #코모란 형태소분석기는 '호불호'라는 핵심 단어를 인식하지 못합니다. 사용자 사전을 통해 인식하게 해줍니다.
#크롤링 범위
title_nums=range(0,300)
#리스트
Title_list=[]
#페이지 열기
FA_url='https://www.google.com/search?q=%ED%98%B8%EB%B6%88%ED%98%B8&sxsrf=ALeKk00EbuGshbJAe8dkk5NFGFKSJZchQA:1591979528843&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiNnLny2fzpAhUNc5QKHZ2KDfoQ_AUoAXoECBcQAw&biw=1707&bih=907'
driver=webdriver.Chrome()
driver.get(FA_url)
#스크롤 내리기
body = driver.find_element_by_css_selector('body')
for i in range(60):
body.send_keys(Keys.PAGE_DOWN)
time.sleep(1)
#파싱
source=driver.page_source
bs=BeautifulSoup(source, 'html.parser')
data=bs.select('div.WGvvNb')
L=list(data)
#크롤링
trial=0
for title in tqdm(title_nums):
each_title=L[trial].text
time.sleep(1)
Title_list.append(each_title)
trial=trial+1
if trial>len(L):
break
#여기까지 오면 Title_list가 각 이미지(300개)들의 제목을 전부 받은 상황입니다.
#토픽 모델링을 위한 특정 형식의 자료 생성(DTM과 Dictionary 형식), 단어 빈도 보기
from gensim import corpora
FA_noun=[] #Title_list의 모든 제목을 형태소분석하여 담아낼 새로운 리스트입니다.
for titles in tqdm(Title_list):
try:
noun=list(term for term in komoran.nouns(titles) if len(term)>1)
except UnicodeDecodeError: #코모란이 이모티콘 등의 특수문자를 처리할 때 오류가 발생하는데 이를 무시하게 해줍니다.
pass
FA_noun.append(noun) #형태소 단위로 분류한 각 단어들이 리스트에 추가됩니다.
FA_dic=corpora.Dictionary(FA_noun) #그 리스트를 바탕으로 단어 빈도별 목록을 생성합니다.
term_freq=FA_dic.cfs #각 단어의 개수를 셉니다.
print(term_freq)
for term in tqdm(FA_dic.token2id.keys()):
for term_id in term_freq.keys():
if FA_dic.token2id[term] == term_id:
term_freq[term] = term_freq.pop(term_id)
a= sorted(FA_dic.cfs.items(), key=lambda x:x[1], reverse=True) #단어 빈도순 정렬
print(a)
FA_dtm=[FA_dic.doc2bow(doc) for doc in FA_noun] #토픽 모델링을 위한 자료 형식인 DTM을 생성합니다.
#토픽 개수 결정 - 최적화된 토픽 모델링을 위해 토픽 개수에 따라 분석의 혼잡도와 일관성을 분석합니다. 이 부분까지 1차적으로 확인해서 최선의 토픽 개수를 정한 후, 2차로 이 부분을 삭제하고 아래의 토픽 모델링 코드를 작동시켜야 합니다.
import gensim
from gensim.models import CoherenceModel
Lda=gensim.models.ldamodel.LdaModel
perplexity_score=[]
coherence_score=[]
for i in [5,10,15,20,25,30]: #제목 개수가 5,10,15,20,25,30인 6가지 경우 각각의 혼잡도와 일관성을 측정해서 바로 윗줄의 두 리스트에 담습니다.
ldamodel=Lda(FA_dtm,
num_topics=i,
id2word=FA_dic,
passes=10
)
perplexity_score.append(ldamodel.log_perplexity(FA_dtm)) #혼잡도
coherence_score.append(CoherenceModel(model=ldamodel, texts=FA_noun, dictionary=FA_dic, coherence='c_v').get_coherence()) #일관성
print(i, 'th process complete')
#혼잡도/일관성 그래프화
import matplotlib.pyplot as plt
plt.plot([5,10,15,20,25,30],perplexity_score)
plt.plot([5,10,15,20,25,30],coherence_score)
#그래프를 보면서 최선의 토픽 개수를 정합니다.
#그 정한 토픽 개수로 토픽 모델링을 진행합니다.
FA_lda=Lda(FA_dtm,
num_topics=10,
id2word=FA_dic,
passes=10
)
topics=FA_lda.print_topics(num_words=5)
for topic in topics: #num_topics=10이므로 10개로 압축된 토픽을 각각 출력합니다.
print(topic)
#시각화 - 각각의 토픽을 2차원 공간에서 시각적으로 나타냅니다.
import pyLDAvis.gensim
vis=pyLDAvis.gensim.prepare(FA_lda,
FA_dtm,
FA_dic)
pyLDAvis.save_html(vis, '호불호300LDA.html') #토픽모델링 결과를 html형태로 저장합니다.