logo

[텍스트 분석] 감성분석

 

실습 준비

파일 열기

import pandas as pd
df = pd.read_excel('yelp.xlsx')
df.head()
reviewsentiment
0Wow... Loved this place.1
1Crust is not good.0
2Not tasty and the texture was just nasty.0
3Stopped by during the late May bank holiday of...1
4The selection on the menu was great and so wer...1

문서 단어 행렬 만들기

from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(max_features=1000, stop_words='english')
dtm = cv.fit_transform(df.review)

x와 y를 지정

x = dtm
y = df.sentiment

데이터 분할

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(
    x,
    y,
    test_size=0.2,   # 20%의 데이터를 테스트용으로 유보
    random_state=42) # 유사난수의 씨앗값 seed을 42로 설정
 

나이브 베이즈 분류

임포트

from sklearn.naive_bayes import BernoulliNB

모델 만들기

model = BernoulliNB()

학습

model.fit(x_train, y_train)

훈련 데이터로 정확도(accuracy) 평가

model.score(x_train, y_train)
0.92125

테스트 데이터로 정확도 평가

model.score(x_test, y_test)
0.765

단어별 확률

prob_df = pd.DataFrame({
    '단어': cv.get_feature_names_out(),
    '비율': model.feature_log_prob_[1] - model.feature_log_prob_[0]
})

상대적으로 긍정 문장에서 많이 나오는 단어

prob_df.sort_values('비율').tail(10)
단어비율
26attentive1.965811
744spot1.965811
221fantastic2.099343
365loved2.099343
12amazing2.159967
472perfect2.217126
208excellent2.322486
32awesome2.504808
153delicious3.155395
268great4.062952

상대적으로 부정 문장에서 많이 나오는 단어

prob_df.sort_values('비율').head(10)
단어비율
37bad-2.688149
392minutes-2.619156
939wasn-2.465005
65bland-2.377994
703slow-2.177323
847took-2.177323
546probably-2.177323
179don-1.972529
816terrible-1.926009
607rude-1.926009
 

로지스틱 회귀분석

임포트

from sklearn.linear_model import LogisticRegressionCV

엘라스틱넷으로 C는 0.001, 0.01, 0.1 세 가지, L1의 비율은 0, 0.5, 1 세 가지를 시도 총 9가지 조합을 시도하여 성능이 가장 좋은 조합을 찾음

model = LogisticRegressionCV(
    penalty='elasticnet', solver='saga', random_state=42,
    Cs=[0.1, 1, 10], l1_ratios=[0, 0.5, 1], max_iter=4000)

학습

model.fit(x_train, y_train)

가장 좋은 C

model.C_
array([1.])

가장 좋은 L1의 비율

model.l1_ratio_
array([0])

훈련 데이터에서 정확도

model.score(x_train, y_train)
0.94125

테스트 데이터에서 정확도

model.score(x_test, y_test)
0.76

단어별 가중치

word_coef = pd.DataFrame({
    '단어': cv.get_feature_names_out(),
    '가중치': model.coef_.flat
})

긍정 단어

word_coef.sort_values('가중치').tail(10)
단어가중치
208excellent1.340621
221fantastic1.439516
250friendly1.524526
364love1.525609
265good1.532660
409nice1.555230
32awesome1.714438
12amazing1.779166
153delicious2.201475
268great2.867876

부정 단어

word_coef.sort_values('가중치').head(10)
단어가중치
37bad-1.448292
179don-1.397359
65bland-1.274375
939wasn-1.225014
392minutes-1.177965
977worst-1.146635
607rude-1.040134
889unfortunately-1.039067
703slow-1.036536
546probably-1.015125

예측

y_pred = model.predict(x_test)

확률로 예측

probs = model.predict_proba(x_test)

긍정 확률만

prob = probs[:, 1]

문턱값에 따라 다르게 예측

import numpy as np
threshold = 0.5 # 문턱값
y_pred = np.where(prob > threshold, 1, 0)
Previous
검색