텍스트 처리용 IMDB 영화 리뷰 데이터 준비
- 감성분석은 NLP 연구 분야 중 인기 있는 하위 분야로 의견 분석(opinion mining)이라고도 한다.
- 이 분야에서는 문서 성향을 분석하는 것을 주로 다룬다.
영화 리뷰 데이터셋 구하기
영화 리뷰 데이터셋을 더 간편한 형태로 전처리
- 내려 받은 데이터셋을 DataFrame 형태로 변환하고 CSV로 저장하는 코드
# <http://ai.stanford.edu/~amaas/data/sentiment/> 에서 내려받은 파일
import tarfile
with tarfile.open('aclImdb_v1.tar.gz', 'r:gz') as tar:
tar.extractall()
import pyprind
import pandas as pd
import os
import numpy as np
# aclImdb_v1.tar.gz 파일이 있는 path
basepath = 'aclImdb'
labels = {'pos':1, 'neg':0}
pbar = pyprind.ProgBar(50000)
df = pd.DataFrame()
for s in ('test', 'train'):
for l in ('pos', 'neg'):
path = os.path.join(basepath, s, l)
for file in sorted(os.listdir(path)):
with open(os.path.join(path, file), 'r', encoding='utf-8') as infile:
txt = infile.read()
df = df.append([[txt, labels[l]]], ignore_index=True)
pbar.update()
df.columns = ['review', 'sentiment']
np.random.seed(0)
df = df.reindex(np.random.permutation(df.index))
df.to_csv('movie_data.csv', index=False, encodeing='utf-8')
BoW 모델 소개
- BoW(Bag-of-Word) 모델의 아이디어는 다음과 같다.
- 전체 문서에 대해 고유한 토큰(token), 예컨대 단어로 이루어진 어휘 사전(vocabulary)를 만든다.
- 특정 문서에 각 단어가 얼마나 자주 등장하는지 헤아려 문서의 특성 벡터를 만든다.
- 각 문서에 있는 단어의 고유한 단어는 BoW 어휘 사전에 있는 모든 단어의 일부분에 지나지 않으므로 특성 벡터는 대부분이 0으로 채워진다. 그래서 이 특성 벡터를 희소(sparse)하다고 한다.
단어를 특성 벡터로 변환
- 사이킨런에 구현된 CountVectorizer를 이용하여 각각의 문서에 있는 단어 카운트를 기반으로 BoW 모델을 만들 수 있다.
- CountVectorizer는 문서 또는 문장으로 이루어진 텍스트 데이터 배열을 입력 받아 BoW 모델을 만든다.
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
count = CountVectorizer()
docs = np.array(['The sun is shining', 'The weather is sweet', 'The sun is shining, the weather is sweet, and one and one is two'])
bag = count.fit_transform(docs)
print(count.vocabulary_)
# [결과]
# {'the': 6, 'sun': 4, 'is': 1, 'shining': 3, 'weather': 8, 'sweet': 5, 'and': 0, 'one': 2, 'two': 7}
print(bag.toarray())
# [결과]
# [[0 1 0 1 1 0 1 0 0]
# [0 1 0 0 0 1 1 0 1]
# [2 3 2 1 1 1 2 1 1]]
- 어휘사전을 호출하면 (위 예시의 count.vocabulary_) 고유 단어와 정수 인덱스가 매핑된 파이썬 딕셔너리를 확인할 수 있다.
- 특성 벡터 (위 예시의 bag.toarray()) 의 각 인덱스는 CountVectorizer의 어휘 사전 딕셔너리에 저장된 정수 값에 해당한다.
- 예컨대 인덱스 0에 있는 첫 번째 특성은 ‘and’ 단어의 카운트를 의미한다. 이 단어는 1, 2 번 문장에는 없고 3번째 문장에는 2번 등장한다.
- 인덱스 1에 들어 있는 단어 ‘is’ 는 세 문장에서 모두 등장한다. (1번, 1번, 3번)
- 특성 벡터의 이런 값들을 단어 빈도(term frequency)라고 한다. 문서 d에 등장한 단어 t의 횟수를 tf(t, d) 와 같이 쓴다.
- 위 예시 모델에 있는 아이템 시퀀스를 1-그램(1-gram) 또는 유니그램(unigram) 모델이라고 한다. 어휘 사전에 있는 각 아이템 또는 토큰이 하나의 단어를 표현한다는 뜻이다.
- NLP에서 연속된 아이템의 시퀀스를 n-gram이라고 한다. 어플리케이션마다 사용하는 n의 값이 다른데, 이메일 스팸 필터링에서는 3, 4의 n-그램이 좋은 성능을 낸다고 한다.
- ‘the sun is shining’을 1-그램과 2-그램으로 표현하면 다음과 같다.
- 1-그램: ‘the’, ‘sun’, ‘is’, ‘shining’
- 2-그램: ‘the sun’, ‘sun is’, ‘is shining’
tf-idf를 사용하여 단어 적합성 평가
- 텍스트 데이터를 분석할 때 클래스 레이블이 다른 문서에 같은 단어들이 나타나는 경우를 보게되는데, 일반적으로 자주 등장하는 단어는 유용하거나 판별에 필요한 정보를 가지고 있지 않다.