您描述的情况实际上与文档示例中的情况相同,使用虹膜数据的前 2 类和 LinearSVC 分类器(该算法使用平方铰链损失,就像您在此处使用的铰链损失一样,导致只产生二元结果而不是概率结果的分类器)。产生的情节是:

即在质量上与您的相似。
不过,您的问题是一个合理的问题,而且确实是一个不错的问题;当我们的分类器确实没有产生概率预测时(因此任何阈值的概念听起来都不相关),我们怎么会得到与概率分类器产生的行为相似的行为?
要了解为什么会这样,我们需要对 scikit-learn 源代码进行一些挖掘,从plot_precision_recall_curve
这里使用的函数开始,然后沿着线程向下进入兔子洞......
从 的源代码开始plot_precision_recall_curve
,我们发现:
y_pred, pos_label = _get_response(
X, estimator, response_method, pos_label=pos_label)
因此,为了绘制 PR 曲线,预测y_pred
不是由我们的分类器直接产生的,predict
而是由_get_response()
scikit-learn 的内部函数产生的。
_get_response()
反过来包括以下行:
prediction_method = _check_classifier_response_method(
estimator, response_method)
y_pred = prediction_method(X)
这最终将我们引向了_check_classifier_response_method()
内部函数;您可以查看它的完整源代码- 这里感兴趣的是语句后的以下3 行:else
predict_proba = getattr(estimator, 'predict_proba', None)
decision_function = getattr(estimator, 'decision_function', None)
prediction_method = predict_proba or decision_function
到现在为止,你可能已经开始明白了:在底层,plot_precision_recall_curve
检查一个predict_proba()
或一个decision_function()
方法是否可用于所使用的分类器;如果 apredict_proba()
不可用,例如您在此处的带有铰链损失的 SGDClassifier 的情况(或带有平方铰链损失的 LinearSVC 分类器的文档示例decision_function()
),它会改为使用该方法,以计算y_pred
随后将用于绘制 PR(和 ROC)曲线。
以上可以说已经回答了您关于 scikit-learn 在这种情况下如何准确地生成绘图和基础计算的编程问题;关于是否以及为什么使用非概率分类器确实是获得 PR(或 ROC)曲线的正确和合法方法的进一步理论调查超出了 SO 的范围,如有必要,decision_function()
应将其提交给Cross Validated 。