본문 바로가기
[파이썬]/데이터 분석

[데이터 분석] 데이터 빈도분석 및 워드클라우드 시각화

by sung min_Kim 2023. 12. 6.

 본 글에서는 "영화 긍정/부정 리뷰데이터에서 빈도분석 및 워드클라우드 시각화"에 대한 내용을 다룰 것이다. 차례와 사용 툴 및 라이브러리는 아래와 같다.

 [차례]
 첫 번째, 빈도분석과 워드 클라우드
 두 번째, 영화 긍정/부정 리뷰데이터에서 빈도분석 및 워드클라우드 시각화 단계별 수행
 
 [단계]
 리뷰 데이터 필터링 및 분류 >
리뷰 데이터 전처리_정규식 패턴 > 리뷰 데이터 형태소 추출 > 
 리뷰 명사 전처리_한 글자 제외 > 리뷰 명사 빈도분석 > 리뷰 명사 전처리_상위 20개 명사 추출 >
 빈도 시각화 워드클라우드(wordcloud) 시각화

 [사용 툴]
- Jupyter notebook(웹 기반 대화형 코딩 환경)
 
 [사용 라이브러리 및 플러그인]
 - (판다스) pandas
 - (정규식) re
 - (형태소) jpype | konlpy(Okt)
 - (데이터집계) collections(Counter)
 - (워드클라우드)
wordcloud(WordCloud)
 - (시각화) matplotlib.pyplot | matplotlib(font_manager, rc)

 


· 빈도분석과 워드 클라우드


 데이터 빈도분석과 워드클라우드는 텍스트 데이터를 분석하고 이해하는데 아주 중요한 도구이다. 두 기법은 서로 밀접하게 연관되어 있으며, 특히 텍스트 데이터에서 가장 빈번하게 등장하는 단어나 구문을 시각적으로 표현하는데 유용하다.

 먼저, 데이터 빈도분석은 특정 데이터 세트 내에서 각 항목이 얼마나 자주 등장하는지를 측정하는 분석 방법이다. 텍스트 데이터에서는 이를 통해 가장 자주 등장하는 단어나 구문을 파악할 수 있다. 이러한 정보는 텍스트 주제나 특징을 이해하는데 중요한 역할을 한다.

 그리고 이렇게 빈도분석을 통해 얻은 결과를 워드클라우드를 이용해 시각적으로 표현할 수 있다. 워드클라우드는 텍스트 데이터에서 단어의 빈도를 시각적으로 나타내는 그래픽이다. 가장 자주 등장하는 단어는 크게, 덜 자주 등장하는 단어는 작게 표시되어 한눈에 어떤 단어가 중요한지 파악할 수 있다.

 따라서, 빈도분석을 통해 텍스트의 주요 키워드와 트렌드를 파악하고, 워드클라우드를 통해 이를 시각적으로 나타내어 보다 직관적으로 이해할 수 있다. 이 두 방법은 함께 사용함으로써 텍스트 데이터 분석의 효율성을 크게 높일 수 있다.

 


· 사용할 파일 호출하기

 

# 판다스라이브러리 호출
import pandas as pd

# 사용할 파일 불러오기
file_path = "./data/df_new.csv"
df_org = pd.read_csv(file_path)
df_org


 판다스 라이브러리를 호출하여, 데이터 분석에 사용할 파일을 'df_org' 데이터프레임 객체에 저장한다. 이 데이터는 이전에 검증단계를 거쳐 필요한 전처리 과정이 완료된 데이터이다.
 이제 이 'df_org' 데이터프레임을 활용하여, 우리의 주요 분석 목표인 빈도분석과 워드클라우드 생성을 진행할 것이다.

데이터 분석에 사용할 데이터프레임 객체 'df_org'

 


· 리뷰 데이터 필터링 및 분류

 

# 긍정 리뷰 데이터 필터링
pos_reviews = df_org[df_org["label"] == 1]
pos_reviews

