[ML] day5 지도 학습 - 앙상블 학습
* 앙상블 학습 ( ensemble learning )
- 여러 가지 지도학습 알고리즘을 조합해서 데이터를 학습
- 트레이닝 데이터를 활용한 분류 모형을 여러 개 만들고 비교
- 개별 분류 모형을 분류기( classifier )
- 성능이 낮은 분류기를 조합해 성능 좋은 분류기 생성
보팅 ( Voting )
* 보팅
: 여러 가지 지도학습 알고리즘의 결과를 투표를 통해 최종 라벨 지정
* 실습
import pandas as pd
df = pd.read_csv('./data/wine_data.csv')
features = ['Alcohol', 'Malic', 'Ash', 'Alcalinity', 'Magesium', 'Phenols',
'Flavanoids', 'Nonflavanoids', 'Proanthocyanins', 'Color', 'Hue',
'Dilution', 'Proline']
X = df[features]
y = df['class']
# 트레이닝/테스트 데이터 분할
from sklearn.model_selection import train_test_split
X_tn, X_te, y_tn, y_te = train_test_split(X, y, random_state=0)
# 데이터 표준화
from sklearn.preprocessing import StandardScaler
std_scale = StandardScaler()
std_scale.fit(X_tn)
X_tn_std = std_scale.transform(X_tn)
X_te_std = std_scale.transform(X_te)
# 보팅 학습
from sklearn.linear_model import LogisticRegression
from sklearn import svm
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import VotingClassifier
clf1 = LogisticRegression()
clf2 = svm.SVC(kernel='linear')
clf3 = GaussianNB()
clf_voting = VotingClassifier(
estimators=[
('lr', clf1),
('svm', clf2),
('gnb', clf3)
],
voting='hard',
weights=[1,1,1])
clf_voting.fit(X_tn_std, y_tn)
- v o t i n g :
- hard : 많이 나온 클래스값을 예측값으로 사용
- soft : 결과값 ( 각 클래스별 예측 확률의 평균값 ) 이 가장 높은 값을 예측값으로 사용
=> 두 개의 차이가 크게 존재하지 않음
# 예측
pred_voting = clf_voting.predict(X_te_std)
print(pred_voting)
### 결과값 ###
[0 2 1 0 1 1 0 2 1 1 2 2 0 1 2 1 0 0 1 0 1 0 0 1 1 1 1 1 1 2 0 0 1 0 0 0 2
1 1 2 0 0 1 1 1]
# 정확도
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_te, pred_voting)
print("accuracy:", accuracy)
# 정밀도
from sklearn.metrics import precision_score
precision = precision_score(y_te, pred_voting, average='macro')
print("precision:", precision)
# 리콜
from sklearn.metrics import recall_score
recall = recall_score(y_te, pred_voting, average='macro')
print("recall:", recall)
# F1 스코어
from sklearn.metrics import f1_score
f1 = f1_score(y_te, pred_voting, average='macro')
print("f1:", f1)
### 결과값 ###
accuracy: 1.0
precision: 1.0
recall: 1.0
f1: 1.0
# confusion matrix 확인
from sklearn.metrics import confusion_matrix
conf_matrix = confusion_matrix(y_te, pred_voting)
print(conf_matrix)
### 결과물 ###
[[16 0 0]
[ 0 21 0]
[ 0 0 8]]
# 분류 레포트 확인
from sklearn.metrics import classification_report
class_report = classification_report(y_te, pred_voting)
print(class_report)
### 결과물 ###
precision recall f1-score support
0 1.00 1.00 1.00 16
1 1.00 1.00 1.00 21
2 1.00 1.00 1.00 8
accuracy 1.00 45
macro avg 1.00 1.00 1.00 45
weighted avg 1.00 1.00 1.00 45
배깅 (Bagging)
* 배깅(bagging)
- 개별 분류기들의 분류 결과를 종합 후 최종 분류기 성능 향상
- 부트스트랩(bootstrap) 샘플을 뽑아 학습
- 부트스트랩(bootstrap) : 중복을 허용한 랜덤 샘플 방법을 의미
==> 랜덤으로 샘플을 뽑아 학습 like 미니배치 minibatch
* 랜덤 포레스트 (Random Forest)
- training 데이터에서 중복을 허용하여 랜덤 샘플링(bootstrap) ==> 배깅(bagging)
- feature 선택 시에는 중복이 허용 안됨
* 실습 ( 랜덤 포레스트 )
import pandas as pd
df = pd.read_csv('./data/wine_data.csv')
features = ['Alcohol', 'Malic', 'Ash', 'Alcalinity', 'Magesium', 'Phenols',
'Flavanoids', 'Nonflavanoids', 'Proanthocyanins', 'Color', 'Hue',
'Dilution', 'Proline']
X = df[features]
y = df['class']
# 트레이닝/테스트 데이터 분할
from sklearn.model_selection import train_test_split
X_tn, X_te, y_tn, y_te = train_test_split(X, y, random_state=0)
# 데이터 표준화
from sklearn.preprocessing import StandardScaler
std_scale = StandardScaler()
std_scale.fit(X_tn)
X_tn_std = std_scale.transform(X_tn)
X_te_std = std_scale.transform(X_te)
# 랜덤포레스트
from sklearn.ensemble import RandomForestClassifier
clf_rf = RandomForestClassifier(max_depth=2,
random_state=0)
clf_rf.fit(X_tn_std, y_tn)
- max_depth : 각 decision tree의 깊이
- 의사 결정 나무는 데이터 표준화를 안하는게 결과가 좋은 경우 有
( ∵ 파이썬의 IF문과 비슷한 로직이므로 단위의 영향을 받지 않음 )
ex) 유치원생의 키 : 100 & 대학생의 키 : 180
표준화 하면 유치원생 : 0.6 & 대학생 : 1.3
=> 표준화를 하면 격차가 적어짐
# 예측
pred_rf = clf_rf.predict(X_te_std)
print(pred_rf)
### 결과값 ###
[0 2 1 0 1 1 0 2 1 1 2 2 0 1 2 1 0 0 2 0 0 0 0 1 1 1 1 1 1 2 0 0 1 0 0 0 2
1 1 2 0 0 1 1 1]
# 정확도
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_te, pred_rf)
print("accuracy:", accuracy)
# 정밀도
from sklearn.metrics import precision_score
precision = precision_score(y_te, pred_rf, average='macro')
print("precision:", precision)
# 리콜
from sklearn.metrics import recall_score
recall = recall_score(y_te, pred_rf, average='macro')
print("recall:", recall)
# F1 스코어
from sklearn.metrics import f1_score
f1 = f1_score(y_te, pred_rf, average='macro')
print("f1:", f1)
### 결과값 ###
accuracy: 0.9555555555555556
precision: 0.943355119825708
recall: 0.9682539682539683
f1: 0.9536244800950685
# confusion matrix 확인
from sklearn.metrics import confusion_matrix
conf_matrix = confusion_matrix(y_te, pred_rf)
print(conf_matrix)
### 결과값 ###
[[16 0 0]
[ 1 19 1]
[ 0 0 8]]
# 분류 레포트 확인
from sklearn.metrics import classification_report
class_report = classification_report(y_te, pred_rf)
print(class_report)
### 결과값 ###
precision recall f1-score support
0 0.94 1.00 0.97 16
1 1.00 0.90 0.95 21
2 0.89 1.00 0.94 8
accuracy 0.96 45
macro avg 0.94 0.97 0.95 45
weighted avg 0.96 0.96 0.96 45
* 실습 ( 배깅 bagging )
# 배깅 학습
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import BaggingClassifier
clf_bagging = BaggingClassifier(estimator=GaussianNB(),
n_estimators=10,
random_state=0)
clf_bagging.fit(X_tn_std, y_tn)
- n _ estimator : 모형의 갯수 즉, 하나의 분류기가 모델을 시행하는 횟수
- 위의 예제는 나이브 베이즈 알고리즘 사용 ( default는 의사결정나무)
# 예측
pred_bagging = clf_bagging.predict(X_te_std)
print(pred_bagging)
### 결과값 ###
[0 2 1 0 1 1 0 2 1 1 2 2 0 1 2 1 0 0 2 0 0 0 0 1 1 1 1 1 1 2 0 0 1 0 0 0 2
1 1 2 0 0 1 1 1]
# 정확도
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_te, pred_bagging)
print("accuracy:", accuracy)
# 정밀도
from sklearn.metrics import precision_score
precision = precision_score(y_te, pred_bagging, average='macro')
print("precision:", precision)
# 리콜
from sklearn.metrics import recall_score
recall = recall_score(y_te, pred_bagging, average='macro')
print("recall:", recall)
# F1 스코어
from sklearn.metrics import f1_score
f1 = f1_score(y_te, pred_bagging, average='macro')
print("f1:", f1)
### 결과값 ###
accuracy: 0.9555555555555556
precision: 0.943355119825708
recall: 0.9682539682539683
f1: 0.9536244800950685
# confusion matrix 확인
from sklearn.metrics import confusion_matrix
conf_matrix = confusion_matrix(y_te, pred_bagging)
print(conf_matrix)
### 결과값 ###
[[16 0 0]
[ 1 19 1]
[ 0 0 8]]
# 분류 레포트 확인
from sklearn.metrics import classification_report
class_report = classification_report(y_te, pred_bagging)
print(class_report)
### 결과값 ###
precision recall f1-score support
0 0.94 1.00 0.97 16
1 1.00 0.90 0.95 21
2 0.89 1.00 0.94 8
accuracy 0.96 45
macro avg 0.94 0.97 0.95 45
weighted avg 0.96 0.96 0.96 45
부스팅 ( Boosting )
* 부스팅 ( boosting )
- 분류하기 어려운 데이터 포인트에 가중치를 할당
- 학습이 진행되면서 올바르게 분류된 데이터의 가중치는 감소 / 잘못 분류된 데이터의 가중치는 증가
==> 학습이 진행되면서 학습기는 분류하기 어려운 데이터에 집중
- 보팅, 배깅과 다르게 parallel 하지 않음
=> 예를 들어 보팅, 배깅은 여러명이 동시에 문제를 풀지만 부스팅은 한명식 차례로 문제를 품
* 실습
# 에이다 부스트
from sklearn.ensemble import AdaBoostClassifier
clf_ada = AdaBoostClassifier(random_state=0)
clf_ada.fit(X_tn_std, y_tn)
# 예측
pred_ada = clf_ada.predict(X_te_std)
print(pred_ada)
### 결과값 ###
[0 2 0 0 1 0 0 2 1 1 2 2 0 0 2 1 0 0 1 0 0 0 0 1 1 1 1 1 1 2 0 0 1 0 0 0 2
1 0 2 1 0 1 1 1]
# 정확도
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_te, pred_ada)
print("accuracy:", accuracy)
# 정밀도
from sklearn.metrics import precision_score
precision = precision_score(y_te, pred_ada, average='macro')
print("precision:", precision)
# 리콜
from sklearn.metrics import recall_score
recall = recall_score(y_te, pred_ada, average='macro')
print("recall:", recall)
# F1 스코어
from sklearn.metrics import f1_score
f1 = f1_score(y_te, pred_ada, average='macro')
print("f1:", f1)
### 결과물 ###
accuracy: 0.8666666666666667
precision: 0.8970588235294118
recall: 0.8998015873015873
f1: 0.8918128654970761
# confusion matrix 확인
from sklearn.metrics import confusion_matrix
conf_matrix = confusion_matrix(y_te, pred_ada)
print(conf_matrix)
### 결과물 ###
[[15 1 0]
[ 5 16 0]
[ 0 0 8]]
# 분류 레포트 확인
from sklearn.metrics import classification_report
class_report = classification_report(y_te, pred_ada)
print(class_report)
### 결과물 ###
precision recall f1-score support
0 0.75 0.94 0.83 16
1 0.94 0.76 0.84 21
2 1.00 1.00 1.00 8
accuracy 0.87 45
macro avg 0.90 0.90 0.89 45
weighted avg 0.88 0.87 0.87 45
* 실습 ( 그래디언트 부스팅 )
# Gradient Boosting 학습
from sklearn.ensemble import GradientBoostingClassifier
clf_gbt = GradientBoostingClassifier(max_depth=2,
learning_rate=0.1,
random_state=0)
clf_gbt.fit(X_tn_std, y_tn)
# 예측
pred_gbt = clf_gbt.predict(X_te_std)
print(pred_gbt)
### 결과값 ###
[0 2 1 0 1 0 0 2 1 1 2 2 0 1 2 1 0 0 2 0 1 0 0 1 1 1 1 1 1 2 0 0 1 0 0 0 2
1 1 2 0 0 1 1 1]
# 정확도
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_te, pred_gbt)
print("accuracy:", accuracy)
# 정밀도
from sklearn.metrics import precision_score
precision = precision_score(y_te, pred_gbt, average='macro')
print("precision:", precision)
# 리콜
from sklearn.metrics import recall_score
recall = recall_score(y_te, pred_gbt, average='macro')
print("recall:", recall)
# F1 스코어
from sklearn.metrics import f1_score
f1 = f1_score(y_te, pred_gbt, average='macro')
print("f1:", f1)
### 결과값 ###
accuracy: 0.9555555555555556
precision: 0.943355119825708
recall: 0.9682539682539683
f1: 0.9536244800950685
# confusion matrix 확인
from sklearn.metrics import confusion_matrix
conf_matrix = confusion_matrix(y_te, pred_gbt)
print(conf_matrix)
### 결과값 ###
[[16 0 0]
[ 1 19 1]
[ 0 0 8]]
# 분류 레포트 확인
from sklearn.metrics import classification_report
class_report = classification_report(y_te, pred_gbt)
print(class_report)
### 결과물 ###
precision recall f1-score support
0 0.94 1.00 0.97 16
1 1.00 0.90 0.95 21
2 0.89 1.00 0.94 8
accuracy 0.96 45
macro avg 0.94 0.97 0.95 45
weighted avg 0.96 0.96 0.96 45
스태킹 ( Stacking )
* 스태킹 (stacking)
- 여러 가지 학습기를 쌓는 방법
- 스태킹 : 베이스 학습기(base learner)와 메타 학습기(meta learner)
- 베이스 학습기가 먼저 학습
- 메타 학습기는 베이스 학습기의 예측을 피처 데이터로 활용해 최종 예측
* 실습
# 스태킹
from sklearn import svm
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import StackingClassifier
clf1 = svm.SVC(kernel='linear', random_state=1)
clf2 = GaussianNB()
clf_stkg = StackingClassifier(
estimators=[
('svm', clf1),
('gnb', clf2)
],
final_estimator=LogisticRegression())
clf_stkg.fit(X_tn_std, y_tn)
- 베이스 학습기 : 서포트 벡터 머신 & 나이브 베이즈 알고리즘
- 메타 학습기 : 로지스틱 회귀분석
# 예측
pred_stkg = clf_stkg.predict(X_te_std)
print(pred_stkg)
### 결과값 ###
[0 2 1 0 1 1 0 2 1 1 2 2 0 1 2 1 0 0 2 0 0 0 0 1 1 1 1 1 1 2 0 0 1 0 0 0 2
1 1 2 0 0 1 1 1]
# 정확도
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_te, pred_stkg)
print("accuracy:", accuracy)
# 정밀도
from sklearn.metrics import precision_score
precision = precision_score(y_te, pred_stkg, average='macro')
print("precision:", precision)
# 리콜
from sklearn.metrics import recall_score
recall = recall_score(y_te, pred_stkg, average='macro')
print("recall:", recall)
# F1 스코어
from sklearn.metrics import f1_score
f1 = f1_score(y_te, pred_stkg, average='macro')
print("f1:", f1)
### 결과값 ###
accuracy: 0.9555555555555556
precision: 0.943355119825708
recall: 0.9682539682539683
f1: 0.9536244800950685
# confusion matrix 확인
from sklearn.metrics import confusion_matrix
conf_matrix = confusion_matrix(y_te, pred_stkg)
print(conf_matrix)
### 결과값 ###
[[16 0 0]
[ 1 19 1]
[ 0 0 8]]
# 분류 레포트 확인
from sklearn.metrics import classification_report
class_report = classification_report(y_te, pred_stkg)
print(class_report)
### 결과값 ###
precision recall f1-score support
0 0.94 1.00 0.97 16
1 1.00 0.90 0.95 21
2 0.89 1.00 0.94 8
accuracy 0.96 45
macro avg 0.94 0.97 0.95 45
weighted avg 0.96 0.96 0.96 45