我有以下目标函数在Optuna超参数优化中运行:
def objective(trial, data=data):
num_train_pool = data["num_train_pool"]
num_test_pool = data["num_test_pool"]
true_labels_test = data["true_labels_test"]
params = {'objective': 'MultiClass',
'task_type': 'GPU',
'logging_level': 'Verbose',
'bootstrap_type': 'Bayesian',
'learning_rate': trial.suggest_loguniform('learning_rate', 1e-4, 1),
'depth': trial.suggest_int('depth', 3, 12),
'l2_leaf_reg': trial.suggest_loguniform('l2_leaf_reg', 1e-2, 1),
'border_count': trial.suggest_int('border_count', 32, 255)
}
def custom_precision(y_true, y_pred):
true_positives = ((y_true[:, 0] == -1) & (y_pred[:, 0] == -1)).sum() + ((y_true[:, 1] == 1) & (y_pred[:, 1] == 1)).sum()
false_positives = ((y_true[:, 0] != -1) & (y_pred[:, 0] == -1)).sum() + ((y_true[:, 1] != 1) & (y_pred[:, 1] == 1)).sum()
return true_positives / (true_positives + false_positives + 1e-8)
model = catboost.CatBoostClassifier(**params, custom_metric='Precision:custom_precision', random_seed=65)
model.fit(num_train_pool,
verbose=0,
eval_set=num_test_pool,
early_stopping_rounds=5)
preds = model.predict(num_test_pool)
pred_labels = np.rint(preds)
score = custom_precision(true_labels_test, pred_labels)
这是一个不平衡的分类问题,其中我的类权重如下:{-1:12.5,0:0.5,1:10}。我只关心类-1和1获得高的True Positives分数,这就是为什么我写了自定义精度函数。此外,我的训练池有一个weight_vector,因为不是所有的样本都有相同的“质量”。我的池看起来像这样:
num_train_pool = catboost.Pool(data=X_train,
label=y_train,
weight=y_train_weights,
feature_names=X_train.columns.to_list())
运行优化后,我得到了这个:
CatBoostError: catboost/private/libs/options/loss_description.cpp:34: Invalid metric description, it should be in the form "metric_name:param1=value1;...;paramN=valueN"
我认为我正确地遵循了CatBoost指南,但无法找出我的代码中的错误。有任何反馈吗?
1条答案
按热度按时间l7mqbcuq1#
问题在于你如何构造
Catboost
对象。你需要根据错误消息重新格式化你的字符串,我建议在你的params dict中包括你的custom_metric
,以避免任何混乱。尝试将
params
更改为:然后你的Catboost构造函数:
model = catboost.CatBoostClassifier(**params)