반응형
6.1 차원의 저주와 차원 축소의 이유
- 차원의 저주: 낮은 차원에서는 발생하지 않던 문제가 차원이 커지면서 발생하는 것
- 해결방법
- 데이터를 충분히 늘리는 것
- BOW로 표현한 문서의 특성 수를 줄임
6.2 PCA를 이용한 차원 축소
- PCA(Principal Component Analysis): 주성분 분석, 데이터의 분산을 최대한 보존하는 새로운 축을 찾아 변환함으로써 차원을 축소하고자 하는 방법
from sklearn.datasets import fetch_20newsgroups
#20개의 토픽 중 선택하고자 하는 토픽을 리스트로 생성
categories = ['alt.atheism', 'talk.religion.misc', 'comp.graphics', 'sci.space']
#학습 데이터셋을 가져옴
newsgroups_train = fetch_20newsgroups(subset='train',
#메일 내용에서 hint가 되는 부분을 삭제 - 순수하게 내용만으로 분류
remove=('headers', 'footers', 'quotes'),
categories=categories)
#검증 데이터셋을 가져옴
newsgroups_test = fetch_20newsgroups(subset='test',
remove=('headers', 'footers', 'quotes'),
categories=categories)
X_train = newsgroups_train.data #학습 데이터셋 문서
y_train = newsgroups_train.target #학습 데이터셋 라벨
X_test = newsgroups_test.data #검증 데이터셋 문서
y_test = newsgroups_test.target #검증 데이터셋 라벨
from sklearn.feature_extraction.text import TfidfVectorizer
from nltk.corpus import stopwords
cachedStopWords = stopwords.words("english")
from nltk.tokenize import RegexpTokenizer
from nltk.stem.porter import PorterStemmer
RegTok = RegexpTokenizer("[\w']{3,}") # 정규포현식으로 토크나이저를 정의
english_stops = set(stopwords.words('english')) #영어 불용어를 가져옴
def tokenizer(text):
tokens = RegTok.tokenize(text.lower()) #이렇게 해도 되는지 확인
# stopwords 제외
words = [word for word in tokens if (word not in english_stops) and len(word) > 2]
# portr stemmer 적용
features = (list(map(lambda token: PorterStemmer().stem(token),words)))
return features
tfidf = TfidfVectorizer(tokenizer=tokenizer)
X_train_tfidf = tfidf.fit_transform(X_train) # train set을 변환
X_test_tfidf = tfidf.transform(X_test) # test set을 변환
from sklearn.linear_model import LogisticRegression
LR_clf = LogisticRegression() #분류기 선언
LR_clf.fit(X_train_tfidf, y_train) # train data를 이용하여 분류기를 학습
print('#Train set score: {:.3f}'.format(LR_clf.score(X_train_tfidf, y_train)))
print('#Test set score: {:.3f}'.format(LR_clf.score(X_test_tfidf, y_test)))
"""
#Train set score: 0.962
#Test set score: 0.761
"""
from sklearn.decomposition import PCA
pca = PCA(n_components=2000, random_state=7)
X_train_pca = pca.fit_transform(X_train_tfidf.toarray())
X_test_pca = pca.transform(X_test_tfidf.toarray())
print('Original tfidf matrix shape:', X_train_tfidf.shape)
print('PCA Converted matrix shape:', X_train_pca.shape)
print('Sum of explained variance ratio: {:.3f}'.format(pca.explained_variance_ratio_.sum()))
"""
Original tfidf matrix shape: (2034, 20085)
PCA Converted matrix shape: (2034, 2000)
Sum of explained variance ratio: 1.000
"""
LR_clf.fit(X_train_pca, y_train)
print('#Train set score: {:.3f}'.format(LR_clf.score(X_train_pca, y_train)))
print('#Test set score: {:.3f}'.format(LR_clf.score(X_test_pca, y_test)))
"""
#Train set score: 0.962
#Test set score: 0.761
"""
lasso_clf = LogisticRegression(penalty='l1', solver='liblinear', C=1)
lasso_clf.fit(X_train_tfidf, y_train)
print('#Train set score: {:.3f}'.format(lasso_clf.score(X_train_tfidf, y_train)))
print('#Test set score: {:.3f}'.format(lasso_clf.score(X_test_tfidf, y_test)))
import numpy as np
# 계수(coefficient) 중에서 0이 아닌 것들의 개수를 출력
print('#Used features count: {}'.format(np.sum(lasso_clf.coef_ != 0)), 'out of', X_train_tfidf.shape[1])
"""
#Train set score: 0.790
#Test set score: 0.718
#Used features count: 321 out of 20085
"""
pca = PCA(n_components=321, random_state=7)
X_train_pca = pca.fit_transform(X_train_tfidf.toarray())
X_test_pca = pca.transform(X_test_tfidf.toarray())
print('PCA Converted X shape:', X_train_pca.shape)
print('Sum of explained variance ratio: {:.3f}'.format(pca.explained_variance_ratio_.sum()))
LR_clf.fit(X_train_pca, y_train)
print('#Train set score: {:.3f}'.format(LR_clf.score(X_train_pca, y_train)))
print('#Test set score: {:.3f}'.format(LR_clf.score(X_test_pca, y_test)))
"""
PCA Converted X shape: (2034, 321)
Sum of explained variance ratio: 0.437
#Train set score: 0.875
#Test set score: 0.751
"""
pca = PCA(n_components=100, random_state=7)
X_train_pca = pca.fit_transform(X_train_tfidf.toarray())
X_test_pca = pca.transform(X_test_tfidf.toarray())
print('PCA Converted X shape:', X_train_pca.shape)
print('Sum of explained variance ratio: {:.3f}'.format(pca.explained_variance_ratio_.sum()))
LR_clf.fit(X_train_pca, y_train)
print('#Train set score: {:.3f}'.format(LR_clf.score(X_train_pca, y_train)))
print('#Test set score: {:.3f}'.format(LR_clf.score(X_test_pca, y_test)))
"""
PCA Converted X shape: (2034, 100)
Sum of explained variance ratio: 0.211
#Train set score: 0.807
#Test set score: 0.738
"""
※ 해당 내용은 <파이썬 텍스트 마이닝 완벽 가이드>의 내용을 토대로 학습하며 정리한 내용입니다.
반응형
'텍스트 마이닝' 카테고리의 다른 글
차원축소 (3) (0) | 2023.07.10 |
---|---|
차원축소 (2) (0) | 2023.07.09 |
BOW 기반의 문서 분류 (8) (0) | 2023.07.07 |
BOW 기반의 문서 분류 (7) (0) | 2023.07.06 |
BOW 기반의 문서 분류 (6) (0) | 2023.07.05 |