ML

텍스트 분류 실습 - 20 뉴스그룹 분류

hyerimir 2022. 11. 23. 09:46

 

텍스트 분류

: 특정 문서의 분류를 학습 데이터를 통해 학습해 모델을 생성한 뒤 이 학습 모델을 이용해 다른 문서의 분류를 예측하는 것

 

텍스트를 피처 벡터화하면 일반적으로 희소 행렬이 되는데 이 희소 행렬에 분류를 효과적으로 잘 처리할 수 있는 알고리즘은 로지스틱 회귀, 선형 서포트 벡터 머신, 나이브 베이즈 등

 

텍스트 정규화

from sklearn.datasets import fetch_20newsgroups

news_data = fetch_20newsgroups(subset='all', random_state=156)

 

print(news_data.keys())

 

import pandas as pd
print(pd.Series(news_data.target).value_counts().sort_index())
print(news_data.target_names)
print(news_data.data[0])
from sklearn.datasets import fetch_20newsgroups

fectch_20newsgroups(subset='train', remove=('headers', 'footers', 'quotes'), random_state=156)
X_train = train_news.data
y_train = train_news.target

fetch_20newsgroups(subset='test', remove=('headers', 'footers', 'quotes'), random_state=156)
X_test = test_news.data
y_test = test_news.target

 

피처 벡터화 변환과 머신러닝 모델 학습/예측/평가

테스트 데이터에서 CountVectorizer를 적용할 때는 반드시 학습 데이터를 이용해 fit()이 수행된 CountVectorizer 객체를 이용해 테스트 데이터를 변환(transform)해야 함

테스트 데이터의 피처 벡터화 시 fit_transform()을 사용하면 안됨

 

from sklearn.feature_extraction.text import CountVectorizer

# Count Vectorization으로 피처 벡터화 변환 수행
cnt_vect = CountVectorizer()
cnt_vect.fit(X_train)
X_train_cnt_vect = cnt_vect.transform(X_train)

# 학습 데이터로 fit()된 CountVectorizer를 이용해 테스트 데이터를 피처 벡터화 변환 수행
X_test_cnt_vect = cnt_vect.transform(X_test)

print(X_train_cnt_vect.shape)

11314개 문서에서 피처, 즉 단어가 101631개 만들어짐

 

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import warnings
warnings.filterwarnings('ignore')

#LogisticRegression을 이용해 학습/예측/평가 수행
lr_clf = LogisticRegression(solver='liblinear')
lr_clf.fit(X_train_cnt_vent, y_train)
pred = lr_clf.predict(X_test_cnt_vect)
print(accuracy_score(y_test, pred))
from sklearn.feature_extraction.text import TfidfVectorizer

#TF-IDF 벡터화를 적용해 학습 데이터 세트와 테스트 데이터 세트 변환
tfidf_vect = TfidfVectorizer()
tfidf_vect.fit(X_train)
X_train_tfidf_vect = tfidf.vect.transform(X_train)
X_test_tfidf_vect = tfidf_vect.transform(X_test)

#LogisticRegression을 이용해 학습/예측/평가 수행
lr_clf = LogisticRegression(solver='liblinear')
lr_clf.fit(X_train_tfidf_vect, y_train)
pred = lr_clf.predict(X_test_tfidf_vect)
print(accuracy_score(y_test, pred))

TF-IDF가 단순 카운트 기반보다 훨씬 높은 예측 정확도를 제공

 

 

텍스트 분석에서 머신러닝 모델의 성능을 향상시키는 중요한 두 가지 방법

1. 최적의 ML 알고리즘을 선택하기

2. 최상의 피처 전처리 수행하기

 

# stop words 필터링을 추가하고 ngram을 기본(1,1)에서 (1,2)로 변경해 피처 벡터화 적용
tfidf_vect = TfidfVectorizer(stop_words='english', ngram_range=(1,2), max_df=300)
tfidf_vect.fit(X_train)
X_train_tfidf_vect = tfidf_vect.transform(X_train)
X_test_tfidf_vect = tfidf_vect.transform(X_test)

lr_clf = LogisticRegression(solver='liblinear')
lr_clf.fit(X_train_tfidf_vect, y_train)
pred = lr_clf.predict(X_test_tfidf_vect)
print(accuracy_score(y_test, pred))

 

GridSearhCV를 이용해 로지스틱 회귀의 하이퍼 파라미터 최적화 수행

from sklearn.model_selection import GridSearchCV

#최적 C 값 도출 튜닝 수행. CV는 3 폴드 세트로 설정
params = {'C' : [0.01, 0.1, 1, 5, 10]}
grid_cv_lr = GridSearhCV(lr_clf, param_grid=params, cv=3, scoring='accuracy', verbose=1)
grid_cv_lr.fit(X_train_tfidf_vet, y_train)
print(grid_cv_lr.best_params_)

#최적 C 값으로 학습된 grid_cv로 예측 및 정확도 평가
pred = grid_cv_lr.predict(X_test_tfidf_vect)
print(accuracy_score(y_test, pred))

 

 

사이킷런 파이프라인(Pipeline) 사용 및 GridSearchCV와의 결합

- 머신러닝에서 Pipeline이란 데이터의 가공, 변환 등의 전처리와 알고리즘 적용을 마치 '수도관(pipe)에서 물이 흐르듯' 한꺼번에 스트림 기반으로 처리한다는 의미

- 데이터의 전처리와 머신러닝 학습 과정을 통일된 API 기반에서 처리할 수 있어 더 직관적인 ML 모델 코드 생성

- 대용량 데이터의 피처 벡터화 결과를 별도 데이터로 저장하지 않고 스트림 기반에서 바로 머신러닝 알고리즘의 데이터로 입력할 수 있기 때문에 수행 시간 절약

from sklearn.pipeline import Pipeline

#TfidfVectorizer 객체를 tfidf_vect로, LogisticRegression 객체를 lr_clf로 생성하는 Pipeline 생성
pipeline = Pipeline([
                    ('tfidf_vect', TifdfVecotrizer(stop_words='english', ngram_range(1,2), max_df=300)),
                    ('lr_clf', LogisticRegression(solver='liblinear', C=10))
                    ])
                    
#별도의 fit(), transform() 필요 없음
# pipeline의 fit()과 predict()만으로 한꺼번에 피처 벡터화와 ML 학습/예측이 가능
pipeline.fit(X_train, y_train)
pred = pipeline.predict(X_test)
print(accuracy_score(y_test, pred))

 

Pipeline + GridSearchCV를 적용할 때 모두의 파라미터를 최적화하려면 너무 많은 튜닝 시간이 소모됨

GridSearchCV에 Estimator가 아닌 Pipeline을 입력할 경우 param_grid의 입력값 설정이 기존과 약간 다름