이전 포스팅까지 사용하던 IMDb 영화 리뷰 데이터에 감성 분석도 적용해 보겠습니다.
감성 분석을 위해선 각 토큰의 품사가 태깅된 상태의 데이터가 필요하기 때문에 df['pos_tagged_tokens']를 사용해 분석을 진행하겠습니다.
df[['pos_tagged_tokens']]
df['pos_tagged_tokens']는 모든 전처리 단계가 전부 적용되진 않았는데요. 보통 정제 작업에서 제거되는 단어들은 감성 지수가 중립인 경우가 많기 때문에, 전체 결과에 큰 영향을 주진 않습니다. 그래서 품사 태깅까지만 된 데이터를 가지고 실습을 진행해도 큰 문제는 없습니다.
감성 분석
먼저 첫 번째 로우로 감성 분석을 진행해 보고, 해당 코드를 함수로 만들어서 전체 데이터 프레임에도 적용해 볼게요. 하나의 코퍼스로 감성 분석을 하는 전체 코드는 다음과 같습니다.
pos_tagged_words = df['pos_tagged_tokens'][0]
senti_score = 0
for word, tag in pos_tagged_words:
# PennTreeBank 기준 품사를 WordNet 기준 품사로 변경
wn_tag = penn_to_wn(tag)
if wn_tag not in (wn.NOUN, wn.ADJ, wn.ADV, wn.VERB):
continue
# Synset 확인, 어휘 사전에 없을 경우에는 스킵
if not wn.synsets(word, wn_tag):
continue
else:
synsets = wn.synsets(word, wn_tag)
# SentiSynset 확인
synset = synsets[0]
swn_synset = swn.senti_synset(synset.name())
# 감성 지수 계산
word_senti_score = (swn_synset.pos_score() - swn_synset.neg_score())
senti_score += word_senti_score
코드의 한 부분씩 살펴볼게요. 먼저 분석에 활용할 데이터 프레임의 첫 번째 로우에 있는 코퍼스를 pos_tagged_words로 받아옵니다. 그리고 senti_score라는 변수를 만들어 줄게요. 코퍼스의 감성 지수는 해당 코퍼스에 포함된 각 단어들의 감성 지수 합으로 계산합니다. senti_score는 코퍼스 안의 단어들을 하나씩 순회하며 계산한 각 단어 감성 지수의 총합을 저장하는 변수입니다. 초기 값은 0으로 하겠습니다.
pos_tagged_words = df['pos_tagged_tokens'][0]
senti_score = 0
다음으로 품사가 태그 된 각 토큰들을 순회하며 감성 지수를 계산해야 합니다. 그 전에 먼저 PennTreebank Tag로 태깅된 품사를 WordNet Tag 기준으로 바꿀게요. 참고로, PennTreebank Tag에는 있지만 WordNet Tag에는 없는 품사가 있기 때문에 이 경우는 분석에서 제외해야 합니다.
for word, tag in pos_tagged_words:
wn_tag = penn_to_wn(tag)
# WordNet Tag에 포함되지 않는 경우는 제외
if wn_tag not in (wn.NOUN, wn.ADJ, wn.ADV, wn.VERB):
continue
이제 단어와 품사를 이용해 Synset과 SentiSynset을 구합니다. 이때 WordNet 어휘 목록에 없는 단어일 경우에는 Synset을 구할 수 없기 때문에 이 경우도 분석에서 제외합니다.
for word, tag in pos_tagged_words:
# ...
# Synset 확인, 어휘 사전에 없을 경우에는 제외
if not wn.synsets(word, wn_tag):
continue
else:
synsets = wn.synsets(word, wn_tag)
# SentiSynset 확인
synset = synsets[0]
swn_synset = swn.senti_synset(synset.name())
마지막으로 swn_synset의 긍정 지수와 부정 지수를 바탕으로 해당 단어의 감성 지수를 구합니다. 구해진 값은 senti_score에 더해 특정 코퍼스의 전체 단어가 가지는 감성 지수의 총합을 의미합니다.
for word, tag in pos_tagged_words:
# ...
# 감성 지수 계산
word_senti_score = (swn_synset.pos_score() - swn_synset.neg_score())
senti_score += word_senti_score
결과를 확인하면 다음과 같습니다.
print(senti_score)
첫 번째 코퍼스는 부정적인 리뷰인 것으로 확인되네요.
이번 포스팅에서 배운 감성 지수를 구하는 코드를 데이터 프레임 전체에 적용하기 위하여 함수로 만들어 보겠습니다. 해당 함수도 preprocess.py에 추가하고, 다음 포스팅에서도 데이터 프레임 전체 로우에 저장된 코퍼스들의 감성 지수들을 한 번에 확인하고 결과를 비교해 보도록 하겠습니다.
def swn_polarity(pos_tagged_words):
senti_score = 0
for word, tag in pos_tagged_words:
# PennTreeBank 기준 품사를 WordNet 기준 품사로 변경
wn_tag = penn_to_wn(tag)
if wn_tag not in (wn.NOUN, wn.ADJ, wn.ADV, wn.VERB):
continue
# Synset 확인, 어휘 사전에 없을 경우에는 스킵
if not wn.synsets(word, wn_tag):
continue
else:
synsets = wn.synsets(word, wn_tag)
# SentiSynset 확인
synset = synsets[0]
swn_synset = swn.senti_synset(synset.name())
# 감성 지수 계산
word_senti_score = (swn_synset.pos_score() - swn_synset.neg_score())
senti_score += word_senti_score
return senti_score
'Data Analysis > Natural Language Processing(NLP)' 카테고리의 다른 글
SentiWordnet 감성 분석 실습 (0) | 2023.07.05 |
---|---|
감성 분석 결과 확인 (0) | 2023.07.05 |
감성 지수 구하기 실습 (0) | 2023.07.05 |
SentiWordNet (0) | 2023.07.04 |
WordNet (0) | 2023.07.04 |