본문 바로가기

Minding's Programming/Knowledge

카카오톡 메시지로 긍/부정어 감정 분석해보기 (재미로 보는 야구팬들의 감정 분석)

728x90
반응형

내겐 '야구'라는 주제로 뭉친 친구들의 단체 카톡방이 있다. 여느 야구팬들이 보통 그렇듯이, 야구 경기를 보면서 희노애락의 이야기들을 나누곤 한다. 16년차 한화팬인 나는 올 시즌에도 기대에 못 미치는 경기력을 보며 한탄을 하던 도중 문득 궁금해졌다.

 

'이겨도 져도 욕하는 야구라지만 성적이 좀 괜찮다면 욕을 좀 덜하지 않았을까?'

 

하는 생각을 가지고 가볍게 재미를 가지고 카카오톡 메시지를 통해 긍/부정어 분석을 진행해보았다.

 

필요한 라이브러리

import pandas as pd
import torch
from transformers import BertTokenizer, BertForSequenceClassification
from transformers import TextClassificationPipeline
import re
import matplotlib.pyplot as plt
%matplotlib inline

사용한 라이브러리는 데이터를 dataframe으로 변환해 다룰 수 있는 Pandas, BERT 모델을 이용해 긍/부정 점수를 계산할 것이므로 Pytorch, 형태소 분석 및 토크나이저, 파이프라인을 위한 Transformers, txt파일을 다루기 위해 정규 표현식을 쓸 것이므로 re, 그리고 그래프를 그리기 위한 matplotlib이 있다.

 

txt 파일 dataframe으로 변환

카카오톡 내에서 내보내기를 통해 메시지를 txt파일로 받게 되면 아래와 같은 형태로 txt파일이 제공된다.

2022년 7월 11일 오전 8:49, XXX : 일단 화수는 안될 듯 동생 약속잇대
2022년 7월 11일 오전 8:50, XXX : 둘이 화요일에 봐라..

 

이 파일을 단순히 split() 메서드를 통해 나누게 된다면 dataframe의 칼럼으로 다루기가 모호해진다. 그래서 아래와 같이 정규표현식을 이용해 내가 의도한 칼럼 별로 데이터가 나눠지도록 했다.

# 텍스트 파일 불러오기
with open('/content/drive/MyDrive/baseball_talk/chat_data_single_line.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()

# 정규 표현식 패턴
pattern = re.compile(r'(\d{4})년 (\d{1,2})월 (\d{1,2})일 (.*) (\d{1,2}:\d{2}), (.*) : (.*)')

# 결과를 저장할 리스트
parsed_data = []

for line in lines:
    match = pattern.match(line.strip())
    if match:
        year, month, day, ampm, time, speaker, message = match.groups()
        parsed_data.append([year, month, day, ampm, time, speaker, message])

 

그리고 이를 기준으로 dataframe을 만들어준다.

df = pd.DataFrame(parsed_data, columns = ['Year', 'Month', 'Day', 'AMPM', 'Time', 'Speaker', 'Message'])

 

 

긍/부정어  감정 분석

# BERT 모델과 토크나이저 불러오기
model_name = "beomi/kcbert-base"
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name)

이제 긍/부정 감정 분석에 사용할 BERT 모델과 토크나이저를 불러온다. 한국어를 대상으로 하는 분석이기 때문에, kcBERT를 사용했다.

 

# 파이프라인 생성
pipeline = TextClassificationPipeline(model=model, tokenizer=tokenizer, return_all_scores=True)

그 뒤에 위 모델과 토크나이저를 기준으로 긍정/부정어를 나눌 파이프라인을 생성해준 뒤,

 

# 감정 분석 수행
def sentiment_analysis(message):
    results = pipeline(message)
    positive_score = results[0][1]['score']
    negative_score = results[0][0]['score']
    return positive_score, negative_score
    
# 대화 내용에 대해 감정 분석 수행
df['Positive'], df['Negative'] = zip(*df['Message'].map(sentiment_analysis))

sentiment_analysis 함수를 실행시켜 각 메시지에 대한 긍/부정 점수를 매기도록 한다. 이 부분에서 다소 시간이 걸린다. Colab Pro L4 GPU를 사용했을 때 기준으로 8~9분 정도 걸렸던 것 같다. 물론 메시지의 양에 따라 시간은 달라진다.

 

분석 결과 및 시각화

분석 결과에 앞서, 단체 카톡방의 멤버를 먼저 소개한다. 나를 포함해 총 4명이다.

  • 16년차 LG팬
  • 5년차 LG팬
  • 5년차 KIA팬
  • 16년차 한화팬(나)

그래프는 멤버 별 메시지의 긍정 점수 평균과 부정 점수 평균을 나타냈다.

 

그래프를 보면 알겠지만, 응원하는 팀의 성적과는 달리 점수는 생각보다 큰 차이가 없다. 실제 수치로 따져도 0.01~0.05점 차이 정도의 근소한 차이다. (오히려 성적 높은 애들이 더하다.) 2022년의 데이터부터 저장되어 있어서 연도 별로도 비교해봤으나 큰 차이는 없었다.

각 멤버별 긍정/부정 점수 평균

 

물론 kcBERT 모델이 야구의 특성을 고려한 대화흐름을 완벽히 파악하지는 못 했을 것이다. 하지만 모두가 큰 차이 없는 결과를 보니, 응원하는 팀과는 관계없이 '야구팬들은 다 똑같구나' 하는 생각도 든다.

 

그리고 또 하나 놀라운 점은 부정 점수에 비해 긍정점수가 생각보다 높다는 것이다. 어떤 사람은 '야구팬들은 이래도 욕하고 저래도 욕한다'라고 하지만, 야구로 얻는 기쁨과 짜릿함도 그에 못지않게 크다라는 것을 알 수 있었다.

 

이 글을 쓴 날은 야구팬들에게 '지지 않는 날'로 불리우는 월요일이다. 다른 날이었다면 저 단체 카톡방에 한탄을 하느라 이 분석도 못해봤겠지... 막상 데이터를 분석하면서 중간 중간 보이는 메시지들이 '이때 야구 참 재밌게 봤구나' 하는 생각도 떠오르게 해 재밌는 경험으로 남을 것 같다. 그리고 내일도 똑같이 이 시간에 야구를 보고 있을텐데... 한화는 제발 좀 이겨줬으면 좋겠다.

 

728x90