ML
한글 텍스트 처리 - 네이버 영화 평점 감성 분석
hyerimir
2022. 12. 2. 00:20
한글 NLP 처리의 어려움
일반적으로 한글 언어 처리는 굉장히 어려운데, 그 주된 원인은 띄어쓰기와 다양한 조사 때문이다
상대적으로 라틴어 계열의 언어보다 어려운 문제가 있음
KoNLPy 소개
KoNLPy는 파이썬의 대표적인 한글 형태소 패키지
형태소 분석(Morphological analysis) : 형태소 어근 단위로 쪼개고 각 형태소에 품사 태깅을 부착하는 작업
Anaconda는 KoNLPy 설치를 아직 지원하지 않으므로 pip로 설치해야 한다
pip install konlpy
한글로 된 문서를 Dataframe으로 로딩할 때 인코딩 이슈가 발생할 수 있음
import pandas as pd
train_df = pd.read_csv('', sep='\t', encoding='cp949')
train_df.head(3)
학습 데이터 세트의 0과 1의 Label 값 비율 살펴보기
train_df['label'].value_counts()
0과 1이 어느 한쪽으로 치우치지 않고 균등한 분포 이루고 있음
Null이 존재하면 이 값은 공백으로 변환
문자가 아닌 숫자의 경우 단어적인 의미로 부족하므로 파이썬의 정규 표현식 모듈인 re를 이용해 이 역시 공백으로 변환
테스트 데이터 세트의 경우도 동일한 방식으로 데이터 가공
import re
train_df = train_df.fillna(' ')
#정규 표현식을 이용해 숫자를 공백으로 변경(정규 표현식으로 \d는 숫자를 의미함.)
train_df['document'] = train_df['document'].apply(lambda x : re.sub(r"\d+", " ", x))
#테스트 데이터 세트를 로딩하고 동일하게 Null 및 숫자를 공백으로 변환
test_df = pd.read_csv('', sep='\t', encoding='cp949')
test_df = test_df.fillna(' ')
test_df['document'] = test_df['document'].apply(lambda x : re.sub(r"\d+", " ", x))
#id 칼럼 삭제 수행
train_df.drop('id', axis=1, inplace=True)
test_df.drop('id', axis=1, inplace=True)
from konlpy.tag import Twitter
twitter = Twitter()
def tw_tokenizer(text):
#입력 인자로 들어온 텍스트를 형태소 단어로 토큰화해 리스트 형태로 반환
tokens_ko = twitter.morphs(text)
return tokens_ko
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model impot LogisticRegression
from sklearn.model_selection import GridSearchCV
#Twitter 객체의 morphs() 객체를 이용한 tokenizer를 사용. ngram_range는 (1,2)
tfidf_vect = TfidfVectorizer(tokenizer=tw_tokenizer, ngram_range=(1,2), min_df=3, max_df=0.9)
tfidf_vect.fit(train_df['document'])
tfidf_matrix_train = tfidf_vect.transform(train_df['documnet'})
#로지스틱 회귀를 이용해 감성 분석 분류 수행
lg_clf = LogisticRegression(random_state=0, solver='liblinear')
#파라미터 C 최적화를 위해 GridSearchCV를 이용
params = {'C' : [1, 3.5, 4.5, 5.5, 10])
grid_cv = GridSearchCV(lg_clf, param_grid=params, cv=3, scoring='accuracy', verbose=1)
grid_cv.fit(tfidf_matrix_train, train_df['label'])
print(grid_cv.best_params_, round(grid_cv.best_score_, 4))
테스트 세트를 이용해 예측할 때는 학습할 때 적용한 TfidfVectorizer를 그대로 사용해야 한다
그래야 학습 시 설정된 TfidfVectorizer의 피처 개수와 테스트 데이터를 TfidfVectorizer로 변환할 피처 개수가 같아짐
from sklearn.metrics import accuracy_score
#학습 데이터를 적용한 TfidfVectorizer를 이용해 테스트 데이터를 TF-IDF 값으로 피처 변환함
tfidf_matrix_test = tfidf_vect.transform(test_df['document'])
#classifier는 GridSearchCV에서 최적 파라미터로 학습된 classifier를 그대로 이용
best_estimator = grid_cv.best_estimator_
preds = best_estimator.predict(tfidf_matrix_test)
print(accuracy_score(test_df['label'], preds))