머신러닝
[파이썬 머신러닝] 4장. 스태킹 앙상블
오월&절미
2021. 1. 20. 00:37
In [11]:
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:1200px !important; }</style>"))
스태킹¶
- 개별적인 여러알고리즘을 서로 결합해 예측 결과를 도출.
개별 알고리즘으로 예측한 데이터를 기반으로 다시 예측을 수행. = 개별 알고리즘의 예측 결과 데이터 세트를 최종적인 메타 데이터 세트로 만들어 별도의 ML알고리즘으로 최종 학습을 수행. 테스트 데이터를 기반으로 다시 최종 예측을 수행.
개별적인 기반 모델과 최종 메타 모델이 필요 = 여러 개별 모델의 예측 데이터를 각각 스태킹 형태로 결합해 최종 메타 모델의 학습용 피처 데이터 세트와 테스트용 피처 데이터 세트를 만드는 것.
In [1]:
# 기본 스태킹 모델
import numpy as np
from sklearn.neighbors import KNeighborsClassifier #1.KNN모델
from sklearn.ensemble import RandomForestClassifier #2.랜덤포레스트
from sklearn.ensemble import AdaBoostClassifier #3.에이다부스트
from sklearn.tree import DecisionTreeClassifier #4.결정트리
from sklearn.linear_model import LogisticRegression #최종모델=로지스틱회귀
from sklearn.datasets import load_breast_cancer #데이터로드
from sklearn.model_selection import train_test_split #데이터 분리
from sklearn.metrics import accuracy_score #예측성능평가
cancer_data = load_breast_cancer()
X_data = cancer_data.data
y_label = cancer_data.target
X_train , X_test , y_train , y_test = train_test_split(X_data , y_label , test_size=0.2 , random_state=0)
In [2]:
# 개별 ML 모델을 위한 Classifier 생성.
knn_clf = KNeighborsClassifier(n_neighbors=4)
rf_clf = RandomForestClassifier(n_estimators=100, random_state=0)
dt_clf = DecisionTreeClassifier()
ada_clf = AdaBoostClassifier(n_estimators=100)
# 최종 Stacking 모델을 위한 Classifier생성.
lr_final = LogisticRegression(C=10)
In [3]:
# 개별 모델들을 학습.
knn_clf.fit(X_train, y_train)
rf_clf.fit(X_train , y_train)
dt_clf.fit(X_train , y_train)
ada_clf.fit(X_train, y_train)
Out[3]:
AdaBoostClassifier(n_estimators=100)
In [4]:
# 학습된 개별 모델들이 각자 반환하는 예측 데이터 셋을 생성하고 개별 모델의 정확도 측정.
knn_pred = knn_clf.predict(X_test)
rf_pred = rf_clf.predict(X_test)
dt_pred = dt_clf.predict(X_test)
ada_pred = ada_clf.predict(X_test)
print('KNN 정확도: {0:.4f}'.format(accuracy_score(y_test, knn_pred)))
print('랜덤 포레스트 정확도: {0:.4f}'.format(accuracy_score(y_test, rf_pred)))
print('결정 트리 정확도: {0:.4f}'.format(accuracy_score(y_test, dt_pred)))
print('에이다부스트 정확도: {0:.4f} :'.format(accuracy_score(y_test, ada_pred)))
KNN 정확도: 0.9211 랜덤 포레스트 정확도: 0.9649 결정 트리 정확도: 0.9035 에이다부스트 정확도: 0.9561 :
In [5]:
"""
개별 알고리즘으로부터 예측된 예측값을
칼럼 레벨로 옆으로 부여서 피처 값으로 만들고 최종 메타모델의 학습 데이터로 사용
> 반환된 예측 데이터 세트는 1차원 형태의 ndarray이므로
먼저 반환된 예측 결과를 행 형태로 붙인뒤
넘파이 transpose()를 이용해 행과 열 위치를 바꾼 ndarray로 반환
"""
pred = np.array([knn_pred, rf_pred, dt_pred, ada_pred])
print("개별 모델 결과를 옆으로 붙인 pred")
print(pred.shape)
# transpose를 이용해 행과 열의 위치 교환. 컬럼 레벨로 각 알고리즘의 예측 결과를 피처로 만듦.
pred = np.transpose(pred)
print("행과 열의 위치 교환 확인")
print(pred.shape)
개별 모델 결과를 옆으로 붙인 pred (4, 114) 행과 열의 위치 교환 확인 (114, 4)
In [6]:
# 최종 로지스틱 회귀 모델로 예측
lr_final.fit(pred, y_test)
final = lr_final.predict(pred)
print('최종 메타 모델의 예측 정확도: {0:.4f}'.format(accuracy_score(y_test , final)))
최종 메타 모델의 예측 정확도: 0.9737
CV 세트 기반의 스태킹¶
- 과적합을 개선하기 위해 최종 메타 모델을 위한 데이터 세트를 만들 때 교차 검증 기반으로 예측된 결과 데이터 세트를 이용.
- 개별 모델들이 각각 교차 검증으로 메타 모델을 위한 학습용 스태킹 데이터 생성과 예측을 위한 테스트용 스태킹 데이터를 생성한 뒤 이를 기반으로 메타 모델이 학습과 에측을 수행.
In [7]:
from sklearn.model_selection import KFold
from sklearn.metrics import mean_absolute_error
# 개별 기반 모델에서 최종 메타 모델이 사용할 학습 및 테스트용 데이터를 생성하기 위한 함수.
# 개별 모델 객체, 원본인 학습용 피처 데이터, 원본인 학습용 레이블 데이터, 원본인 테스트 피처 데이터, K폴드를 몇개로 할 지.
def get_stacking_base_datasets(model, X_train_n, y_train_n, X_test_n, n_folds ):
# 지정된 n_folds값으로 KFold 생성.
kf = KFold(n_splits=n_folds, shuffle=False, random_state=0)
#추후에 메타 모델이 사용할 학습 데이터 반환을 위한 넘파이 배열 초기화
train_fold_pred = np.zeros((X_train_n.shape[0] ,1 ))
test_pred = np.zeros((X_test_n.shape[0],n_folds))
print(model.__class__.__name__ , ' model 시작 ')
#학습
for folder_counter , (train_index, valid_index) in enumerate(kf.split(X_train_n)):
#입력된 학습 데이터에서 기반 모델이 학습/예측할 폴드 데이터 셋 추출
print('\t 폴드 세트: ',folder_counter,' 시작 ')
X_tr = X_train_n[train_index]
y_tr = y_train_n[train_index]
X_te = X_train_n[valid_index]
#폴드 세트 내부에서 다시 만들어진 학습 데이터로 기반 모델의 학습 수행.
model.fit(X_tr , y_tr)
#폴드 세트 내부에서 다시 만들어진 검증 데이터로 기반 모델 예측 후 데이터 저장.
train_fold_pred[valid_index, :] = model.predict(X_te).reshape(-1,1)
#입력된 원본 테스트 데이터를 폴드 세트내 학습된 기반 모델에서 예측 후 데이터 저장.
test_pred[:, folder_counter] = model.predict(X_test_n)
# 테스트
# 폴드 세트 내에서 원본 테스트 데이터를 예측한 데이터를 평균하여 테스트 데이터로 생성
test_pred_mean = np.mean(test_pred, axis=1).reshape(-1,1)
#train_fold_pred는 최종 메타 모델이 사용하는 학습 데이터, test_pred_mean은 테스트 데이터
return train_fold_pred , test_pred_mean
In [8]:
knn_train, knn_test = get_stacking_base_datasets(knn_clf, X_train, y_train, X_test, 7)
rf_train, rf_test = get_stacking_base_datasets(rf_clf, X_train, y_train, X_test, 7)
dt_train, dt_test = get_stacking_base_datasets(dt_clf, X_train, y_train, X_test, 7)
ada_train, ada_test = get_stacking_base_datasets(ada_clf, X_train, y_train, X_test, 7)
C:\Users\LG\anaconda3\envs\pjt\lib\site-packages\sklearn\model_selection\_split.py:297: FutureWarning: Setting a random_state has no effect since shuffle is False. This will raise an error in 0.24. You should leave random_state to its default (None), or set shuffle=True. FutureWarning C:\Users\LG\anaconda3\envs\pjt\lib\site-packages\sklearn\model_selection\_split.py:297: FutureWarning: Setting a random_state has no effect since shuffle is False. This will raise an error in 0.24. You should leave random_state to its default (None), or set shuffle=True. FutureWarning
KNeighborsClassifier model 시작 폴드 세트: 0 시작 폴드 세트: 1 시작 폴드 세트: 2 시작 폴드 세트: 3 시작 폴드 세트: 4 시작 폴드 세트: 5 시작 폴드 세트: 6 시작 RandomForestClassifier model 시작 폴드 세트: 0 시작 폴드 세트: 1 시작 폴드 세트: 2 시작 폴드 세트: 3 시작 폴드 세트: 4 시작 폴드 세트: 5 시작 폴드 세트: 6 시작
C:\Users\LG\anaconda3\envs\pjt\lib\site-packages\sklearn\model_selection\_split.py:297: FutureWarning: Setting a random_state has no effect since shuffle is False. This will raise an error in 0.24. You should leave random_state to its default (None), or set shuffle=True. FutureWarning C:\Users\LG\anaconda3\envs\pjt\lib\site-packages\sklearn\model_selection\_split.py:297: FutureWarning: Setting a random_state has no effect since shuffle is False. This will raise an error in 0.24. You should leave random_state to its default (None), or set shuffle=True. FutureWarning
DecisionTreeClassifier model 시작 폴드 세트: 0 시작 폴드 세트: 1 시작 폴드 세트: 2 시작 폴드 세트: 3 시작 폴드 세트: 4 시작 폴드 세트: 5 시작 폴드 세트: 6 시작 AdaBoostClassifier model 시작 폴드 세트: 0 시작 폴드 세트: 1 시작 폴드 세트: 2 시작 폴드 세트: 3 시작 폴드 세트: 4 시작 폴드 세트: 5 시작 폴드 세트: 6 시작
In [9]:
# 각 모델별 학습 데이터와 테스트데이터를 합치기 > concatenate() 함수 사용
Stack_final_X_train = np.concatenate((knn_train, rf_train, dt_train, ada_train), axis=1)
Stack_final_X_test = np.concatenate((knn_test, rf_test, dt_test, ada_test), axis=1)
print('원본 학습 피처 데이터 Shape:',X_train.shape, '원본 테스트 피처 Shape:',X_test.shape)
print('스태킹 학습 피처 데이터 Shape:', Stack_final_X_train.shape,
'스태킹 테스트 피처 데이터 Shape:',Stack_final_X_test.shape)
원본 학습 피처 데이터 Shape: (455, 30) 원본 테스트 피처 Shape: (114, 30) 스태킹 학습 피처 데이터 Shape: (455, 4) 스태킹 테스트 피처 데이터 Shape: (114, 4)
In [10]:
# 최종= 로지스틱 회귀
lr_final.fit(Stack_final_X_train, y_train)
stack_final = lr_final.predict(Stack_final_X_test)
print('최종 메타 모델의 예측 정확도: {0:.4f}'.format(accuracy_score(y_test, stack_final)))
최종 메타 모델의 예측 정확도: 0.9737
In [ ]: