import konlpy
import pandas as pd
import numpy as np
최신 tweepy
를 설치할 경우 StreamListener
가 없다는 에러가 발생(https://github.com/tweepy/tweepy/issues/1531) 하므로 3.10버전을 설치해 주세요.
pip install tweepy==3.10
konlpy.__version__
'0.5.2'
데이터 파일을 읽어 리뷰 텍스트와 점수를 text_train, y_train 변수에 저장합니다. 데이터 파일의 내용은 번호, 텍스트, 레이블이 탭으로 구분되어 한 라인에 한개의 데이터 샘플이 들어 있습니다.
df_train = pd.read_csv('data/ratings_train.txt', delimiter='\t', keep_default_na=False)
df_train.head()
id | document | label | |
---|---|---|---|
0 | 9976970 | 아 더빙.. 진짜 짜증나네요 목소리 | 0 |
1 | 3819312 | 흠...포스터보고 초딩영화줄....오버연기조차 가볍지 않구나 | 1 |
2 | 10265843 | 너무재밓었다그래서보는것을추천한다 | 0 |
3 | 9045019 | 교도소 이야기구먼 ..솔직히 재미는 없다..평점 조정 | 0 |
4 | 6483659 | 사이몬페그의 익살스런 연기가 돋보였던 영화!스파이더맨에서 늙어보이기만 했던 커스틴 ... | 1 |
text_train, y_train = df_train['document'].values, df_train['label'].values
같은 방식으로 테스트 데이터를 읽습니다.
df_test = pd.read_csv('data/ratings_test.txt', delimiter='\t', keep_default_na=False)
text_test = df_test['document'].values
y_test = df_test['label'].values
훈련 데이터와 테스트 데이터의 크기를 확인합니다.
len(text_train), np.bincount(y_train)
(150000, array([75173, 74827]))
len(text_test), np.bincount(y_test)
(50000, array([24827, 25173]))
KoNLPy 0.4.5 버전부터 Twitter
클래스가 Okt
클래스로 바뀌었습니다. open-korean-text 프로젝트는 twitter-korean-text 프로젝트의 공식 포크입니다.
병렬 처리를 위해 Mecab
을 사용하여 전체 데이터로 학습시킵니다. Mecab
으로 토큰을 분할하는 함수를 만듭니다.
MeCab을 설치하려면 다음 명령을 실행하세요.
$ bash <(curl -s https://raw.githubusercontent.com/konlpy/konlpy/master/scripts/mecab.sh)
파이썬 가상 환경에서 MeCab을 설치하려면 이 깃허브에 포함된 mecab.sh
파일을 실행하세요.
최신 macOS Mojave에서는 Mecab
에 필요한 jpype 라이브러리가 컴파일 오류가 발생할 수 있습니다. 이런 경우 다음 명령으로 konlpy를 설치해 주세요.
$ export MACOSX_DEPLOYMENT_TARGET=10.10 CFLAGS='-stdlib=libc++' pip install konlpy
Mecab 클래스(SwigPyObject)를 피클링(pickling)하지 못해 n_jobs=-1
로 설정하면 오류가 발생합니다.
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from konlpy.tag import Mecab
mecab = Mecab()
def mecab_tokenizer(text):
return mecab.morphs(text)
mecab_param_grid = {'tfidfvectorizer__min_df': [3],
'tfidfvectorizer__ngram_range': [(1, 1)],
'logisticregression__C': [0.1]}
mecab_pipe = make_pipeline(TfidfVectorizer(tokenizer=mecab_tokenizer), LogisticRegression(solver='liblinear'))
mecab_grid = GridSearchCV(mecab_pipe, mecab_param_grid, n_jobs=1, cv=3)
# 그리드 서치를 수행합니다
mecab_grid.fit(text_train, y_train)
print("최상의 크로스 밸리데이션 점수: {:.3f}".format(mecab_grid.best_score_))
print("최적의 크로스 밸리데이션 파라미터: ", mecab_grid.best_params_)
최상의 크로스 밸리데이션 점수: 0.830 최적의 크로스 밸리데이션 파라미터: {'logisticregression__C': 0.1, 'tfidfvectorizer__min_df': 3, 'tfidfvectorizer__ngram_range': (1, 1)}
SwigPyObject의 피클링을 위해 __setstate__
, __getstate__
메서드를 추가하여 Mecab 클래스를 감쌉니다.
class PicklableMecab(Mecab):
def __init__(self, *args):
self.args = args
Mecab.__init__(self, *args)
def __setstate__(self, state):
self.__init__(*state['args'])
def __getstate__(self):
return {'args': self.args}
mecab = PicklableMecab()
def mecab_tokenizer(text):
return mecab.morphs(text)
규제 파라미터의 범위를 확대하여 그리드 서치를 수행합니다.
mecab_param_grid = {'tfidfvectorizer__min_df': [3, 5 ,7],
'tfidfvectorizer__ngram_range': [(1, 1), (1, 2), (1, 3)],
'logisticregression__C': [0.1, 1, 10, 100]}
mecab_pipe = make_pipeline(TfidfVectorizer(tokenizer=mecab_tokenizer), LogisticRegression(solver='liblinear'))
mecab_grid = GridSearchCV(mecab_pipe, mecab_param_grid, n_jobs=-1, cv=3)
# 그리드 서치를 수행합니다
mecab_grid.fit(text_train, y_train)
print("최상의 크로스 밸리데이션 점수: {:.3f}".format(mecab_grid.best_score_))
print("최적의 크로스 밸리데이션 파라미터: ", mecab_grid.best_params_)
최상의 크로스 밸리데이션 점수: 0.870 최적의 크로스 밸리데이션 파라미터: {'logisticregression__C': 10, 'tfidfvectorizer__min_df': 3, 'tfidfvectorizer__ngram_range': (1, 3)}
X_test_mecab = mecab_grid.best_estimator_.named_steps["tfidfvectorizer"].transform(text_test)
score = mecab_grid.best_estimator_.named_steps["logisticregression"].score(X_test_mecab, y_test)
print("테스트 세트 점수: {:.3f}".format(score))
테스트 세트 점수: 0.875