# 부정 리뷰 데이터 필터링
neg_reviews = df_org[df_org["label"] == 0]
neg_reviews


 리뷰 데이터를 '긍정'과 '부정'으로 분류하기 위해 데이터 필터링 작업을 수행한다. 원본 데이터프레임(df_org)에서' label' 열의 값이 '1'인 경우를 '긍정 리뷰', '0'인 경우를 '부정 리뷰'로 분류한다. 이러한 분류는 각 각의 리뷰 유형에 대 빈도분석과 워드클라우드 시각화를 위해 필요하다.


 코드를 살펴보면, 원본 데이터프레임(df_org)에서 'label' 열의 값이 '1' 또는 '0'인 행을 선택하는 조건식을 대괄호로 묶어 사용하고 있다. 이때 '==' 연산자를 사용하여 'label' 열의 값이 '1' 또는 '0'인지를 판별하며, 이 조건에 맞는 경우 'True', 그렇지 않은 경우 'False'를 반환한다.

 


· 리뷰 데이터 전처리_정규식 패턴

 

# 정규 표현식 라이브러리 활용
improt re

# 긍정 리뷰에서 한글 이외 모두 제거 처리하기
pos_reviews.loc[ : , "comment"] = [re.sub(r"[^ㄱ-ㅣ가-힣+]", 
                                          " ", 
                                          data) for data in pos_reviews["comment"]]


# 부정 리뷰에서 한글 이외 모두 제거 처리하기
neg_reviews.loc[ : , "comment"] = [re.sub(r"[^ㄱ-ㅣ가-힣+]", 
                                          " ", 
                                          data) for data in neg_reviews["comment"]]

 

 정규 표현식 라이브러리(re)를 활용하여 긍정 및 부정 리뷰 데이터프레임에서 'comment' 열의 각 데이터를 순회한다. 각 데이터에서 한글이 아닌 문자가 발견되면 이를 공백으로 대체한다. 이 작업은 긍정 리뷰와 부정 리뷰에 대해 모두 수행된다. 이렇게 정규 표현식을 활용하여 불필요한 문자나 단어를 제거하는 전처리 작업을 수행함으로써, 분석에 중요한 단어들이 더욱 명확하게 도드라지게 되며, 이는 워드클라우드 시각화에서 의미 있는 정보를 더욱 잘 캐치할 수 있게 해 준다.

 코드를 살펴보면, 're.sub()' 함수는 첫 번째 인자로 주어진 패턴을 찾아 두 번째 인자로 대체한다. 여기서는 'r"[^ㄱ-ㅣ가-힣]"' 패턴이 사용되었는데, 이는 한글을 제외한 모든 문자를 찾는다는 의미이다. 세 번째 인자로는 패턴 검색을 수행할 대상인 'comment' 열의 데이터가 사용된다. 따라서 'comment' 열의 한글을 제외한 모든 문자는 공백으로 대체되며, 대체된 값들은 긍정 리뷰와 부정 리뷰 데이터프레임의 'comment' 열의 모든 행 데이터에 대해 각 각 수행된다.

 


· 리뷰 데이터 형태소 추출

 

# 형태소 분석 라이브러리
import jpype

# 한국어 형태소 분석기
from konlpy.tag import Okt

# 긍정 리뷰데이터에서 명사 추출하기
pos_comment_nouns = []

for cmt in pos_reviews["comment"] :
   pos_comment_nouns.extend(okt.nouns(cmt))


# 부정 리뷰데이터에서 명사 추출하기
neg_comment_nouns = []

for cmt in neg_reviews["comment"] :
   neg_comment_nouns.extend(okt.nouns(cmt))

 

 형태소 분석 라이브러리(jpype)와 한국어 형태소 분석기(Okt)를 사용하여, 긍정 리뷰와 부정 리뷰에서 'comment' 열의 데이터에 포함된 명사를 추출하고 있다. 이는 자연어 처리의 한 부분으로 형태소 분석 과정이다. 이 과정을 통해 각 리뷰에 어떤 명사들이 사용되었는지를 파악할 수 있다. 이 정보를 사용하여, 리뷰의 주요 키워드를 분석하는 워드클라우드를 생성하거나, 리뷰의 긍정/부정 여부를 예측하는 모델을 만드는 데 사용할 수도 있다.

 코드를 살펴보면, 'comment' 열의 각 데이터에 'okt.nouns()' 함수를 적용해 문자열이 명사인 데이터를 추출하고, 'extend()' 함수를 사용해 추출한 데이터를 빈 리스트 'pos_comment_nouns'에 추가하고 있다. 이를 통해 모든 긍정 리뷰와 부정 리뷰에서 사용된 명사를 각 각 모을 수 있게 된다.

