감성분석과 문서분류

Python을 이용해 텍스트에 나타난 감성과 의견을 분석하고, 문서를 카테고리에 따라 분류합니다.


수강중

1. 감성분석 준비

동영상이 없는 텍스트 강의 자료입니다.

감성분석이란 문서에 나타난 긍부정의 감정 또는 태도를 분석하는 것입니다. 감정 분석에는 크게 사전에 의한 방법과 기계 학습에 의한 방법 2가지가 있습니다.

사전에 의한 방법은 단어 중에 긍/부정의 감성을 나타내는 단어들을 사전으로 만들고, 문서에서 긍정 단어, 부정 단어의 비율을 계산해서 긍정 단어가 많으면 긍정으로, 부정 단어가 많으면 부정으로 판정하는 것입니다. 감성 사전을 만들기 위해서는 높은 전문성과 많은 노력이 필요하다는 단점이 있습니다.

기계학습에 의한 방법은 미리 긍/부정으로 분류된 문서들을 수집하여 기계학습 모형에 학습시키는 방법입니다. 여기서는 아마존 핸드폰 리뷰 데이터를 기반으로 기계학습으로 감성 분석을 실시하는 방법을 알아보겠습니다.

데이터 다운로드

데이터를 다운받습니다.

import requests
res = requests.get('https://archive.ics.uci.edu/ml/machine-learning-databases/00331/sentiment%20labelled%20sentences.zip')
with open('sentiment labelled sentences.zip', 'wb') as f:
    f.write(res.content)

데이터 압축 해제

압축을 풉니다.

from zipfile import ZipFile
z = ZipFile('sentiment labelled sentences.zip')
data = z.open('sentiment labelled sentences/amazon_cells_labelled.txt')

파일 열기

탭(\t) 으로 구분된 CSV 형태의 데이터를 df로 불러들입니다.

import pandas as pd
df = pd.read_csv(data, sep="\t", header=None)

데이터의 초반 5개를 확인합니다. 0번째 컬럼은 고객들의 리뷰입니다. 1번째 컬럼에는 부정적 리뷰가 0, 긍정적 리뷰가 1로 표시되어 있습니다.

df.head()
0 1
0 So there is no way for me to plug it in here i... 0
1 Good case, Excellent value. 1
2 Great for the jawbone. 1
3 Tied to charger for conversations lasting more... 0
4 The mic is great. 1

.shape로 데이터의 크기를 확인합니다.

df.shape
(1000, 2)

단어 문서 행렬 만들기

CountVectorizer 를 사용하여 단어 문서 행렬을 만듭니다.

from sklearn.feature_extraction.text import CountVectorizer
  • max_features=1000: 피처의 개수는 1000개로 설정합니다.
  • 영어 데이터이므로 stop_words='english' 를 통해 관사 등을 제거합니다.
cv = CountVectorizer(max_features=1000, stop_words='english')
tdm = cv.fit_transform(df[0])

데이터 분할

x는 문서를 단어 문서 행렬로 나타낸 것입니다.

x = tdm
y = df[1]

기계학습 후 성능을 평가하기 위해 데이터를 훈련용과 테스트용으로 나눕니다.

scikitlearn.model_selectiontrain_test_split 모듈을 사용합니다.

  • test_size=0.2: 전체 데이터 중 20%를 테스트용 데이터로 할당합니다. 여기서는 전체 개수가 1000개 이므로 훈련용 데이터(800개)와 테스트용 데이터(200개)로 나눕니다.
  • random_state=: 숫자가 같을 경우 동일한 샘플링을 하게 된다. 재현가능한 결과를 위하여 임의의 숫자를 할당합니다.
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, random_state=42)

x_train: 훈련용 데이터(리뷰) 결과를 확인합니다. 크기가 800x1000 행렬을 확인할 수 있습니다.

x_train
<800x1000 sparse matrix of type '<class 'numpy.int64'>'
	with 3220 stored elements in Compressed Sparse Row format>

x_test: 테스트용 데이터(리뷰) 결과를 확인합니다. 크기가 200x1000 행렬을 확인할 수 있습니다.

x_test
<200x1000 sparse matrix of type '<class 'numpy.int64'>'
	with 840 stored elements in Compressed Sparse Row format>

y_trainy_test도 확인해봅니다.

y_train
29     0
535    0
695    0
557    1
836    0
      ..
106    0
270    0
860    0
435    0
102    1
Name: 1, Length: 800, dtype: int64
y_test
521    1
737    1
740    1
660    0
411    1
      ..
408    1
332    1
208    1
613    1
78     1
Name: 1, Length: 200, dtype: int64

저장

다음의 분석에 사용하기 위해 전처리된 데이터를 저장합니다. joblib이 없으면 pip install joblib으로 설치하시면 됩니다. 또는 joblib 대신에 pickle을 사용하셔도 됩니다.

import joblib

joblib.dump((x_train, x_test, y_train, y_test, cv), 'review.pkl')
['review.pkl']