본문 바로가기
SW 개발/Data 분석 (RDB, NoSQL, Dataframe)

Python KoNLPy와 WordCloud를 활용하여 WordCloud 생성하기 (Sample code 포함)

by Kibua20 2021. 7. 19.

WordCloud는 텍스트 기반의 문서에서 키워드, 단어, 자주 사용하는 단어를 추출하여 핵심 내용을 직관적으로 파악할 수 있도록 그래픽으로 가시화하는 방법입니다.  Python으로 WordCloud를 생성하기 위해서는 아래와 같은 3가지 단계가 필요합니다.

 

  1. KoNLPy와 nltk lib를 사용해서 문서에서 각각의 형태소(≒ 주로 명사인 단어)로 추출 
  2. Collection Counter() 모듈을 사용해서 명사가 언급된 횟수를 계산
  3. WordCloud Lib를 사용하여 형태소(단어) 빈도에 따른 WordCloud 이미지 생성 및 저장

 

한국어 형태소 분석 KoNLPy (Korean NLP in Python)

한국어 자연어 처리 Python 오픈소스인 KoNLPy를 사용합니다.  KoNLPy의 소스 코드와 홈 페이지는 https://github.com/konlpy/konlpy와 https://konlpy.org/ko/latest/ 입니다. KoNLP에서는 Kkma, Twitter, Komoran의  Tokenizer를 지원하며 각각에 대한 성능은 홈페이지에서 확인 가능하며, 이중에서 Twitter 방법을 사용할 예정입니다.

 

KoNLPy 설치

KoNLPy는 Java가 먼저 설치되어 있어야 합니다. 

 

$ sudo apt-get install openjdk-7-jdk 

$ sudo apt-get install python-dev

$ sudo pip3 install konlpy

 

KoNLP는 Lib의 API는 Python으로 구현되어 있지만, 실제 자연어 처리는 Java code에서 처리합니다.  예를 들어 KoNLPy 설치 후 __okt.py 파일에서 __init__() 함수를 확인해보면 kr.lucypark.okt java pakcage를 로딩하는 것을 알 수 있습니다. 

KoNLPy의 Java 모듈

 

 

 

KoNLPy 사용해서 문장에서 명사 단어를 추출

KoNLPy lib는 morphs(), normalize(), nouns(), pos() 등의 형태소 관련해서 다양한 함수를 지원합니다.   noun() 함수를 포함하여 morph(), pos() 함수에 대한 실행 결과는 아래 그림을 참고해주세요.   

 

이 중에서는 WordCloud에서는 noun() 함수를 사용해서 명사를 추출하여 list로 만들고, 이를 빈도에 따라서 WordCloud 그래프로 그릴 예정입니다.  문장에서 Okt (Twitter) 방식으로 형태소를 분석하고 이 중에서 명사를 추출하는 방법은 아래 tokenizer_konlpy()와 같이 구현합니다.  분리한 명사에서 단어의 문자 개수가 1개 이상인 것으로 추출합니다. 

def tokenizer_konlpy(text):
    okt = Okt()
    return [word for word in okt.nouns(text) if len(word) >1]

출처:  https://github.com/chiheon/Korean-NLP

 

Collection Counter() 모듈를 사용해서 단어가 언급된 횟수를 계산

KoNLPy에 의해서 명사인 단어를 추출한 상태에서 다음 단계는 빈도를 계산하는 단계입니다. 빈도를 계산하는 모듈은 Built-in함수의 collection 모듈의 count.most_common() 함수를 사용합니다. 

# count word
count = Counter(noun)

# get most frequent words
noun_list = count.most_common(3000)

 

Counter 모듈에 대한 설명은 https://docs.python.org/ko/3/library/collections.html#collections.Counter에 설명이 있습니다 (아래 그림 참조). 

Collection 의 Counter() 설명

 

 

 

WordCloud Lib를 사용하여 형태소 (단어) 빈도에 따른 WordCloud 이미지 생성  저장

WordCloud 모듈이 설치되어 있지 않은 경우 pip3를 통해서 먼저 wordcloud를 설치해야 합니다.

 

# wordcloud 설치

$ sudo pip3 install wordcloud

 

Python code에서는 아래와 같이 WordCloud 객체를 만들고, wc.generate_from_frequencies()에 단어 list를 전달하고 이미지 파일로 저장합니다.  WordCloud() 객체 생성 시 한글인 경우에는 한글 폰트를 지정하지 않으면 한글이 모두 깨져 나오기 때문에 한글 폰트의 경로를 font_path를 통해서 지정해야 합니다. 

    # Generate a word cloud image
    wc = WordCloud(font_path = './gulim.ttf',
                        background_color = 'white',
                        width=512, height=512,
                        max_font_size=500,
                        max_words=1000)
    wc.generate_from_frequencies(dict(noun_list))
    
    # Save to png
    wc.to_file(output_file)

 

