본문 바로가기

NPL with ML

Python 머신러닝, 한글 감정분석을 위한 리뷰 분석 : 프로그램부터 실전적용까지 (rhinoMorph이용

반응형

한국어 감정분석 관련하여 가장 많이 사용되고 있는 Naver Sentiment Movie Corpus에 대해 알아보겠습니다. 

테스트 파일은 아래와 같습니다.

 

ratings_morphed.txt
9.98MB

 

1. 데이터를 원하는 곳에 위치

리뷰는 data_text에 점수는 data_senti에 입력합니다. data_senti의 값이 1이면 긍정입니다.

import os

def read_data(filename):
    with open(filename, 'r', encoding="cp949") as f:
        data = [line.split('\t') for line in f.read().splitlines()]
        data = data[1:]
    return data

data = read_data(r'C:\Users\HANA\PycharmProjects\HANATOUR\NLP\TEXT_Example\ratings_morphed.txt')
data_text = [line[1] for line in data]    
data_senti = [line[2] for line in data]

 

2. 데이타를 test와 train으로 분류합니다.

stratify옵션의 경우 default는 None입니다. class 비율(ratio)을 train / validation에 유지해 줍니다. (한쪽에 쏠려서 분배되는 것을 방지합니다) 만약 이 옵션을 지정해 주지 않고 classification 문제를 다룬다면, 성능의 차이가 많이 날 수 있습니다.

from sklearn.model_selection import train_test_split

train_data_text, test_data_text, train_data_senti, test_data_senti \
    = train_test_split(
        data_text,
        data_senti,
        stratify=data_senti,
        test_size=0.3,
        random_state=156
)

 

Test와 Train이 잘 나누어졌는지 확인합니다.

from collections import Counter
train_data_senti_freq = Counter(train_data_senti)
print('train_data_senti_freq:', train_data_senti_freq)
test_data_senti_freq = Counter(test_data_senti)
print('test_data_senti_freq:', test_data_senti_freq)

 

3. 피처 벡터화를 진행합니다.

CountVectorizer를 아래와 같이 시행합니다.

from sklearn.feature_extraction.text import CountVectorizer
vect = CountVectorizer(min_df=5).fit(train_data_text)
X_train = vect.transform(train_data_text)

feature_names = vect.get_feature_names()
print("특성 개수:", len(feature_names))
print("처음 20개 특성:\m", feature_names[:20])

 

만약 Tfid 벡터화를 원한다면 하기 내용으로 진행하면 됩니다.

from sklearn.feature_extraction.text import TfidfVectorizer
vect = TfidfVectorizer(min_df=5, ngram_range=(1,2)).fit(train_data_text)
X_train = vect.transform(train_data_text)

 

4. 벡터화 데이터를 회귀분석을 통해 정확도를 검증합니다.

회귀분석을 이용합니다. 이때 교차검증을 하기 위해 cross_val_score을 시행하고 GridSearch로 여러 하이퍼 파라미터로 실행해봅니다.  회귀분석의 C값이 1이 최상 변수로 나와 값을 입력하면 됩니다.

import pandas as pd
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
y_train = pd.Series(train_data_senti)
scores = cross_val_score(LogisticRegression(solver="liblinear"), X_train, y_train, cv=5)
print('교차 검증 점수:', scores)
print('교차 검증 점수 평균:', scores.mean())

from sklearn.model_selection import GridSearchCV
param_grid = {'C': [0.01, 0.1, 1, 3, 5]}
grid = GridSearchCV(LogisticRegression(solver="liblinear"), param_grid, cv=5)
grid.fit(X_train, y_train)
print("최고 교차 검증 점수:", round(grid.best_score_, 3))
print("최적의 매개변수:", grid.best_params_)

 

5. Test데이터를 검증 모델에 넣어 정확도를 확인해 봅니다. 

반드시 유의해야 할 점은 테스트 데이터에서 CountVectorizer를 적용할 때는 반드시 학습 데이터를 이용해 fit()이 수행된 CountVectorizer객체를 이용해 테스트 데이터를 변환(transform) 해야 한다는 것입니다. 그래야만 학습 시 설정된 CountVectorizer의 피처 개수와 테스트 데이터를 CountVectorizer로 변환할 피처 개수가 같아집니다. 테스트 데이터의 피처 벡터화는 학습 데이터에 사용된 CountVectorizer객체 변수인 cnt_vect.traform()을 이용해 반환합니다.

X_test = vect.transform(test_data_text)
y_test = pd.Series(test_data_senti)
print("테스트 데이터 점수:", grid.score(X_test, y_test))

 

6. 신규 데이터를 넣어주십시오.

검증 모델을 기준으로 신규 데이터를 넣어보고 확인하세요.  rhinoMorph을 이용한 감정분석입니다.

import rhinoMorph
rn = rhinoMorph.startRhino()
print('rn\n',rn)
new_input = '오늘은 정말 재미있는 하루구나!'

# 입력 데이터 형태소 분석하기
inputdata = []
morphed_input = rhinoMorph.onlyMorph_list(rn, new_input, pos=['NNG', 'NNP', 'VV', 'VA', 'XR', 'IC', 'MM', 'MAG', 'MAJ'])
morphed_input = ' '.join(morphed_input)                     # 한 개의 문자열로 만들기
inputdata.append(morphed_input)                               # 분석 결과를 리스트로 만들기
X_input = vect.transform(inputdata)
print(float(grid.predict(X_input)))
result = grid.predict(X_input) # 0은 부정,1은 긍정
print(result)
print(type(result))
if result == 0.0:
    print("부정적인 글입니다")
else:
    print("긍정적인 글입니다")

 

반응형