-
[2022_하계_모각코] 3회차(07/25)[CNU] Mogakco 2022. 7. 25. 21:10
3회차 목표
04. 분류 - 랜덤포레스트, GBM, XGBoost, LightGBM, 산탄데르 고객 만족 예측 캐글 심부전증 예측
4. 랜덤 포레스트
배깅(bagging)은 앞에서 소개한 보팅(Voting)과는 다르게, 같은 알고리즘으로 여러 개의 분류기를 만들어서 보팅으로 최종 결정하는 알고리즘이다. 배깅의 대표적인 알고리즘은 랜덤 포레스트이다. 랜덤 포레스트는 다재다능한 알고리즘이다.
- 앙상블 알고리즘 중 비교적 빠른 수행.
- 다양한 영역에서 높은 예측 성능을 보이고 있다.
- 기반 알고리즘은 결정트리, 결정트리의 쉽고 직관적인 장점을 그대로 가지고 있음.
랜덤 포레스트는 여러 개의 결정 트리 분류기가 전체 데이터에서 배깅 방식으로 각자의 데이터를 샘플링 해 개별적으로 학습을 수행한 뒤 최종적으로 모든 분류기가 보팅을 통해 예측 결정을 하게된다.
랜덤 포레스트는 개별적인 분류기의 기반 알고리즘은 결정 트리이지만 개별 트리가 학습하는데이터 세트는 전체 데이터에서 일부가 중첩되게 샘플링된 데이터 세트이다. 이렇게 여러 개의 데이터 세트를 중첩되게 분리하는 것을 부트스트래핑 분할 방식이라고 한다.
원본 데이터의 건수가 10개인 학습 데이터 세트에 랜덤 포레스트를 3개의 결정 트리 기반으로 학습하려고 n_estimators=3으로 하이퍼 파라미터를 부여하면, 다음과 같이 데이터 서브 세트가 만들어진다.
이렇게 데이터가 중첩된 개별 데이터 세트에 결정 트리 분류기를 각각 적용하는 것이 랜덤 포레스트
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score import pandas as pd import numpy as np import warnings warnings.filterwarnings('ignore') #결정트리에서 사용한 get_human_dataset()을 이용해 학습.테스트용 데이터프레임 반환 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
랜덤 포레스트는 사용자 행동 인식 데이터 세트에 약 92.53%의 정확도를 보여줌.
랜덤 포레스트 하이퍼 파라미터 및 튜닝
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("최적 하이퍼 파라미터: ",grid_cv.best_params_) print("최고 예측 정확도 : ",grid_cv.best_score_)
최적 하이퍼 파라미터: {'max_depth': 10, 'min_samples_leaf': 8, 'min_samples_split': 8, 'n_estimators': 100} 최고 예측 정확도 : 0.9179815016322089
별도의 테스트 데이터 세트에서 예측 성능 확인
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
별도의 테스트 데이터 세트에서 수행한 예측 정확도 수치는 약 91.65%. feature_importances_속성을 이용해 피처의 중요도
import seaborn as sns import matplotlib.pyplot as plt %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 top20") sns.barplot(x=ftr_top20,y=ftr_top20.index) plt.show()
5. GBM(Gradient Boosting Machine)
부스팅 알고리즘은 여러 개의 약한 학습기를 순차적으로 학습-예측 하면서 잘못 예측한 데이터에 가중치 부여를 통해 오류를 개선해 나가면서 학습하는 방식이다. 부스팅의 대표적인 구현은 AdaBoost와 그래디언트 부스트가 있다. 에이다 부스트는 오류 데이터에 가중치를 부여하면서 부스팅을 수행하는 대표적인 알고리즘이다.
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 하이퍼 파라미터 및 튜닝
n_estimators,max_depth,max_features와 같은 트리 기반 자체의 파라미터는 결정 트리, 랜덤 포레스트에서 이미 많이 소개했으므로 생략.
- loss : 경사 하강법에서 사용할 비용함수를 지정. 특별한 이유가 없으면 기본값인 deviance를 그대로 적용한다.
- learning_rate : GBM이 학습을 진행할 떄마다 적용하는 학습률. 약한 학습기가 순차적으로 오류값을 보정해 나가는데 적용하는 계수. 0~1사이의 값을 지정할 수 있으며 기본값은 0.1이다. 너무 작은 값을 적용하면 업데이트 되는 값이 작아져 최소 오류 값을 찾아 예측 성능이 높아질 가능성이 있다. 하지만 많은 약한 학습기는 순차적인 반복이 필요해 수행시간이 오래 걸리고 또 너무 작게 설정하면 모든 약한 학습기의 반복이 완료 돼도 최소 오류값을 찾지 못할 수 있다 반대로 크 값을 적용하면 최소 오류 값을 차지 못하고 그냥 지나쳐 버려 예측 성능이 떨어질 가능성이 높아지지만. 빠른 수행이 가능. 이런 특성 떄문에 learning_rate는 상호 보완적으로 조합해 사용한다. learning_rate를 작게 하고 n_estimators를 크게하면 더 이상 성능이 좋아지지 않는 한계점까지는 예측 성능이 조금씩 좋아질 수 있다. 하지만 시간이 너무 오래 걸림.
- n_estimators : weak learner의 개수. weak_learner가 순차적으로 오류를 보정하므로 개수가 많을 수록 예측 성능이 일정 수준까지는 좋아질 수 있다. 하지만 개수가 많을 수록 수행시간 오래걸림. 기본값은 100.
- subsample : 약한 학습기가 학습에 사용하는 데이터 샘플링의 비율. 기본 값은 1이고 이는 전체 학습 데이터를 기반으로 학습한다는 의미. 과적합이 염려되는 경우 subsample을 1보다 작은 값으로 설정.
GridSearchCV를 이용해 하이퍼 파라미터를 최적화해보겠다. 간략하게 n_estimators를 100,500으로, learning_rate를 0.05,0.1로만 제약하겠다. 그리고 교차 검증 세트고 2개로만 설정해 GridSearchCV를 적용.
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_))
Fitting 2 folds for each of 4 candidates, totalling 8 fits [Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers. [Parallel(n_jobs=1)]: Done 8 out of 8 | elapsed: 81.3min finished 최적 하이퍼 파라미터 : {'learning_rate': 0.05, 'n_estimators': 500} 최고 예측 정확도 :0.9013
그리고 최적화된 파라미터로 테스트 데이터 세트에 적용해 예측 정확도 확인.
#gridsearchcv를 이용해 최적으로 학습된 estimator로 학습 수행 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.9396
6. XGBoost(eXtra Gradient Boost)
- 뛰어난 예측 성능 : 일반적으로 분류와 회귀 영역에서 뛰어난 예측 성능을 발휘한다.
- GBM 대비 빠른 수행 시간 : 일반적인 GBM에 비해 수행 시간이 빠르다는 것이지 다른 머신러닝 알고리즘에 비해 빠르다는 의미는 아님.
- 과적합 규제 : 표준 GBM의 경우 과적합 구제 기능이 없으나 XGBoost는 자체에 과적합 규제 기능으로 과적합에 좀더 강한 내구성을 가짐
- Tree pruning : 다른 GBM과 마찬가지로 XGBoost도 max_depth 파라미터로 분할 깊이를 조정하기도 하지만 tree pruning으로 더 이상 긍정 이득이 없는 분할을 가지치기 해서 분할 수를 더 줄이는 추가적인 장점을 가지고 있음.
- 자체 내장된 교차 검증 : XGBoost 반복 수행 시 마다 내부적으로 학습 데이터 세트와 평가 데이터 세트에 대한 교차검증을 수행해 최적화된 반복 수행 횟수를 가질 수 있다. 지정된 반복횟수가 아니라 교차검증을 통해 평가 데이터 세트의 평가값이 최적화 되면 반복을 증간에 멈출수 있는 조기 중단 기능이 있다.
사이킷런 래퍼 XGBoost의 개요 및 적용
XGBoost 개발 그룹은 사이킷런의 프레임워크와 연동하기 위해 사이킷런 전용의 XGBoost 래퍼 클래스를 개발했다. 사이킷런 기본 Estimator를 그대로 상속해 만들었기 떄문에 다른 Estimator와 동일하게 fit()과 predict()만으로 학습과 예측이 가능. GridSearchCV,Pipeline 등 사이킷런의 다른 유틸리티를 그대로 사용할 수 있다.
- 분류를 위한 래퍼 클래스 XGBClassifier
- 회귀를 위한 래퍼 클래스 XGBRegressor
파이썬 래퍼 XGBoost와 사이킷런 래퍼 XGBoost의 하이퍼파라미터에 약간 차이가 있다.
- eta → learning_rate
- sub_sample → subsample
- lambda → reg_lambda
- alpha → reg_alpha
또한 xgboost의 n_estimator와 num_boost_round 하이퍼 파라미터는 서로 동일한 파라미터이다. 만일 두개가 동시에 사용되며 파이썬 래퍼 XGBoost에서는 n_estimators 파라미터를 무시한다. 하지만 XGBoostClassifier와 같은 사이킷런 래퍼 XGBoost 클래스에서는 n_estimators 파라미터를 적용한다.
- 위스콘신 유방암 데이터 세트 실습파이썬 래퍼 XGBoost와 동일하게 n_estimators(num_rounds 대응)은 400, learning_rate(eta 대응)는 0.1, max_depth=3으로 설정.
get_clf_eval(y_test,w_preds,w_preds_proba)
결과는 앞의 파이썬 래퍼 XGBoost랑 동일하게 나온다.오차행렬 [[35 2] [ 1 76]] 정확도: 0.9737, 정밀도: 0.9744, 재현율: 0.9870, F1: 0.9806, AUC:0.9665
from xgboost import XGBClassifier xgb_wrapper=XGBClassifier(n_estimators=400,learning_rate=0.1,max_depth=3) evals=[(X_test,y_test)] xgb_wrapper.fit(X_train,y_train,early_stopping_rounds=100,eval_metric="logloss", eval_set=evals,verbose=True) ws100_preds=xgb_wrapper.predict(X_test) ws100_pred_proba=xgb_wrapper.predict_proba(X_test)[:,1]
[308] validation_0-logloss:0.085999 [309] validation_0-logloss:0.085877 [310] validation_0-logloss:0.085923 [311] validation_0-logloss:0.085948 Stopping. Best iteration: [211] validation_0-logloss:0.085593
- n_estimators를 400으로 설정해도 400번 반복을 수행하지 않고 311번 반복한 후 학습을 완료했음을 알수 있다. 311번에서 멈춘 이유는 211번 반복시 logloss가 0.085593이고 311반복 시 logloss가 0.085948인데 211번에서 311번까지 early_stopping_rounds=100으로 지정된 100번의 반복동안 성능평가지수가 향상되지 않았기 때문이다.
get_clf_eval(y_test,ws100_preds,ws100_pred_proba)
오차행렬 [[34 3] [ 1 76]] 정확도: 0.9649, 정밀도: 0.9620, 재현율: 0.9870, F1: 0.9744, AUC:0.9530
[60] validation_0-logloss:0.091939 [61] validation_0-logloss:0.091461 [62] validation_0-logloss:0.090311 Stopping. Best iteration: [52] validation_0-logloss:0.089577 오차행렬 [[34 3] [ 2 75]] 정확도: 0.9561, 정밀도: 0.9615, 재현율: 0.9740, F1: 0.9677, AUC:0.9465
from xgboost import plot_importance import matplotlib.pyplot as plt %matplotlib inline fig,ax=plt.subplots(figsize=(10,12)) #사이킷런 Wrapper 클래스를 입력해도 무방 plot_importance(xgb_wrapper,ax=ax)
7. LightGBM
- 더 빠른 학습과 예측 수행 시간
- 더 작은 메모리 사용량
- 카테고리형 피처의 자동 변환과 최적 분할(원-핫 인코딩을 사용하지 않고도 카테고리형 피처를 최적으로 변환하고 이에 따른 노드 분할 수행)
3회차 회고록 (2022.07.25)
오늘은 랜덤 포레스트부터 신탄데르 고객 만족 예측 데이터 캐글 분석까지 진행하였다. 머신러닝을 배우는 것에 있어 생각보다 많은 대수학적 지식이 필요하다는 것을 알 수 있었다. 머신러닝을 하기 위해 필요한 사이킷런 모듈이나 알고리즘 종류를 배우면서 각각의 장단점과 성능을 비교할 수 있어서 값진 시간이었다. 모각코가 끝나고 나면 개인적인 데이터 분석도 진행하고자 한다.
'[CNU] Mogakco' 카테고리의 다른 글
[2022_하계_모각코] 6회차(08/15) (0) 2022.08.19 [2022_하계_모각코] 5회차(08/09) (0) 2022.08.19 [2022_하계_모각코] 2회차(07/11) (1) 2022.07.11 [2022_하계_모각코] 1회차 (07/04) (0) 2022.07.04 [2022_하계_모각코] 목표 및 활동계획 (0) 2022.06.24