WordCloud 생성 결과와 전체 Sample code

블로그 중 하나를 Text파일로 만들어서 WordCloud 생성하고 PNG로 저장한 결과입니다. KoNLPy는 한글만 처리하고 있기 때문에 한글만 표시되고 있고, 영어도 포함되어 있는 경우에는 nltk 모듈을 사용해서 명사만 추출할 수 있습니다. 

WordCloud 실행 결과

 

Sample Code 위치 (GitHub)

GitHub에 실제 동작하는 sample code를 정리해서 아래 링크에 올렸고,  wdcloud.py 파일을 참고하면 쉽게 사용 가능합니다.

 

GitHub 링크:  https://github.com/kibua20/devDocs/tree/master/word_cloud

GitHub Sample code

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from collections import Counter
from wordcloud import WordCloud
from konlpy.tag import Okt
import nltk

def wordcloud_from_text(input_file, output_file='wordcloud.png'):
    # get text from file
    try:
        with open(input_file, "rb") as f:
            text=f.read().decode('utf8')
    except Exception as e:
        print ('wordcloud_from_text() - %s' %(e))
        return        

    # 예외 처리
    if text == None:
        print ('wordcloud_from_text() text is None')
        return

    # get noun list
    noun_list = get_noun_list(text)

    # 예외 처리 2
    if len(noun_list) < 10:
        print ('wordcloud_from_text() - Too small noun list')
        return

    # Generate a word cloud image
    wc = WordCloud(font_path = './gulim.ttf',
                        background_color = 'white',
                        width=512, height=512,
                        max_font_size=500,
                        max_words=1000)
    wc.generate_from_frequencies(dict(noun_list)) 
    wc.to_file(output_file)
    print ('Create WordCloud:', output_file)

#-------------------------------------------------------------------------------------------------------------------
def get_noun_list(text, method=0):    
    # Sentence to token
    if method == 0:
        # 한국어
        noun = tokenizer_konlpy(text)
    else:
        # 영어
        noun = tokenizer_nltk(text)

    # count word
    count = Counter(noun)

    # get most frequent words
    noun_list = count.most_common(3000)
    return noun_list

#-------------------------------------------------------------------------------------------------------------------
def tokenizer_nltk(text):
    # NNP: 단수 고유명사, VB: 동사, VBP: 동사 현재형, TO: to 전치사, NN: 명사(단수형 혹은 집합형), DT: 관형사
    is_noun = lambda pos : (pos[:2] == 'NN' or pos[:2] == 'NNP')
    tokenized = nltk.word_tokenize(text)
    return [word for (word, pos) in nltk.pos_tag(tokenized) if is_noun(pos)]

#-------------------------------------------------------------------------------------------------------------------
def tokenizer_konlpy(text):
    okt = Okt()
    return [word for word in okt.nouns(text) if len(word) >1]

#-------------------------------------------------------------------------------------------------------------------
if __name__ == '__main__':
    wordcloud_from_text (input_file='test.txt')

 

※ 참고 내용

https://liveyourit.tistory.com/57

https://github.com/chiheon/Korean-NLP

관련 글:

[SW 개발/Python] - Python: JSON 개념과 json 모듈 사용법

[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - Apple App Store 사용자 댓글(리뷰) 데이터 수집하기 (Sample code 포함)

[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - Python Selenium과 BeautifulSoup을 활용하여 Google PlayStore 사용자 리뷰 (댓글) 가져오기 (Sample Code 포함)

[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - Pandas Dataframe 여러 열과 행에 apply() 함수 적용 (Sample code 포함)

[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - Panda Dataframe 날짜 기준으로 데이터 조회 및 처리하기

[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - MariaDB의 Python Connector 설치와 사용 방법

[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - Jupyter Notebook의 업그레이드: Jupyter Lab 설치 및 extension 사용법

[개발환경/우분투] - 대용량 파일을 작은 크기로 분할하는 방법: split

[SW 개발/Android] - Python으로 개발된 Android Apk Decompile Tool: androguard

[SW 개발/Android] - Python BeautifulSoup으로 만든 Apk download 자동화 (Sample code)

[SW 개발/Python] - Python: 날짜와 시간 처리 함수(현재 날짜, 어제 날짜, UTC 시간)

[개발환경/Web Server] - Python: Web Framework Flask 사용하기




댓글