ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • KoNLpy 텍스트 빈도수 체크
    카테고리 없음 2020. 3. 5. 00:08

    앞서 웹에 있는 텍스트 데이터를 수집했다면, 이번에는 데이터를 가지고 간단하게 가공해보고 시각화해보는 작업을 할 예정이다. 앱에 대한 사용성 피드백을 체크하던 중, 평점이 낮은 데이터에 대한 리뷰를 가지고 시각화해보는 작업이 사용자 피드백을 점검하는데 효과적일 수 있다는 생각을 하면서 시작하게 됐다.

     

    KoNLpy는 텍스트 마이닝을 위한 라이브러리에서 한국어에 최적되어, 한글을 분석하는데 효과적이다.

    하지만, 윈도우 환경에서는 몇가지 설치 과정이 필요하다. 

     

    1. 자바설치: https://java.com/ko/download/

    2. JPype(>=0.5.7) 다운로드 설치

    * 윈도우 환경 설정: https://blog.naver.com/myincizor/221624979283

     

    윈도우에 KoNLPy 설치 방법!!

    한국어 자연어 처리를 하기 위해서 형태소 분석을 해야 하는 경우 많이 있습니다. ​한국어 형태소 분석기...

    blog.naver.com

     


    우선, 대표적인 라이브러리 twitter와 nltk이다. twitter이외에도 KoNLpy에서는 mecab,코코모와 같은 여러 분석 라이브러리가 있지만, 여기서는 트위터를 활용했다.

    트twitter는 텍스트 데이터를 tokenization(토큰화)하는 과정에 필요하다. 단어를 형태소 별로 구분함으로써 추후에 단어를 분류하거나 다른 단어를 예측할때, 활용성을 높여준다. 다음 nltk는 토큰화된 데이터에서 상위, 하위 빈도가 높은 단어를 뽑아보거나 연관된 맥락의 글을 긁어온다던지, 토큰을 살펼볼 수 있는 다양한 기능을 제공한다. 

    import numpy as np 
    import pandas as pd 
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    %matplotlib inline
    import nltk  
    from subprocess import check_output
    from wordcloud import WordCloud, STOPWORDS
    from konlpy.tag import Twitter

    워드 클라우드는 데이터를 이미지 모양으로 시각화를 지원한다. 텍스트 내용 전체를 보여주기는 좋지만, 상대적으로 텍스트 내용이 깔끔하게 정리되지 않고 직관적이지 않아, 간단하게 찍어보는 수준에서 활용되는 것같다. 

    실제 워드클라우드를 했을때, 텍스트 데이터에서 인사이트를 도출하기는 대단히 힘들다. 왠만하게 정제되지 않은 상태에서 워드 클라우드는 큰 의미가 없어 보인다. 

    data = pd.read_csv("C:/Users/ghkdn/Jupyter/ETC/0301_review.csv")
    def word_cloud_save(data):
        #mpl.rcParams['figure.figsize']=(8.0,6.0)    #(6.0,4.0)
        mpl.rcParams['font.size']=12                #10 
        mpl.rcParams['savefig.dpi']=100             #72 
        mpl.rcParams['figure.subplot.bottom']=.1 


        stopwords = set(STOPWORDS)
        data = pd.read_csv("C:/Users/ghkdn/Jupyter/ETC/0301_review.csv")

        wordcloud = WordCloud(
                                  font_path='C:/Users/ghkdn/Jupyter/ETC/NanumSquareB',
                                  background_color='white',
                                  stopwords=stopwords,
                                  max_words=200,
                                  max_font_size=40, 
                                  random_state=42
                                 ).generate(str(data['내용']))
        wordcloud.to_file("0301_review.png")

    현재 내가 준비한 데이터는 구글 앱스토에서 가져온 리뷰 데이터이다. 속성으로는 평점, 공감수, 리뷰내용, 작성자, 날짜로 되어있다. 

    우선, Twitter 함수를 이용해, 객체를 선언하여, 단어를 토큰, 토큰+형태소(튜플),토큰 중 명사만 등 다양한 형태로 텍스트를 뽑아낼 수 있다.  또한, nltk를 활영하면, 빈도 수가 높은 단어 그리고 키워드와 연관있는 무장등 앞에서 뽑은 토큰을 다양하게 활용할 수 있느 기능이 제공된다.

     

    twit = Twitter()

    data['token_review'] = data['내용'].apply(twit.morphs) #tokenize
    data['tagging'] = data['내용'].apply(twit.pos) #tokenize + 형태소
    data['Noun'] = data['내용'].apply(twit.nouns) # only 명사

    추가된 속성 토큰,형태소,명사토큰
    리스트로 추출

    빈도수 높은 탑10 단어 추출

    해당 키워드와 연관된 맥락 추출

    다음은, 텍스트 데이터 시각화 과정이다. 텍스트 데이터를 리스트로 구성한뒤, counter를 이용해 단어의 빈도 수를 체크하고 빈도수를 matplot을 사용하여 히스토그램으로 시각화해보았습니다. 이때, 한글을 사용할 경우 그래프 아래가 ㅁㅁ처리되는 경우가 발생하는데, 이를 해결하기 위해, font_location = "c:/Windows/Fonts/malgun.ttf" 을 통해, 필기체를 지정하고  font_name = font_manager.FontProperties(fname=font_location).get_name() 폰트매니저를 적용할 경우, 한글이 올바르게 나타나느 것을 확인할 수 있습니다.

    * 일부 글씨체는 안됨. ex. 네이버 나눔 필기체

    from collections import Counter
    import matplotlib
    from matplotlib import font_manager, rc

    matplotlib.rcParams['axes.unicode_minus'] = False   
    #그래프에서 마이너스 기호가 표시되도록 하는 설정입니다. 

    def showGraph(wordInfo):
        
        font_location = "c:/Windows/Fonts/malgun.ttf"
        font_name = font_manager.FontProperties(fname=font_location).get_name()
        rc('font', family=font_name)

        plt.xlabel('주요 단어')
        plt.ylabel('빈도수')
        plt.grid(True)
        
        Sorted_Dict_Values = sorted(wordInfo.values(), reverse=True)
        Sorted_Dict_Keys = sorted(wordInfo, key=wordInfo.get, reverse=True)

        plt.bar(range(len(wordInfo)), Sorted_Dict_Values, align='center')
        plt.xticks(range(len(wordInfo)), list(Sorted_Dict_Keys), rotation='70')

        plt.show()

     

    noun_text = [ take2 for take1 in data['Noun'] for take2 in take1]
    text = nltk.Text(noun_text, name='NMSC')
    count = Counter(text.vocab())
    wordInfo = dict()
    for tags, counts in text.vocab().most_common(30):
        if (len(str(tags)) > 1):
            wordInfo[tags] = counts
            print ("%s : %d" % (tags, counts))
                
    showGraph(wordInfo)

     

     

    추가적으로, 사용자의 리뷰가 주간마다 어느정도 발생하는지를 확인하고자 날짜 속성을 datetime형식으로 바꿔 길이를 체크해보았고 평점에 따라 데이터를 구분하고 길이도 확인해보았습니다. 

    #별점 4개 이상, 3개 이하로 등급 구분

    data['class'] =0
    for i in range(len(data)):
        if data['평점'].loc[i] >=4 :
            data['class'].loc[i] = 'Good'
        else:
            data['class'].loc[i] = 'Bad'

     

    # 평점 같은 데이터 길이 체크 


    data['개수'] = 1
    dataPlot = data[['개수', '평점', '날짜'] ]
    #dataPlot = data.groupby('평점').sum()
    dataPlot = dataPlot.groupby('평점').sum()
    dataPlot
    dataPlot.to_csv("rating.csv")

     

    # 주간 리뷰 데이터 길이 


    data['날짜'] = pd.to_datetime(data['날짜']) # datetime형식으로 자동 변환
    data = data.set_index('날짜')
    data['temp'] =1
    #feature
    weekly_df =data.resample('W-Mon', how ={'temp':np.sum}).fillna(0)
    weekly_df.to_csv("weekly_df.csv")

     

    댓글

Life goes on.