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

时间:2018-03-07 11:55:28

标签: python machine-learning scikit-learn

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

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

2 个答案:

答案 0 :(得分:9)

有几种选择:

  • 正如评论中所建议的,class_weight应该将损失函数提升到首选类。各种估算工具都支持此选项,包括sklearn.linear_model.LogisticRegressionsklearn.svm.SVCsklearn.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)
    

    如果您针对precisions绘制recallsthresholds,您应该会看到如下图片:

    precision-recall-tradeoff

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

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

答案 1 :(得分:0)

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

模型训练阶段的另一项调整是using a recall scorer。您可以在网格搜索交叉验证(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, ...)