brunch

You can make anything
by writing

C.S.Lewis

by Viel Liebe Jul 28. 2020

#11-1 토픽 모델링 코드

*앞 부분은 #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형태로 저장합니다.

매거진의 이전글 #11 토픽 모델링 결과
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari