문서 분류
데이터 준비
- 문서 분류에 필요한 데이터는 scikit-learn이 제공하는 20개의 주제를 가지는 뉴스그룹 데이터를 사용한다.
- 텍스트는 CounterVectorizer를 거쳐 DTM으로 변환
- DTM은 문서에 등장하는 단어들을 빈도수 별로 표현한 행렬
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
news = fetch_20newsgroups()
x = news.data
y = news.target
cv = CountVectorizer()
x = cv.fit_transform(x)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3)
print(x_train.shape,y_train.shape,x_test.shape,y_test.shape)
-----------------------------------------------------------------
(7919, 130107) (7919,) (3395, 130107) (3395,)
print(x_train[0])
-----------------
# (0번째 문서, index값) 몇 번 등장했는지
(0, 3220) 1 # 0번째 문서에 3220이라는 단어가 1번 등장했다.
(0, 3414) 1
(0, 5323) 1
(0, 5805) 1
(0, 6442) 1
(0, 6446) 1
(0, 6448) 1
(0, 6453) 1
(0, 11891) 1
(0, 12392) 2
(0, 13338) 1
(0, 14896) 1
(0, 15171) 2
(0, 17163) 1
(0, 17999) 1
(0, 18427) 2
(0, 19106) 1
(0, 20145) 1
(0, 20444) 1
(0, 20591) 3
(0, 20657) 2
(0, 20749) 2
(0, 21561) 1
(0, 25399) 3
(0, 25721) 1
: :
(0, 123759) 2
(0, 123796) 1
(0, 123984) 2
(0, 124026) 3
(0, 124031) 1
(0, 124046) 1
(0, 124147) 1
(0, 124332) 5
(0, 124397) 1
(0, 124501) 4
(0, 124507) 5
(0, 124509) 1
(0, 124616) 5
(0, 124640) 1
(0, 125007) 1
(0, 125079) 1
(0, 125110) 4
(0, 125271) 1
(0, 125296) 1
(0, 128022) 6
(0, 128026) 2
(0, 128084) 1
(0, 128096) 3
(0, 128402) 10
(0, 128420) 1
1. Scikit-learn을 이용한 문서 분류
Logistic Regression
- 로지스틱 회귀는 이름에 회귀라는 단어가 들어가지만, 가능한 클래스가 2개인 이진 분류를 위한 모델이다.
- 로지스틱 회귀의 예측 함수는 다음과 같이 정의한다.
$$ \sigma (x) = \frac{1}{1+e^{-x}} $$
$$ \hat{y} = \sigma (w_0 + w_1 x_1 + ... + w_p x_p) $$
- $\sigma$: 시그모이드 함수
- 로지스틱 회귀의 학습 목표는 다음과 같은 목적 함수를 최소화하는 파라미터 $w$를 찾는 것이다.
$$ \text{BinaryCrossEntropy} = -\frac{1}{N} \sum\limits_{i=1}^N y_i log(\hat{y}_i) + (1-y_i) log(1-\hat{y}_i)$$
- 로지스틱 회귀는 특성상 다중 분류에는 적합하지 않다.
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
LR = LogisticRegression()
LR.fit(x_train,y_train) # LR을 fit하는 과정(학습을 시킴)
pred = LR.predict(x_test) # 학습된 것에 대해서 predict(x_test에 대해 predict한 값을 받아옴)
acc = accuracy_score(pred,y_test) # predict값과 y_test값을 비교해서 accuracy측정
print(acc)
-------------------------------------------------------------------------------------
0.8621502209131076
Support Vector Machine
- 회귀, 분류, 이상치 탐지 등에 사용되는 지도학습 방법이다.
- 클래스 사이의 경계에 위치한 데이터 포인트를 서포트 벡터라고 한다.
- 각 서포트 벡터가 클래스 사이의 결정 경계를 구분하는데 얼마나 중요한지를 학습한다.
- 각 서포트 벡터 사이의 마진이 가장 큰 방향으로 학습한다.
- 서포트 벡터까지의 거리와 서포트 벡터들의 중요도를 기반으로 예측을 수행한다.
from sklearn import svm
SVM = svm.SVC(kernel='linear')
SVM.fit(x_train,y_train)
pred = SVM.predict(x_test)
acc = accuracy_score(pred,y_test)
print(acc)
---------------------------------
0.8220913107511045
Naive Bayes Classification
- 베이즈 정리를 적용한 확률적 분류 알고리즘이다.
- 모든 특성들이 독립임을 가정한다. (= naive 가정)
- 입력 특성에 따라 다음과 같은 3개의 분류기가 존재한다.
- 가우시안 나이브 베이즈 분류기
- 베르누이 나이브 베이즈 분류기
- 다항 나이브 베이즈 분류기
DTM을 이용한 나이브 베이즈
from sklearn.naive_bayes import MultinomialNB
NB = MultinomialNB()
NB.fit(x_train,y_train)
pred = NB.predict(x_test)
acc = accuracy_score(pred,y_test)
print(acc)
----------------------------------------------
0.8094256259204713
TF-IDF를 이용한 정확도 향상
from sklearn.feature_extraction.text import TfidfTransformer
tfidf = TfidfTransformer()
x_train_tf=tfidf.fit_transform(x_train)
x_test_tf=tfidf.fit_transform(x_test)
NB.fit(x_train_tf,y_train)
pred = NB.predict(x_test_tf)
acc = accuracy_score(pred,y_test)
print(acc)
-------------------------------------------------------------
0.795581737849779
- 왜인지 오히려 정확도가 떨어졌다.
Decision Tree
- 결정 트리는 분류와 회귀에 사용되는 지도학습 방법이다.
- 데이터 특성으로부터 추론된 결정 규칙을 통해 값을 예측한다.
- if-then-else 결정 규칙을 통해 데이터를 학습한다.
- 트리의 깊이가 깊을수록 복잡한 모델이다.
from sklearn.tree import DecisionTreeClassifier
DT = DecisionTreeClassifier()
DT.fit(x_train,y_train)
pred = DT.predict(x_test)
acc = accuracy_score(pred,y_test)
print(acc)
-----------------------------------------------
0.6156111929307806
XGBoost
- 트리 기반의 앙상블 기법이다.
- 분류에 있어서 다른 알고리즘보다 좋은 예측 성능을 보여준다.
- XGBoost는 GBM 기반이지만, GBM의 단점인 느린 수행 시간과 과적합 규제 부재 등의 문제를 해결하였다.
- 병렬 CPU 환경에서 빠르게 학습이 가능하다.
from xgboost import XGBClassifier
xgb = XGBClassifier(n_estimators=30,learning_rate=0.05,max_depth=3)
xgb.fit(x_train,y_train)
pred = xgb.predict(x_test)
acc = accuracy_score(pred,y_test)
print(acc)
-----------------------------------------------------------------
0.7054491899852725
교차 검증
- 일반 검증은 학습 데이터가 테스트 데이터로 사용되지 않는다.
- 교차 검증은 데이터를 n개의 집합으로 나누어 정확도를 계산해 학습 데이터로 사용된 데이터도 테스트 데이터로 사용한다.
- 교차 검증을 사용하면 일반 검증보다 모델의 일반화가 잘 되어 있는지 평가가 가능하다.
- 앞서 구성한 나이브 베이즈 모델을 교차 검증 하였다.
from sklearn.model_selection import cross_val_score
scores = cross_val_score(NB,x,y,cv=5)
print(scores,scores.mean())
---------------------------------------------------
[0.83870968 0.83826779 0.82368537 0.83031374 0.83642794] 0.833480903927519
- 교차 검증을 통해 일반 검증보다 좀 더 일반화된 모델 생성이 가능하다.
- 교차 검증은 일반 검증에 비해 n번 검증을 하여 비용이 더 많이 소요된다.
정밀도와 재현률
- 정밀도(Precision)는 양성 클래스로 예측한 샘플이 양성 클래스일 확률을 의미한다.
- 즉, 모델이 얼마나 양성 클래스를 잘 예측하는지를 나타낸다.
- 재현률(Recall)은 양성 클래스인 샘플에서 모델이 양성 클래스로 예측한 샘플 비율을 의미하며, 모델이 얼마나 실제 상황을 재현하는지를 나타낸다.
- 정밀도와 재현율의 가중 조화평균인 F1-Score라는 지표는 정확도에 비해 더 효과적인 모델 분석 지표이다.
- 다중 클래스 분류 문제에서 정밀도와 재현률을 계산할 때는 클래스 간의 지표를 어떻게 합칠지 지정이 필요하다.
- None: 클래스 간 지표를 합치지 말고 그대로 출력
- micro: 정밀도와 재현률이 같다. 이로 인해 F1-Score도 정밀도, 재현률과 동일하다.
- macro: 클래스 간 지표를 단순 평균한 값
- weighted: 클래스 간 지표를 가중 평균한 값
from sklearn.metrics import precision_score,recall_score,f1_score
precision = precision_score(pred,y_test,average='micro')
recall = recall_score(pred,y_test,average='micro')
f1 = f1_score(pred,y_test,average='micro')
print(precision,recall,f1)
-----------------------------------------------------------------
0.7054491899852725 0.7054491899852725 0.7054491899852725
그리드 검색을 이용한 파라미터 최적화
- 그리드 검색을 사용하면 분류기에 사용하는 파라미터 최적화가 가능하다.
- estimator: 사용 모델 객체
- param_gird: {사용 객체 : 지정 파라미터 리스트}
- scoring: 최적화하고자 하는 성능 지표
- cv: 교차 검증 분할 개수
from sklearn.model_selection import GridSearchCV
GS = GridSearchCV(estimator=NB,param_grid={'alpha':[0.001,0.01,0.1,1.]},scoring='accuracy',cv=10)
GS.fit(x,y)
print(GS.best_score_)
print(GS.best_params_)
--------------------------------------------------
0.8897820965842167
{'alpha': 0.001}
'Study' 카테고리의 다른 글
[NLP] 6. Topic Modeling (0) | 2024.08.21 |
---|---|
[NLP] 5. Semantic Network Analysis (0) | 2024.08.20 |
[NLP] 3. Cluster Analysis (0) | 2024.08.19 |
[NLP] 2. Keyword Analysis (1) | 2024.08.19 |
[NLP] 1. National Language Processing (0) | 2024.08.19 |