【发布时间】:2019-05-11 08:53:54
【问题描述】:
我在 sklearn 中使用带有随机森林分类器的 RandomizedSearchCV 函数。 要查看不同的指标,我正在使用自定义评分
from sklearn.metrics import make_scorer, roc_auc_score, recall_score, matthews_corrcoef, balanced_accuracy_score, accuracy_score
acc = make_scorer(accuracy_score)
auc_score = make_scorer(roc_auc_score)
recall = make_scorer(recall_score)
mcc = make_scorer(matthews_corrcoef)
bal_acc = make_scorer(balanced_accuracy_score)
scoring = {"roc_auc_score": auc_score, "recall": recall, "MCC" : mcc, 'Bal_acc' : bal_acc, "Accuracy": acc }
这些自定义记分器用于随机搜索
rf_random = RandomizedSearchCV(estimator=rf, param_distributions=random_grid, n_iter=100, cv=split, verbose=2,
random_state=42, n_jobs=-1, error_score=np.nan, scoring = scoring, iid = True, refit="roc_auc_score")
现在的问题是,当我使用自定义拆分时,AUC 会抛出异常,因为这个精确拆分只有一个类标签。
我不想更改拆分,因此是否有可能在 RandomizedSearchCV 或 make_scorer 函数中捕获这些异常? 所以例如如果没有计算其中一个指标(由于异常),只需输入 NaN 并继续下一个模型。
编辑: 显然,error_score 不包括模型训练,但不包括度量计算。如果我使用例如 Accuracy 一切正常,我只会在只有一个类标签的折叠处收到警告。如果我使用例如 AUC 作为指标,我仍然会抛出异常。
如果能在这里得到一些想法会很棒!
解决方案: 定义自定义记分器有例外:
def custom_scorer(y_true, y_pred, actual_scorer):
score = np.nan
try:
score = actual_scorer(y_true, y_pred)
except ValueError:
pass
return score
这导致了一个新的指标:
acc = make_scorer(accuracy_score)
recall = make_scorer(custom_scorer, actual_scorer=recall_score)
new_auc = make_scorer(custom_scorer, actual_scorer=roc_auc_score)
mcc = make_scorer(custom_scorer, actual_scorer=matthews_corrcoef)
bal_acc = make_scorer(custom_scorer,actual_scorer=balanced_accuracy_score)
scoring = {"roc_auc_score": new_auc, "recall": recall, "MCC" : mcc, 'Bal_acc' : bal_acc, "Accuracy": acc }
这又可以传递给RandomizedSearchCV的打分参数
我找到的第二个解决方案是:
def custom_auc(clf, X, y_true):
score = np.nan
y_pred = clf.predict_proba(X)
try:
score = roc_auc_score(y_true, y_pred[:, 1])
except Exception:
pass
return score
也可以传递给打分参数:
scoring = {"roc_auc_score": custom_auc, "recall": recall, "MCC" : mcc, 'Bal_acc' : bal_acc, "Accuracy": acc }
(改编自this answer)
【问题讨论】:
-
不完全清楚你想要什么。您正在使用
error_score=np.nan,它将满足您的要求。您还需要什么,还是没有按预期工作? -
我添加了上面的问题。基本上它没有按预期工作,因为即使有 error_score 我也得到了异常
-
哦,是的,我的错。
error_score将仅覆盖estimator.fit()。你能举个“the AUC is throwing an exception because there is only one class label for this exact split.”的例子吗? -
“ValueError:y_true 中只有一个类。在这种情况下未定义 ROC AUC 分数”将是我得到的例外(到目前为止)。
标签: python scikit-learn random-forest cross-validation