如何惩罚假阴性而不是误报

ive*_*ion 9 python machine-learning scikit-learn

从业务角度来看,假阴性导致成本(真实货币)比假阳性高出约10倍.鉴于我的标准二进制分类模型(logit,随机森林等),我如何将其合并到我的模型中?

我是否必须改变(加权)损失函数以支持"首选"错误(FP)?如果是这样,怎么办?

Max*_*xim 11

有几种选择:

  • 正如评论中所建议的那样,class_weight应该将损失函数提升到首选类.此选项是由各种估计,包括支持sklearn.linear_model.LogisticRegression, sklearn.svm.SVC,sklearn.ensemble.RandomForestClassifier,等.请注意,重量比没有理论上的限制,所以即使1到100对你来说还不够强,你也可以继续使用1到500等等.

  • 您还可以在交叉验证期间选择非常低的决策阈值,以选择提供最高召回率的模型(尽管可能精度较低).召回接近1.0有效意味着false_negatives接近0.0,这是想要的.为此,使用sklearn.model_selection.cross_val_predictsklearn.metrics.precision_recall_curve功能:

    y_scores = cross_val_predict(classifier, x_train, y_train, cv=3,
                                 method="decision_function")
    
    precisions, recalls, thresholds = precision_recall_curve(y_train, y_scores)
    
    Run Code Online (Sandbox Code Playgroud)

    如果你绘制precisionsrecalls反对thresholds,你应该看到这样的图片:

    精密召回,权衡

    选择最佳阈值后,您可以使用classifier.decision_function()方法的原始分数进行最终分类.

最后,尽量不要过度优化你的分类器,因为你可以很容易地得到一个简单的const分类器(这显然从来没有错,但是没用).


mor*_*ork 7

正如 @Maxim 提到的,进行这种调整有两个阶段:模型训练阶段(如自定义权重)和预测阶段(如降低决策阈值)。

模型训练阶段的另一个调整是使用召回评分器。您可以在网格搜索交叉验证(GridSearchCV)中使用它,以使用最佳超参数调整分类器以实现高召回率。

GridSearchCV评分参数可以接受“recall”字符串或函数recall_score

由于您使用的是二元分类,因此这两个选项都应该开箱即用,并使用适合二元分类的默认值调用recall_score :

  • 平均值:“二元”(即一个简单的召回值)
  • pos_label: 1 (如 numpy 的 True 值)

如果您需要自定义它,您可以使用make_scorer包装现有的记分器或自定义记分器,并将其传递给评分参数。

例如:

from sklearn.metrics import recall_score, make_scorer

recall_custom_scorer = make_scorer(
    lambda y, y_pred, **kwargs: recall_score(y, y_pred, pos_label='yes')[1]
)

GridSearchCV(estimator=est, param_grid=param_grid, scoring=recall_custom_scorer, ...)
Run Code Online (Sandbox Code Playgroud)