-
[분류] 앙상블머신러닝 & 딥러닝 2021. 10. 14. 21:43
앙상블 Learning
- 여러개의 분류기를 생성하여 그 예측을 결합
앙상블 학습 유형 : Voting, Bagging, Boosting, Stacking 등Voting Classifier
- 여러 개의 분류기가 투표를 통해 최종 예측 결과를 결정하는 방식
- 서로 다른 알고리즘을 가진 분류기를 결합
Hard Voting
- 다수결 원칙과 비슷
Soft Voting
- 분류기들의 레이블 값 결정 확률을 모두 더하고 이를 평균해서 이들 중 확률이 가장 높은 레이블 값을 최종 보팅 결과값으로 선정
- 일반적으로 하드 보팅보다 예측 성능이 더 좋다.
import pandas as pd from sklearn.ensemble import VotingClassifier from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score cancer = load_breast_cancer() data_df = pd.DataFrame(cancer.data, columns=cancer.feature_names) data_df.head(3)
# 개별 모델은 로지스틱 회귀와 KNN 임. lr_clf = LogisticRegression() knn_clf = KNeighborsClassifier(n_neighbors=8) # 개별 모델을 소프트 보팅 기반의 앙상블 모델로 구현한 분류기 vo_clf = VotingClassifier( estimators=[('LR',lr_clf),('KNN',knn_clf)] , voting='soft' ) X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, test_size=0.2 , random_state= 156) # VotingClassifier 학습/예측/평가. vo_clf.fit(X_train , y_train) pred = vo_clf.predict(X_test) print('Voting 분류기 정확도: {0:.4f}'.format(accuracy_score(y_test , pred))) # 개별 모델의 학습/예측/평가. classifiers = [lr_clf, knn_clf] for classifier in classifiers: classifier.fit(X_train , y_train) pred = classifier.predict(X_test) class_name= classifier.__class__.__name__ print('{0} 정확도: {1:.4f}'.format(class_name, accuracy_score(y_test , pred)))
Voting 분류기 정확도: 0.9474
LogisticRegression 정확도: 0.9386
KNeighborsClassifier 정확도: 0.93861.2 Bagging
- 여러 개의 분류기가 투표를 통해 최종 예측 결과를 결정하는 방식
- 모두 같은 유형의 알고리즘 기반이지만, 데이터 샘플링을 서로 다르게 가져가면서 학습을 수행해 보팅을 수행.
- 대표적인 배깅 방식이 랜덤 포레스트 알고리즘
- 개별 classifier에게 데이터를 샘플링해서 추출하는 방식을 부트스트래핑(Bootstrapping) 분할 방식이라 한다.
- 개별 분류기가 부트스트래핑 방식으로 샘플링된 데이터 세트에 대해서 학습을 통해 개별적인 예측을 수행한 결과를 보팅을 통해서 최종 예측 결과를 선정하는 방식이 배깅 앙상블 방식.
- 데이터 중복 허용.
import pandas as pd def get_new_feature_name_df(old_feature_name_df): feature_dup_df = pd.DataFrame(data=old_feature_name_df.groupby('column_name').cumcount(), columns=['dup_cnt']) feature_dup_df = feature_dup_df.reset_index() new_feature_name_df = pd.merge(old_feature_name_df.reset_index(), feature_dup_df, how='outer') new_feature_name_df['column_name'] = new_feature_name_df[['column_name', 'dup_cnt']].apply(lambda x : x[0]+'_'+str(x[1]) if x[1] >0 else x[0] , axis=1) new_feature_name_df = new_feature_name_df.drop(['index'], axis=1) return new_feature_name_df
import pandas as pd def get_human_dataset( ): # 각 데이터 파일들은 공백으로 분리되어 있으므로 read_csv에서 공백 문자를 sep으로 할당. feature_name_df = pd.read_csv('../human_activity/features.txt',sep='\s+', header=None,names=['column_index','column_name']) # 중복된 feature명을 새롭게 수정하는 get_new_feature_name_df()를 이용하여 새로운 feature명 DataFrame생성. new_feature_name_df = get_new_feature_name_df(feature_name_df) # DataFrame에 피처명을 컬럼으로 부여하기 위해 리스트 객체로 다시 변환 feature_name = new_feature_name_df.iloc[:, 1].values.tolist() # 학습 피처 데이터 셋과 테스트 피처 데이터을 DataFrame으로 로딩. 컬럼명은 feature_name 적용 X_train = pd.read_csv('../human_activity/train/X_train.txt',sep='\s+', names=feature_name ) X_test = pd.read_csv('../human_activity/test/X_test.txt',sep='\s+', names=feature_name) # 학습 레이블과 테스트 레이블 데이터을 DataFrame으로 로딩하고 컬럼명은 action으로 부여 y_train = pd.read_csv('../human_activity/train/y_train.txt',sep='\s+',header=None,names=['action']) y_test = pd.read_csv('../human_activity/test/y_test.txt',sep='\s+',header=None,names=['action']) # 로드된 학습/테스트용 DataFrame을 모두 반환 return X_train, X_test, y_train, y_test X_train, X_test, y_train, y_test = get_human_dataset()
1.2.1 학습/테스트 데이터로 분리하고 랜덤 포레스트로 학습/예측/평가
from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score import pandas as pd import warnings warnings.filterwarnings('ignore') # 결정 트리에서 사용한 get_human_dataset( )을 이용해 학습/테스트용 DataFrame 반환 X_train, X_test, y_train, y_test = get_human_dataset() # 랜덤 포레스트 학습 및 별도의 테스트 셋으로 예측 성능 평가 rf_clf = RandomForestClassifier(random_state=0) rf_clf.fit(X_train , y_train) pred = rf_clf.predict(X_test) accuracy = accuracy_score(y_test , pred) print('랜덤 포레스트 정확도: {0:.4f}'.format(accuracy))
랜덤 포레스트 정확도: 0.9253
1.2.2 GridSearchCV 로 교차검증 및 하이퍼 파라미터 튜닝
from sklearn.model_selection import GridSearchCV params = { 'n_estimators':[100], 'max_depth' : [6, 8, 10, 12], 'min_samples_leaf' : [8, 12, 18 ], 'min_samples_split' : [8, 16, 20] } # RandomForestClassifier 객체 생성 후 GridSearchCV 수행 rf_clf = RandomForestClassifier(random_state=0, n_jobs=-1) grid_cv = GridSearchCV(rf_clf , param_grid=params , cv=2, n_jobs=-1 ) grid_cv.fit(X_train , y_train) print('최적 하이퍼 파라미터:\n', grid_cv.best_params_) print('최고 예측 정확도: {0:.4f}'.format(grid_cv.best_score_))
최적 하이퍼 파라미터: {'max_depth': 10, 'min_samples_leaf': 8, 'min_samples_split': 8, 'n_estimators': 100}
최고 예측 정확도: 0.91801.2.3 튜닝된 하이퍼 파라미터로 재 학습 및 예측/평가
rf_clf1 = RandomForestClassifier(n_estimators=300, max_depth=10, min_samples_leaf=8, \ min_samples_split=8, random_state=0) rf_clf1.fit(X_train , y_train) pred = rf_clf1.predict(X_test) print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test , pred)))
예측 정확도: 0.9165
1.2.4 개별 feature들의 중요도 시각화
import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline ftr_importances_values = rf_clf1.feature_importances_ ftr_importances = pd.Series(ftr_importances_values,index=X_train.columns ) ftr_top20 = ftr_importances.sort_values(ascending=False)[:20] plt.figure(figsize=(8,6)) plt.title('Feature importances Top 20') sns.barplot(x=ftr_top20 , y = ftr_top20.index) plt.show()
1.3 Boosting
- 대표적인 구현은 AdaBoost, 그래디언트 부스트, XGBoost, LightGBM
- 약한 학습기를 순차적으로 학습-예측
- 앞에서 학습한 분류기가 예측이 틀린 데이터에 대해서는 올바르게 예측할 수 있도록 다음 분류기에게는 가중치(weight)를 부여하면서 학습과 예측 진행.
1.3.1 GBM (Gradient Boost Machine)
- 오류 값 = 실제 값 - 예측 값
- 반복 수행을 통해 오류를 최소화 할 수 있게 한다.
- 에이다부스트와 유사하나 가중치 업데이트를 경사 하강법(Gradient Descent)를 이용
1.3.2 사이킷런 GBM
- GradientBoostingClassifier 클래스 제공
- learning_rate : GBM이 학습을 진행 할 때마다 적용하는 학습률.
- subsample : 학습에 사용하는 데이터의 샘플링 비율.
GBM(Gradient Boosting Machine)from sklearn.ensemble import GradientBoostingClassifier import time import warnings warnings.filterwarnings('ignore') X_train, X_test, y_train, y_test = get_human_dataset() # GBM 수행 시간 측정을 위함. 시작 시간 설정. start_time = time.time() gb_clf = GradientBoostingClassifier(random_state=0) gb_clf.fit(X_train , y_train) gb_pred = gb_clf.predict(X_test) gb_accuracy = accuracy_score(y_test, gb_pred) print('GBM 정확도: {0:.4f}'.format(gb_accuracy)) print("GBM 수행 시간: {0:.1f} 초 ".format(time.time() - start_time))
GBM 정확도: 0.9393
GBM 수행 시간: 532.8 초
from sklearn.model_selection import GridSearchCV params = { 'n_estimators':[100, 500], 'learning_rate' : [ 0.05, 0.1] } grid_cv = GridSearchCV(gb_clf , param_grid=params , cv=2 ,verbose=1) grid_cv.fit(X_train , y_train) print('최적 하이퍼 파라미터:\n', grid_cv.best_params_) print('최고 예측 정확도: {0:.4f}'.format(grid_cv.best_score_))
scores_df = pd.DataFrame(grid_cv.cv_results_) scores_df[['params', 'mean_test_score', 'rank_test_score', 'split0_test_score', 'split1_test_score']]
# GridSearchCV를 이용하여 최적으로 학습된 estimator로 predict 수행. gb_pred = grid_cv.best_estimator_.predict(X_test) gb_accuracy = accuracy_score(y_test, gb_pred) print('GBM 정확도: {0:.4f}'.format(gb_accuracy))
GBM 정확도: 0.9196
[파이썬 머신러닝 완벽 가이드] 교재를 바탕으로 쓴 블로그입니다.
'머신러닝 & 딥러닝' 카테고리의 다른 글
[회귀] Lidge/Lasso/ElasticNet (0) 2021.10.19 [회귀] 다항 회귀 및 과대/과소 적합 (0) 2021.10.18 [분류] 결정 트리 (0) 2021.10.13 [평가] 정확도/정밀도/재현율/F1 스코어/ROC AUC (0) 2021.10.05 [사이킷런] 타이타닉 생존자 예측하기 (0) 2021.10.01