일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 체크인미팅
- EC2
- 개발공부
- 스프링부트
- 인프라
- Developer
- AWS
- 라피신
- 위키북스
- 티스토리챌린지
- 온라인테스트
- 자바개발자
- 게임개발동아리
- 42서울
- UNIDEV
- 백엔드
- CICD
- 프리티어
- 백엔드개발자
- UNICON
- 생활코딩
- 전국대학생게임개발동아리연합회
- 배포
- RDS
- 프로그래밍
- UNICON2023
- 인디게임
- 오블완
- 도커
- 스프링
- Today
- Total
Hyun's Wonderwall
[AIchemist] 파머완 - CH04. 분류 | 09. 캐글 산탄데르 고객 만족 예측 본문
[AIchemist] 파머완 - CH04. 분류 | 09. 캐글 산탄데르 고객 만족 예측
Hyun_! 2023. 10. 31. 05:5509. 산탄데르 고객 만족 예측
- XGBoost와 LightGBM을 활용해 예측해 보자.
- train.csv 는 370개의 피처로 주어진 데이터 세트. (피처 이름은 모두 익명 처리)
- 클래스 레이블 명은 TARGET. 이 값이 1이면 불만을 가진 고객, 0이면 만족한 고객
- ROC-AUC(ROC 곡선 영역)으로 모델의 성능을 평가함
(갑자기 아나콘다가 안 열려서 Jupyter Notebook (anaconda3) 을 실행시켰더니 잘 되었다(?))
- 캐글에서 train.csv 다운로드 https://www.kaggle.com/c/santander-customer-satisfaction
데이터 전처리
- 사이킷런 래퍼 XGBoost를 이용할 것임
# 필요한 모듈 로딩, 학습 데이터를 DataFrame으로 로딩
➔ 클래스 값 칼럼을 포함한 피처가 371개 존재.
# 피처의 타입과 Null 값 알아보기
➔ 111개의 피처가 float, 260개의 피처가 int.(모든 피처의 데이터 타입이 숫자형) Null 값은 없음.
# 전체 데이터에서 만족과 불만족 비율 살펴보기
- 레이블인 Target 속성 값의 분포를 알아보면 된다.
➔ 대부분이 만족, 불만족인 고객은 4%에 불과함.
# DataFrame의 describe() 메서드로 각 피처의 값 분포 확인
➔ var3칼럼의 min값이 -999999: NaN이나 특정 예외 값을 이로 변환했을 것임. print(cust_df.var3.value_counts()[:10])으로 var3의 값 조사해보면 이 값이 116개...
# 너무 편차가 심하므로, 가장 값이 많은 2로 변환함
# ID피처는 단순 식별자에 불과하므로 식별자를 드롭
# 클래스 데이터 세트와 피처 데이터 세트를 분리해 별도의 데이터 세트로 별도 저장
# 원본 데이터 세트에서 학습 데이터 세트와 테스트 데이터 세트 분리
- 원본이 비대칭적인 데이터 세트이므로 TARGET 값 분포도가 학습 데이터 세트와 테스트 데이터 세트에 모두 비슷하게 추출됐는지 확인함
- 학습(X_)과 성능 평가(y_) 진행할 것임
➔ TARGET 값 분포 원본 데이터와 유사하게 전체 4% 정도로 만들어짐
# XGBoost의 조기 중단(기능)의 검증 데이터 세트로 사용할 것임
- X_train, y_train을 쪼개어 학습과 검증 데이터 세트로 만듬
XGBoost 학습 모델과 하이퍼 파라미터 튜닝
XGBoost 학습모델 생성하고 예측 결과를 ROC-AUC로 평가해보자
# 사이킷런 래퍼 XGBClassifier를 기반으로 학습 수행
- (파라미터) n_estimators: 500, early_stopping_rounds: 100, eval_metric: auc, eval_set=[(X_tr, y_tr), (X_val, y_val)], 조기 중단은 100회로 설정
# HyperOpt 이용해 베이지안 최적화 기반으로 XGBoost의 하이퍼 파라미터 튜닝 수행
- max_depth, min_child_weight, colsample_bytree, learning_rate 조정해 하이퍼 파라미터 검색 공간 설정
# 목적 함수 만들기
- 3 Fold 교차 검증. 평균 ROC-AUC 값 반환하되 -1 곱해 최대 ROC-AUC 값이 최소 반환값이 되도록 함
- KFold 클래스를 이용해 학습과 검증 데이터 세트 추출, 교차 검증 횟수만큼 학습과 성능 평가 진행
(*수행 시간 줄이기 위해 임시로 estimators 100으로 줄이고, early_stopping_rounds도 30으로 줄여서 테스트. 하이퍼 파라미터 튜닝 완료 후 증가시킬 것)
# 최적의 하이퍼 파라미터 도출하기
- fmin() 함수 호출해 max_eval=50회만큼 반복
➔ 50회만큼 교차 검증 반복하여 학습과 평가 (약 10분 소요)
colsamplbe_bytree: 약 0.5749, learning_rate: 약 0.1514, max_depth: 5.0, min_child_rate: 6.0 도출됨
# 이렇게 도출된 최적 하이퍼 파라미터를 기반으로 XGBClassifier를 재학습시키고 테스트 데이트 세트에서 ROC-AUC를 측정하기
n_estimators 500으로 증가시킴
# n_estimators를 500증가 후 최적으로 찾은 하이퍼 파라미터를 기반으로 학습과 예측 수행.
xgb_clf = XGBClassifier(n_estimators=500, learning_rate=round(best['learning_rate'], 5),
max_depth=int(best['max_depth']),
min_child_weight=int(best['min_child_weight']),
colsample_bytree=round(best['colsample_bytree'], 5)
)
# evaluation metric을 auc로, early stopping은 100으로 설정하고 학습 수행.
xgb_clf.fit(X_tr, y_tr, early_stopping_rounds=100,
eval_metric="auc", eval_set=[(X_tr, y_tr), (X_val, y_val)])
xgb_roc_score = roc_auc_score(y_test, xgb_clf.predict_proba(X_test)[:,1])
print('ROC AUC: {0:.4f}'.format(xgb_roc_score))
ROC AUC: 0.8457
➔ 개선되었다!
# 튜닝된 모델에서 각 피처의 중요도를 피처 중요도 그래프로 확인하기
from xgboost import plot_importance
import matplotlib.pyplot as plt
%matplotlib inline
fig, ax = plt.subplots(1,1,figsize=(10,8))
plot_importance(xgb_clf, ax=ax , max_num_features=20,height=0.4)
➔ XGBoost의 예측 성능을 좌우하는 가장 중요한 피처는 var38, var15순임.
LightGBM 모델 학습과 하이퍼 파라미터 튜닝
LightGBM으로 학습을 수행하고 ROC-AUC를 측정해 보자.
- (파라미터) n_estimators: 500, early_stopping_rounds: 100, eval_metric: auc, eval_set=[(X_tr, y_tr), (X_val, y_val)]
➔ 걸리는 시간 단축, 성능 조금 낮다..?
# HyperOpt 이용해 다양한 하이퍼 파라미터 튜닝 수행하기
- 튜닝 대상: num_leaves, max_depth, min_child_smaples, subsmaple, learning_rate, 이를 위한 하이퍼 파라미터 검색 공간 설정
lgbm_search_space = {'num_leaves': hp.quniform('num_leaves', 32, 64, 1),
'max_depth': hp.quniform('max_depth', 100, 160, 1),
'min_child_samples': hp.quniform('min_child_samples', 60, 100, 1),
'subsample': hp.uniform('subsample', 0.7, 1),
'learning_rate': hp.uniform('learning_rate', 0.01, 0.2)
}
#목적 함수 생성
- 앞 코드와 LGBMClassifier 객체 생성 부분만 차이
def objective_func(search_space):
lgbm_clf = LGBMClassifier(n_estimators=100, num_leaves=int(search_space['num_leaves']),
max_depth=int(search_space['max_depth']),
min_child_samples=int(search_space['min_child_samples']),
subsample=search_space['subsample'],
learning_rate=search_space['learning_rate'])
# 3개 k-fold 방식으로 평가된 roc_auc 지표를 담는 list
roc_auc_list = []
# 3개 k-fold방식 적용
kf = KFold(n_splits=3)
# X_train을 다시 학습과 검증용 데이터로 분리
for tr_index, val_index in kf.split(X_train):
# kf.split(X_train)으로 추출된 학습과 검증 index값으로 학습과 검증 데이터 세트 분리
X_tr, y_tr = X_train.iloc[tr_index], y_train.iloc[tr_index]
X_val, y_val = X_train.iloc[val_index], y_train.iloc[val_index]
# early stopping은 30회로 설정하고 추출된 학습과 검증 데이터로 XGBClassifier 학습 수행.
lgbm_clf.fit(X_tr, y_tr, early_stopping_rounds=30, eval_metric="auc",
eval_set=[(X_tr, y_tr), (X_val, y_val)])
# 1로 예측한 확률값 추출후 roc auc 계산하고 평균 roc auc 계산을 위해 list에 결과값 담음.
score = roc_auc_score(y_val, lgbm_clf.predict_proba(X_val)[:, 1])
roc_auc_list.append(score)
# 3개 k-fold로 계산된 roc_auc값의 평균값을 반환하되,
# HyperOpt는 목적함수의 최소값을 위한 입력값을 찾으므로 -1을 곱한 뒤 반환.
return -1*np.mean(roc_auc_list)
# fmin 호출해 최적의 파라미터 도출
from hyperopt import fmin, tpe, Trials
trials = Trials()
# fmin()함수를 호출. max_evals지정된 횟수만큼 반복 후 목적함수의 최소값을 가지는 최적 입력값 추출.
best = fmin(fn=objective_func, space=lgbm_search_space, algo=tpe.suggest,
max_evals=50, # 최대 반복 횟수를 지정합니다.
trials=trials, rstate=np.random.default_rng(seed=30))
print('best:', best)
➔ learning_rate가 약 0.08592, max_depth가 121.0, min_child_samples가 69.0, num_leaves가 41.0, subsample이 0.91489로 도출됨.
# 이들 하이퍼 파라미터 이용해 LightGBM 학습후 데이터 세트에서 ROC-AUC 평가해보기
lgbm_clf = LGBMClassifier(n_estimators=500, num_leaves=int(best['num_leaves']),
max_depth=int(best['max_depth']),
min_child_samples=int(best['min_child_samples']),
subsample=round(best['subsample'], 5),
learning_rate=round(best['learning_rate'], 5)
)
# evaluation metric을 auc로, early stopping은 100으로 설정하고 학습 수행.
lgbm_clf.fit(X_tr, y_tr, early_stopping_rounds=100,
eval_metric="auc", eval_set=[(X_tr, y_tr), (X_val, y_val)])
lgbm_roc_score = roc_auc_score(y_test, lgbm_clf.predict_proba(X_test)[:,1])
print('ROC AUC: {0:.4f}'.format(lgbm_roc_score))
ROC AUC: 0.8446
➔ 개선되었다! LightGBM은 학습 시간이 상대적으로 빠른 장점. 추가적인 하이퍼 파라미터를 적용해 수행해 보는 것도 좋다.
'Study > Python-Machine-Learning' 카테고리의 다른 글
[AIchemist] 파머완 - CH05. 회귀 | 1~8 (0) | 2023.11.07 |
---|---|
[AIchemist] 파머완 - CH04. 분류 | 10. 캐글 신용카드 사기 검출 (0) | 2023.10.31 |
[AIchemist] 파머완 - CH04. 분류 (5~8, 11) (1) | 2023.10.10 |
[AIchemist] 파머완 - CH03. 평가 (6. 피마 인디언 당뇨병 예측) (0) | 2023.10.09 |
[AIchemist] 파머완 - CH03. 평가 (1~5) (0) | 2023.09.26 |