贝叶斯优化应用于 CatBoost
Bayesian Optimisation applied in CatBoost
这是我在 CatBoost 中应用贝叶斯搜索的尝试:
from catboost import CatBoostClassifier
from skopt import BayesSearchCV
from sklearn.model_selection import StratifiedKFold
# Classifier
bayes_cv_tuner = BayesSearchCV(
estimator = CatBoostClassifier(
silent=True
),
search_spaces = {
'depth':(2,16),
'l2_leaf_reg':(1, 500),
'bagging_temperature':(1e-9, 1000, 'log-uniform'),
'border_count':(1,255),
'rsm':(0.01, 1.0, 'uniform'),
'random_strength':(1e-9, 10, 'log-uniform'),
'scale_pos_weight':(0.01, 1.0, 'uniform'),
},
scoring = 'roc_auc',
cv = StratifiedKFold(
n_splits=2,
shuffle=True,
random_state=72
),
n_jobs = 1,
n_iter = 100,
verbose = 1,
refit = True,
random_state = 72
)
跟踪结果:
def status_print(optim_result):
"""Status callback durring bayesian hyperparameter search"""
# Get all the models tested so far in DataFrame format
all_models = pd.DataFrame(bayes_cv_tuner.cv_results_)
# Get current parameters and the best parameters
best_params = pd.Series(bayes_cv_tuner.best_params_)
print('Model #{}\nBest ROC-AUC: {}\nBest params: {}\n'.format(
len(all_models),
np.round(bayes_cv_tuner.best_score_, 4),
bayes_cv_tuner.best_params_
))
拟合贝叶斯CV
resultCAT = bayes_cv_tuner.fit(X_train, y_train, callback=status_print)
结果
前 3 次迭代工作正常,但随后我得到一个不间断的字符串:
Iteration with suspicious time 7.55 sec ignored in overall statistics.
Iteration with suspicious time 739 sec ignored in overall statistics.
(...)
关于我去哪里的任何想法wrong/How我可以改进它吗?
敬礼,
根据 CatBoost 迄今为止记录的时间,skopt 正在安排的一组实验中的一个迭代实际上花费了太长时间才能完成。
如果您通过设置分类器的冗长程度来探索这种情况何时发生,并使用回调来探索 skopt 正在探索的参数组合,您可能会发现罪魁祸首很可能是深度参数:Skopt 会减慢速度当 CatBoost 试图测试更深的树时。
您也可以尝试使用此自定义回调进行调试:
counter = 0
def onstep(res):
global counter
args = res.x
x0 = res.x_iters
y0 = res.func_vals
print('Last eval: ', x0[-1],
' - Score ', y0[-1])
print('Current iter: ', counter,
' - Score ', res.fun,
' - Args: ', args)
joblib.dump((x0, y0), 'checkpoint.pkl')
counter = counter+1
您可以通过以下方式调用它:
resultCAT = bayes_cv_tuner.fit(X_train, y_train, callback=[onstep, status_print])
实际上,我在实验中注意到了与您相同的问题,随着深度的增加,复杂度以非线性方式增加,因此 CatBoost 需要更长的时间来完成其迭代。一个简单的解决方案是尝试搜索更简单的 space:
'depth':(2, 8)
通常深度8就够了,反正你可以先运行 skopt最大深度等于8,然后通过增加最大值重新迭代。
这是我在 CatBoost 中应用贝叶斯搜索的尝试:
from catboost import CatBoostClassifier
from skopt import BayesSearchCV
from sklearn.model_selection import StratifiedKFold
# Classifier
bayes_cv_tuner = BayesSearchCV(
estimator = CatBoostClassifier(
silent=True
),
search_spaces = {
'depth':(2,16),
'l2_leaf_reg':(1, 500),
'bagging_temperature':(1e-9, 1000, 'log-uniform'),
'border_count':(1,255),
'rsm':(0.01, 1.0, 'uniform'),
'random_strength':(1e-9, 10, 'log-uniform'),
'scale_pos_weight':(0.01, 1.0, 'uniform'),
},
scoring = 'roc_auc',
cv = StratifiedKFold(
n_splits=2,
shuffle=True,
random_state=72
),
n_jobs = 1,
n_iter = 100,
verbose = 1,
refit = True,
random_state = 72
)
跟踪结果:
def status_print(optim_result):
"""Status callback durring bayesian hyperparameter search"""
# Get all the models tested so far in DataFrame format
all_models = pd.DataFrame(bayes_cv_tuner.cv_results_)
# Get current parameters and the best parameters
best_params = pd.Series(bayes_cv_tuner.best_params_)
print('Model #{}\nBest ROC-AUC: {}\nBest params: {}\n'.format(
len(all_models),
np.round(bayes_cv_tuner.best_score_, 4),
bayes_cv_tuner.best_params_
))
拟合贝叶斯CV
resultCAT = bayes_cv_tuner.fit(X_train, y_train, callback=status_print)
结果
前 3 次迭代工作正常,但随后我得到一个不间断的字符串:
Iteration with suspicious time 7.55 sec ignored in overall statistics.
Iteration with suspicious time 739 sec ignored in overall statistics.
(...)
关于我去哪里的任何想法wrong/How我可以改进它吗?
敬礼,
根据 CatBoost 迄今为止记录的时间,skopt 正在安排的一组实验中的一个迭代实际上花费了太长时间才能完成。
如果您通过设置分类器的冗长程度来探索这种情况何时发生,并使用回调来探索 skopt 正在探索的参数组合,您可能会发现罪魁祸首很可能是深度参数:Skopt 会减慢速度当 CatBoost 试图测试更深的树时。
您也可以尝试使用此自定义回调进行调试:
counter = 0
def onstep(res):
global counter
args = res.x
x0 = res.x_iters
y0 = res.func_vals
print('Last eval: ', x0[-1],
' - Score ', y0[-1])
print('Current iter: ', counter,
' - Score ', res.fun,
' - Args: ', args)
joblib.dump((x0, y0), 'checkpoint.pkl')
counter = counter+1
您可以通过以下方式调用它:
resultCAT = bayes_cv_tuner.fit(X_train, y_train, callback=[onstep, status_print])
实际上,我在实验中注意到了与您相同的问题,随着深度的增加,复杂度以非线性方式增加,因此 CatBoost 需要更长的时间来完成其迭代。一个简单的解决方案是尝试搜索更简单的 space:
'depth':(2, 8)
通常深度8就够了,反正你可以先运行 skopt最大深度等于8,然后通过增加最大值重新迭代。