okt.nouns() => 형태소(명사) 추출

 


· 리뷰 명사 전처리_한 글자는 제외

 

# 긍정 리뷰 명사 중, 한 글자 제외
pos_comment_nouns2 = [w for w in pos_comment_nouns if len(w) > 1]

# 부정 리뷰 명사 중, 한 글자 제외
neg_comment_nouns2 = [w for w in neg_comment_nouns if len(w) > 1]

 
 한 글자 명사를 제외하는 이유는 분석 결과의 정확성을 높이기 위해서이다. 의미가 없어 분석에 필요하지 않은 단어('날', '물', '곳' 등)를 제외함으로써 분석의 품질을 향상할 수 있다.

 코드를 살펴보면 긍정과 부정 리뷰 명사에서 문자열 수가 '1'을 초과하는 데이터들만 추출하여 담고 있다. 

 

명사 전처리

 


· 리뷰 명사 빈도분석

 

# 데이터 집계 도구(Counter) 호출
from collections import Counter

# 긍정 리뷰 명사 빈도분석
pos_word_count = Counter(pos_comment_nouns2)

#부정 리뷰 명사 빈도분석
neg_word_count = Counter(neg_comment_nouns2)


 데이터 집계 도구(Counter)를 활용하여 긍정과 부정 리뷰에서 명사의 빈도분석을 수행한다. 이러한 빈도분석을 통해, 긍정 리뷰와 부정 리뷰에서 어떤 단어(명사)들이 많이 등장하는지를 알 수 있으며, 이렇게 분석된 결과는 시각화 자료로 활용할 수 있다.

 코드를 살펴보면, 'Counter()'를 사용하고 있는데, 이는 다양한 데이터 타입의 요소의 개수를 세어주는 역할을 한다. 'Counter'은 딕셔너리를 상속받은 하위 클래스로, 주어진 객체의 요소의 개수를 세어 딕셔너리 형태로 변환한다. 이때, 각 요소가 키(key)가 되고, 그 개수가 값(value)이 된다.
 

Counter() => 빈도분석

 


· 리뷰 명사 전처리_상위 20개의 명사 추출

 

# 긍정 리뷰 명사의 상위 20건 추출
pos_top_20 = {}
for k, v in pos_word_count.most_common(20) :
	pos_top_20[k] = v

# 부정 리뷰 명사의 상위 20건 추출
neg_top_20 = {}
for k, v in neg_word_count.most_common(20) :
	neg_top_20[k] = v


 긍정과 부정 리뷰에서 상위 20개의 명사를 추출하고 있다. 코드를 살펴보면, 각 명사별 개수를 키(key)와 값(value)으로 가지고 있는 딕셔너리 형태의 'pos_word_count'에 대해, 'Counter' 클래스에서 제공하는 'most_common()'함수를 사용하여 상위 20건에 대한 키(명사)와 값(명사의 개수)을 추출하고 있으며, 추출한 키와 값을 'pos_top_20'의 키와 값으로 입력하고 있다. 'neg_word_count'에 대해서도 동일한 작업을 수행한다.

most_common() => 상위 20건의 데이터 추출

 


· 빈도 시각화

 

# 시각화 라이브러리 호출
import matplotlib.pyplot as plt

# 폰트 설정 라이브러리
from matplotlib import font_manager, rc

# 폰트 설정
plt.rc("font", family="Malgun Gothic")

# 마이너스기호 설정
plt.rcParams["axes.unicode_minus"] = False

 

# 막대 그래프를 이용한 빈도 시각화
plt.figure(figsize=(10, 5))
plt.title("긍정 리뷰의 단어 상위 (20개) 빈도 시각화", fontsize=17)

# 막대그래프 그리기
for key, value in pos_top_20.items() :

    if key == "영화" :
        continue
        
    plt.bar(key, value, color="lightgrey")


# x축, y축 레이블 지정
plt.xlabel("리뷰 명사")
plt.ylabel("빈도(count)")

# x축 기울기 설정
plt.xticks(rotation=70)

