<머신러닝 • 딥러닝 문제해결 전략> 8장의 내용을 실습했습니다.
전체 프로세스는 앞절과 동일하게, 모델만 XGBoost로 바꿔 2번째 성능개선 모델을 만들어보도록 하겠습니다.
1. 피처엔지니어링
피처엔지니어링까지의 코드는 앞절과 거의 동일하기 때문에 블로그에서는 내용을 생략하도록 하겠습니다.
lightgbm용 gini()함수를 XGBoost용 gini()함수로 바꾸는 것외에는 앞절과 내용이 동일합니다.
# 피처엔지니어링까지의 코드는 앞절과 거의 같으나 gini()함수만 다름.
# XGBoost용 지니함수 계산함수는 반환값이 2개(평가지표명, 평가점수)
# XGBoost용 gini() 함수
def gini(preds, dtrain):
labels = dtrain.get_label()
return 'gini', eval_gini(labels, preds)
2. 하이퍼파라미터 최적화
데이터셋 준비
import xgboost as xgb
from sklearn.model_selection import train_test_split
# 8:2 비율로 훈련 데이터, 검증 데이터 분리 (베이지안 최적화 수행용)
X_train, X_valid, y_train, y_valid = train_test_split(X, y,
test_size=0.2,
random_state=0)
# 베이지안 최적화용 데이터셋
bayes_dtrain = xgb.DMatrix(X_train, y_train)
bayes_dvalid = xgb.DMatrix(X_valid, y_valid)
하이퍼파라미터 범위 설정
# 베이지안 최적화를 위한 하이퍼파라미터 범위
param_bounds = {'max_depth': (4, 8),
'subsample': (0.6, 0.9),
'colsample_bytree': (0.7, 1.0),
'min_child_weight': (5, 7),
'gamma': (8, 11),
'reg_alpha': (7, 9),
'reg_lambda': (1.1, 1.5),
'scale_pos_weight': (1.4, 1.6)}
# 값이 고정된 하이퍼파라미터
fixed_params = {'objective': 'binary:logistic',
'learning_rate': 0.02,
'random_state': 1991}
베이지안 최적화용 평가지표 계산함수 작성
def eval_function(max_depth, subsample, colsample_bytree, min_child_weight,
reg_alpha, gamma, reg_lambda, scale_pos_weight):
'''최적화하려는 평가지표(지니계수) 계산 함수'''
# 베이지안 최적화를 수행할 하이퍼파라미터 # 1
params = {'max_depth': int(round(max_depth)),
'subsample': subsample,
'colsample_bytree': colsample_bytree,
'min_child_weight': min_child_weight,
'gamma': gamma,
'reg_alpha':reg_alpha,
'reg_lambda': reg_lambda,
'scale_pos_weight': scale_pos_weight}
# 값이 고정된 하이퍼파라미터도 추가
params.update(fixed_params)
print('하이퍼파라미터 :', params)
# XGBoost 모델 훈련 # 2
xgb_model = xgb.train(params=params,
dtrain=bayes_dtrain,
num_boost_round=2000,
evals=[(bayes_dvalid, 'bayes_dvalid')], # 3
maximize=True, # 4
feval=gini,
early_stopping_rounds=200,
verbose_eval=False)
best_iter = xgb_model.best_iteration # 최적 반복 횟수 # 5
# 검증 데이터로 예측 수행 # 6
preds = xgb_model.predict(bayes_dvalid, # 7
iteration_range=(0, best_iter)) # 8
# 지니계수 계산
gini_score = eval_gini(y_valid, preds)
print(f'지니계수 : {gini_score}\n')
return gini_score
# 1, 2, 6: 기본적으로 모델이 달라 하이퍼파라미터 명도 다름
# 5: XGBoost는 성능이 가장 좋을 때의 부스팅 반복횟수를 # 8 예측시 iteration_range 파라미터로 명시해줘야한다.
# 3: 검증 데이터와 검증 데이터 이름의 쌍을 투플로 묶어서 evals=[( , )] 형태로 전달
# 4: 평가점수가 클수록 좋다.
# 6: XGBoost의 predict()에는 데이터를 DMatrix타입으로 전달해야함. 그래서 X_valid가 아닌 bayes_dvalid를 전달함.
최적화 수행
from bayes_opt import BayesianOptimization
# 베이지안 최적화 객체 생성
optimizer = BayesianOptimization(f=eval_function,
pbounds=param_bounds,
random_state=0)
# 베이지안 최적화 수행
optimizer.maximize(init_points=3, n_iter=6)
결과 확인
# 평가함수 점수가 최대일 때 하이퍼파라미터
max_params = optimizer.max['params']
max_params
max_depth는 트리깊이를 의미하는 하이퍼파라미터. 정수형이어야 한다.
# 정수형 하이퍼파라미터 변환
max_params['max_depth'] = int(round(max_params['max_depth']))
# 값이 고정된 하이퍼파라미터 추가
max_params.update(fixed_params)
max_params
from sklearn.model_selection import StratifiedKFold
# 층화 K 폴드 교차 검증기 생성
folds = StratifiedKFold(n_splits=5, shuffle=True, random_state=1991)
# OOF 방식으로 훈련된 모델로 검증 데이터 타깃값을 예측한 확률을 담을 1차원 배열
oof_val_preds = np.zeros(X.shape[0])
# OOF 방식으로 훈련된 모델로 테스트 데이터 타깃값을 예측한 확률을 담을 1차원 배열
oof_test_preds = np.zeros(X_test.shape[0])
# OOF 방식으로 모델 훈련, 검증, 예측
for idx, (train_idx, valid_idx) in enumerate(folds.split(X, y)):
# 각 폴드를 구분하는 문구 출력
print('#'*40, f'폴드 {idx+1} / 폴드 {folds.n_splits}', '#'*40)
# 훈련용 데이터, 검증용 데이터 설정
X_train, y_train = X[train_idx], y[train_idx]
X_valid, y_valid = X[valid_idx], y[valid_idx]
# XGBoost 전용 데이터셋 생성
dtrain = xgb.DMatrix(X_train, y_train)
dvalid = xgb.DMatrix(X_valid, y_valid)
dtest = xgb.DMatrix(X_test)
# XGBoost 모델 훈련
xgb_model = xgb.train(params=max_params,
dtrain=dtrain,
num_boost_round=2000,
evals=[(dvalid, 'valid')],
maximize=True,
feval=gini,
early_stopping_rounds=200,
verbose_eval=100)
# 모델 성능이 가장 좋을 때의 부스팅 반복 횟수 저장
best_iter = xgb_model.best_iteration
# 테스트 데이터를 활용해 OOF 예측
oof_test_preds += xgb_model.predict(dtest,
iteration_range=(0, best_iter))/folds.n_splits
# 모델 성능 평가를 위한 검증 데이터 타깃값 예측
oof_val_preds[valid_idx] += xgb_model.predict(dvalid,
iteration_range=(0, best_iter))
# 검증 데이터 예측 확률에 대한 정규화 지니계수
gini_score = eval_gini(y_valid, oof_val_preds[valid_idx])
print(f'폴드 {idx+1} 지니계수 : {gini_score}\n')
print('OOF 검증 데이터 지니계수 :', eval_gini(y, oof_val_preds))
submission['target'] = oof_test_preds
submission.to_csv('submission.csv')
'Data > MLDL' 카테고리의 다른 글
병든 잎사귀 식별 경진대회 (0) | 2023.02.06 |
---|---|
향후 판매량 예측 경진대회 (0) | 2022.11.21 |
안전 운전자 예측 경진대회: 성능개선1(lightGBM 모델) (0) | 2022.11.14 |
안전 운전자 예측 경진대회: 베이스라인 모델 (0) | 2022.11.14 |
범주형 경진대회 이진분류 (0) | 2022.10.31 |