Data Analysis & ML/Text Mining

[Text Mining] 지도학습 기반 감성 분석 (Sentiment Analysis) (IMDB 영화리뷰)

YSY^ 2020. 9. 15. 18:53

영화리뷰 데이터 셋 전처리 및 긍부정 모델링

이번 포스팅은 영화리뷰 데이터셋을 사용하여 전처리하고 모델링하는 텍스트마이닝을 소개합니다. 텍스트 데이터 전처리부터 Feature vectorization과 머신러닝 모델링까지 진행합니다.

텍스트 분석 수행 프로세스

  1. 텍스트 전처리
    • 클렌징(cleansing)
      • 특수문자, 기호 필요없는 문자 제거
      • 대소문자 변경
    • stop word(분석에 필요 없는 토큰) 제거
    • 텍스트 토큰화
      • 분석의 최소단위로 나누는 작업
      • 보통 단어단위나 글자단위로 나눈다.
    • 어근 추출(Stemming/Lemmatization)을 통한 텍스트 정규화 작업
  2. Feature vectorization
    • 문자열 비정형 데이터인 텍스트를 숫자타입의 정형데이터로 만드는 작업
    • BOW와 Word2Vec
  3. 머신러닝 모델 수립, 학습, 예측, 평가

IMDB(Internet Movie Database) 영화리뷰 데이터 셋 EDA

  • IMDb (Internet Movie Database) : 영화, TV 시리즈, 팟캐스트, 홈 비디오, 비디오 게임 및 온라인 스트리밍 콘텐츠와 관련된 정보의 온라인 데이터베이스
  • https://www.imdb.com/
  • Data 다운로드: http://ai.stanford.edu/~amaas/data/sentiment/
    • train의 unsup 은 제거 (비지도학습용)
  • load_files()
    • 분류범주를 폴더로 분리한 텍스트 파일을 load한다.
    • Bunch 타입으로 반환
  • neg: 0, pos: 1 로 분리해 준다. (폴더의 알파벳 순서대로 )
from sklearn.datasets import load_files
import numpy as np
import pandas as pd

review_train = load_files("aclImdb/train")  #분류 클래스 별로 폴더를 만들고 그 폴더에 document text들을 저장.
review_test = load_files('aclImdb/test')

type(review_train), review_train.keys()
# (sklearn.utils.Bunch, dict_keys(['data', 'filenames', 'target_names', 'target', 'DESCR']))

# label/y
type(review_train.data), type(review_train.target)
# (list, numpy.ndarray)

데이터 전처리

  • <br/> 제거
  • binary string을 string으로 변환
import nltk
from nltk.stem import SnowballStemmer
from nltk.corpus import stopwords

def text_preprocessing(documents):

    stop_words = stopwords.words('english')
    stemmer = SnowballStemmer('english')

    return_list = []
    for doc in documents:
        # binary string => string
        doc = doc.decode('utf-8')
        # 소문자로 변환
        doc = doc.lower()
        # br태그 제거 (공백으로 변환)
        doc = doc.replace('<br />', ' ')
        # 토큰화
        tokens = nltk.regexp_tokenize(doc, r'[A-Za-z]+')
        #stopword 제거 + stemming
        tokens = [stemmer.stem(word) for word in tokens if word not in stop_words]
        #list를 다시 string을 변환
        return_list.append(' '.join(tokens))

    return return_list

X_train = text_preprocessing(review_train.data)
y_train = review_train.target

X_test = text_preprocessing(review_test.data)
y_test = review_test.target

Data 파일 저장

Train Set과 Test Set의 종속변수 데이터와 독립변수 데이터를 각각 저장합니다.

import os
if not os.path.isdir('imdb_text_preprocess_data'): #디렉토리가 없다면
    os.mkdir('imdb_text_preprocess_data')         #디렉토리를 만들어라.

import pickle
# X_train
with open('imdb_text_preprocess_data/X_train.pkl', 'wb') as f:
    pickle.dump(X_train, f)

# y_train
with open('imdb_text_preprocess_data/y_train.pkl', 'wb') as f:
    pickle.dump(y_train, f)

# X_test
with open('imdb_text_preprocess_data/X_test.pkl', 'wb') as f:
    pickle.dump(X_test, f)


# y_test
with open('imdb_text_preprocess_data/y_test.pkl', 'wb') as f:
    pickle.dump(y_test, f)

Data Read

# X_train, y_train, X_test, y_test 읽는 코드.   

import pickle
with open("imdb_text_preprocess_data/X_train.pkl", 'rb') as f:
    X_train2 = pickle.load(f)

with open("imdb_text_preprocess_data/y_train.pkl", 'rb') as f:
    y_train2 = pickle.load(f)

with open("imdb_text_preprocess_data/X_test.pkl", 'rb') as f:
    X_test2 = pickle.load(f)    

with open("imdb_text_preprocess_data/y_test.pkl", 'rb') as f:
    y_test2 = pickle.load(f)  

 

영화리뷰 데이터 긍부정 분류

Feature vectorization

  • 텍스트를 숫자형값의 정형테이터로 변환

CountVectorizer (문서 단어 행렬)

from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer()
# cv = CountVectorizer(max_features=10000)
cv.fit(X_train)

len(cv.get_feature_names()) # 단어(term) 수 (48956)

len(X_train) #문서수 (25000)

# 변환
X_train_cv = cv.transform(X_train)
X_test_cv = cv.transform(X_test)

X_train_cv.shape, X_test_cv.shape # ((25000, 48956), (25000, 48956))

TF-IDF (Term Frequency Inverse Document Frequency)

from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer()

tfidf.fit(X_train)

train_tfidf = tfidf.transform(X_train)
test_tfidf = tfidf.transform(X_test)

train_tfidf.shape, test_tfidf.shape # ((25000, 48956), (25000, 48956))

긍부정 분류 모델링

  • 모델링은 CountVectorizer 기반으로 진행

LogisticRegression (로지스틱회귀)

from sklearn.linear_model import LogisticRegression

lr = LogisticRegression(max_iter=2000)
lr.fit(X_train_cv, y_train)

pred_train = lr.predict(X_train_cv)
pred_test = lr.predict(X_test_cv)

from sklearn.metrics import accuracy_score
accuracy_score(y_train, pred_train), accuracy_score(y_test, pred_test)
# (0.99408, 0.85264)

RandomForestClassifier (랜덤포레스트)

from sklearn.ensemble import RandomForestClassifier

rf_clf = RandomForestClassifier(max_depth=3, n_estimators=200)
rf_clf.fit(X_train_cv, y_train)

pred_train = rf_clf.predict(X_train_cv)
pred_test = rf_clf.predict(X_test_cv)

accuracy_score(y_train, pred_train), accuracy_score(y_test, pred_test)
# (0.83108, 0.82284)
728x90
반응형