# 그래프 출력
plt.show()

 
 빈도분석을 수행한 데이터를 시각화하기 위해, 필요한 시각화 라이브러리를 호출하여 그래프를 생성한다. 그래프는 범주형 데이터의 빈도나 수량 등을 시각적으로 비교하는데 유용한 막대그래프를 사용할 것이다. 각 막대의 길이는 해당 범주의 빈도나 수량을 나타내므로, 각 단어(명사) 별로 얼마나 자주 사용되었는지를 쉽게 파악할 수 있다. '영화'라는 단어는 너무 자주 등장하고, 이 그래프에서 필요성이 낮다고 판단되어 제외하였다.

 코드를 살펴보면, 긍정 리뷰의 단어(명사) 상위 20건에 대한 키(단어)와 값(단어별 개수)을 막대그래프의 x축, y축으로 설정하고, 레이블(이름)을 붙여, 어떤 범주 내에 있는 데이터인지 보기 쉽게 하였다. 이는 부정 리뷰 명사에 대해서도 동일한 동작을 수행한다.

빈도 시각화 => 막대그래프 사용

 


· 워드클라우드(wordcloud) 시각화

 

# 워드클라우드 생성 라이브러리 호출
from wordcloud import WordCloud

plt.figure(figsize=(8, 8))
plt.title("[긍정] 리뷰 단어 워드클라우드 시각화")

# 사용할 폰트 파일 지정
font_path = "C:/Windows/Fonts/malgunsl.ttf"

# 워드클라우드 그래프 속성 설정
wc = WordCloud(
                # 폰트 지정
                font_path=font_path,
                # 배경색 지정
                background_color="ivory",
                # 그래프 너비
                width=800,
                # 그래프 높이
                height=600
            )

# 워드클라우드 그래프에 데이터 넣기
# cloud = wc.generate_from_frequencies(pos_top_20)

# 긍정 전체 단어 넣어보기
cloud = wc.generate_from_frequencies(pos_word_count)

# 워드클라우드 이미지 지정
plt.imshow(cloud)

# x y 좌표축 제외시키기
plt.axis("off")

# 저장하기
plt.savefig("./img/긍정_리뷰_단어_워드클라우드_시각화.png")

plt.show()


 워드클라우드 생성을 위한 라이브러리인 'WordCloud'를 호출하여, 시각화 라이브러리와 함께 사용해 워드클라우드의 시각화를 수행한다. 이를 위해 먼저 클라우드의 크기와 제목을 설정한다.

 그다음 사용할 폰트와 배경색, 그래프의 너비와 높이 등 워드클라우드의 속성을 설정하고, ' WordCloud' 라이브러리에서 제공하는 'wc.generate_from_frequencies()' 함수를 사용해 인자로 설정한 'pos_word_count'로부터 워드클라우드를 생성한다.

 생성된 워드클라우드는 'plt.imshow()' 함수를 통해 이미지 형태로 변환되어 그래프에 표시되며, 이때 'plt.axis("off")' 코드를 통해 x축과 y축의 좌표 정보를 제거하여 깔끔한 시각화를 제공한다.

 마지막으로 'plt.save("경로")'를 이용해 워드클라우드를 이미지 파일로 저장한다. 이렇게 저장된 이미지는 필요할 때 다시 불러와 사용할 수 있다. 최종적으로 'plt.show()'를 호출해 워드클라우드를 화면에 출력한다. 이는 부정 리뷰 명사에 대해서도 동일한 동작을 수행한다.

 

빈도분석을 수행한 데이터에 대한 워드 클라우드 생성

 



긍정 및 부정 리뷰 데이터에서 가장 빈번하게 등장하는 단어를 빈도분석하여
워드클라우드로 시각화하는 단계를 수행하였다. 


원시(기존) 데이터에서 불필요한 부분을 제거하고, 필요한 부분만을 추출하는 과정을 통해 분석하기 좋은 형태로 데이터를 전처리(가공) 하였고, 형태소 분석을 통해 분석 대상이 되는 단어의 빈도수를 파악하기 좋게 전처리(가공)하였다.

위의 과정을 거쳐 빈도분석을 시행하였고, 이 결과를 바탕으로 워드클라우드를 생성하였다. 

이 과정을 숙지하면, 워드클라우드로 나타내고자 하는 데이터를 시각적으로 분석하는데 활용할 수 있을 것이라 생각된다.