필요한 패키지는 구글에... 다시 쳐봐야 할 것 같다..
Mecab 테스트
import MeCab
m = MeCab.Tagger()
m.parse('안녕하세요. 테스트 입니다.')
'안녕\tNNG,행위,T,안녕,*,*,*,*\n하\tXSV,*,F,하,*,*,*,*\n세요\tEP+EF,*,F,세요,Inflect,EP,EF,시/EP/*+어요/EF/*\n.\tSF,*,*,*,*,*,*,*\n테스트\tNNG,행위,F,테스트,*,*,*,*\n입니다\tVCP+EF,*,F,입니다,Inflect,VCP,EF,이/VCP/*+ᄇ니다/EF/*\n.\tSF,*,*,*,*,*,*,*\nEOS\n'
konlpy Mecab 테스트
konlpy는 한국어 자연어 처리를 위한 파이썬 라이브러리 중 하나로, 다양한 한국어 형태소 분석기를 제공한다.
한국어 형태소 분석을 수행하는 데 사용되며, 일반적으로 텍스트를 형태소 단위로 분해하여 명사, 동사, 형용사 등의 품사를 태깅한다.
from konlpy.tag import Mecab # 소문자로 되어있음
tokenizer = Mecab(dicpath= 'c:/mecab/mecab-ko-dic/').morphs
print(tokenizer('안녕하세요. 테스트 입니다.'))
['안녕', '하', '세요', '.', '테스트', '입니다', '.']
[실습] 한글 영화 감성분석
데이터 로딩 및 확인
- 훈련데이터와 평가데이터가 나뉘어져 파일로 저장되어 있다.
import pandas as pd
train_df = pd.read_csv('./ratings_train.txt', sep='\t', encoding= 'utf-8')
train_df.head()
print(train_df.shape)
(150000, 3)
test_df = pd.read_csv('./ratings_test.txt', sep='\t', encoding= 'utf-8')
test_df.head()
print(test_df.shape)
(50000, 3)
긍정(1), 부정(0) 비율 확인
train_df['label'].value_counts()
label
0 75173
1 74827
Name: count, dtype: int64
test_df['label'].value_counts()
label
1 25173
0 24827
Name: count, dtype: int64
결측치 확인
train_df.isna().sum()
id 0
document 5
label 0
dtype: int64
test_df.isna().sum()
id 0
document 3
label 0
dtype: int64
데이터 전처리
결측치 삭제
train_df.dropna(inplace= True)
test_df.dropna(inplace= True)
id 컬럼 삭제
train_df.drop('id',axis = 1, inplace= True)
test_df.drop('id',axis = 1, inplace= True)
konlpy, Mecab 이용한 단어 토큰화
* mecab = Mecab('c:/mecab/mecab-ko-dic/') 경로 설정 해주어야 한다
from konlpy.tag import Mecab
mecab = Mecab('c:/mecab/mecab-ko-dic/')
tokens = [ mecab.morphs(sentence) for sentence in train_df['document']]
# 형태소 분석해서 단어 단위로 토큰한 것을 하나의 문장으로 다시 재결합
tokens = list(map(lambda x: ' '.join(x), tokens))
tokens[:10]
['아 더 빙 . . 진짜 짜증 나 네요 목소리',
'흠 . .. 포스터 보고 초딩 영화 줄 . ... 오버 연기 조차 가볍 지 않 구나',
'너무 재 밓었다그래서보는것을추천한다',
'교도소 이야기 구먼 . . 솔직히 재미 는 없 다 . . 평점 조정',
'사이몬페그 의 익살 스런 연기 가 돋보였 던 영화 ! 스파이더맨 에서 늙 어 보이 기 만 했 던 커스틴 던스트 가 너무나 도 이뻐 보였 다',
'막 걸음마 뗀 3 세 부터 초등 학교 1 학년 생 인 8 살 용 영화 . ㅋㅋㅋ . .. 별반 개 도 아까움 .',
'원작 의 긴장감 을 제대로 살려 내 지 못했 다 .',
'별 반개 도 아깝 다 욕 나온다 이응경 길용우 연기 생활 이 몇 년 인지 . . 정말 발 로 해도 그것 보단 낫 겟 다 납치 . 감금 만 반복 반복 . . 이 드라마 는 가족 도 없 다 연기 못 하 는 사람 만 모엿 네',
'액션 이 없 는데 도 재미 있 는 몇 안 되 는 영화',
'왜 케 평점 이 낮 은 건데 ? 꽤 볼 만한데 . . 헐리우드 식 화려 함 에 만 너무 길들여져 있 나 ?']
KNU 한글 감성어 사진 로딩
SentiWordNet
감성 분석(긍정적인지 부정적인지 판단)을 수행하기 위한 자원 중 하나로, WordNet은 단어들 간의 상위 및 하위어 관계를 나타내는 시맨틱 네트워크이며, SentiWordNet은 WordNet의 각 단어에 대해 긍정, 부정, 중립적인 정도를 나타내는 감성 점수를 부여한 자원
SentiWordNet의 감성 점수는 각 단어의 긍정성(Positive), 부정성(Negative), 중립성(Neutral)을 -1에서 1 사이의 실수 값으로 나타냅니다. 이 점수는 해당 단어가 가지는 감성적인 의미나 정도를 표현. 양수 값은 긍정적인 감성을 나타내며, 음수 값은 부정적인 감성을 나타냅니다. 0은 중립적인 감성을 나타냄
import json
with open('./SentiWord_info.json', encoding= 'utf-8', mode = 'r') as f:
sentiword_info = json.load(f)
sentiword_dic = pd.DataFrame(sentiword_info)
print(sentiword_dic.shape)
print(sentiword_dic.head())
(14843, 3)
word word_root polarity
0 (-; ( 1
1 (;_;) (;_;) -1
2 (^^) (^^) 1
3 (^-^) (^-^) 1
4 (^^* ( 1
sentiword_dic['polarity'] = sentiword_dic['polarity'].astype(int)
print('감성 최대값:', sentiword_dic['polarity'].max())
print('감성 최소값:', sentiword_dic['polarity'].min())
print('감성 평균값:', round(sentiword_dic['polarity'].mean(),3))
감성 최대값: 2
감성 최소값: -2
감성 평균값: -0.483
sentiword_dic['polarity'].value_counts()
polarity
-1 5029
-2 4797
2 2597
1 2266
0 154
Name: count, dtype: int64
토큰 결과 (토큰화된 문장과 감정사전 비교)
sentiment_score = pd.DataFrame(columns=['review','sentimental_score'])
idx = 0
for token in tokens :
senti_score = 0
for i in range(len(sentiword_dic)):
if sentiword_dic['word'][i] in token: # 감상평 안에 포함되어 있으면
senti_score += sentiword_dic['polarity'][i]
sentiment_score.loc[idx] = [token, senti_score]
idx += 1
오랜 시간이 소요되어 해당 결과를 교수님과 돌려 보지 못했음.
++ 프로젝트 기간 초반에 수업을 진행한 것이라 아직까지 오류 살펴 보지 못함
# 리뷰 감성값 데이터 프레임 저장
# 저장되어있는 피클 파일을 불러와서 사용하면 됨
import joblib
joblib.dump(sentiment_score, './sentiment_score.pkl') # 피클 파일
['./sentiment_score.pkl']
#불러오기
sentiment_score = joblib.load('./sentiment_score.pkl')
감성값 긍/부정 레이블 값으로 치환
sentiment_score['label'] = sentiment_score['sentiment_score'].map(lambda x : 1 if x >= 0 else 0 )
# map 함수를 거치면서 치환됨
# 치환된 값을 가지고 혼동매트릭스
정답과 비교하여 정확도 측정
from sklearn.metrics import accuracy_score, confusion_matrix
cm = confusion_matrix(train_df['label'], sentiment_score['label'])
# 정답과 예측값
print(cm)
print(f'정확도: {accuracy_score(train_df['label'], sentiment_score['label']):.2f}')
추가 분석 사항
- 전처리
한글을 제외한 다른 문자 제거(이모티콘은 날아가겠지만, 감성지수에 초점을 맞춤) -> 제거 결과 아무런 값도 남지 않은 레코드 확인 -> 해당 레코드 삭제
불용어 제거: 한글 불용어 사전은 별도 구성 필요
- 분석
딥러닝의 LSTM 모형 사용 (문맥 기반으로 새로운 문서가 들어왔을때 긍정/부정을 판별)
별도의 감성 사전없이도 사용 가능
'국비 교육 > 머신러닝, 딥러닝' 카테고리의 다른 글
[딥러닝 - 교육 외] LSTM 이란 (0) | 2024.08.01 |
---|---|
[딥러닝 - 교육 외] RNN 이란 (0) | 2024.08.01 |
[텍스트 마이닝] 문서 군집화 (0) | 2024.08.01 |
[텍스트 마이닝] 감정 분석 - [실습] IMDB 영화평 분석 (0) | 2024.08.01 |