nz_*_*_21 1 python machine-learning scikit-learn precision-recall stochastic-gradient
我正在研究二元分类问题,我有一个 sgd 分类器,如下所示:
sgd = SGDClassifier(
max_iter = 1000,
tol = 1e-3,
validation_fraction = 0.2,
class_weight = {0:0.5, 1:8.99}
)
Run Code Online (Sandbox Code Playgroud)
我将它安装在我的训练集上并绘制了精确召回曲线:
from sklearn.metrics import plot_precision_recall_curve
disp = plot_precision_recall_curve(sgd, X_test, y_test)
Run Code Online (Sandbox Code Playgroud)
假设scikit-learn中loss="hinge"默认使用sgd分类器,那么如何绘制这条曲线呢?我的理解是 sgd 的输出不是概率性的——它要么是 1/0。因此,不存在“阈值”,但 sklearn 精确回忆曲线绘制了具有不同类型阈值的锯齿形图。这里发生了什么?
您描述的情况实际上与文档示例中的情况相同,使用虹膜数据的前 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)
Run Code Online (Sandbox Code Playgroud)
因此,出于绘制 PR 曲线的目的,预测y_pred不是直接由我们的分类器的方法产生的,而是由scikit-learn 的内部函数产生的。predict_get_response()
_get_response()依次包括以下几行:
prediction_method = _check_classifier_response_method(
estimator, response_method)
y_pred = prediction_method(X)
Run Code Online (Sandbox Code Playgroud)
这最终引导我们进入_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
Run Code Online (Sandbox Code Playgroud)
到目前为止,您可能已经开始明白这一点:在底层,plot_precision_recall_curve检查 a 或predict_proba()adecision_function()方法是否可用于所使用的分类器;如果 apredict_proba()不可用,就像这里具有铰链损失的 SGDClassifier 的情况(或具有平方铰链损失的 LinearSVC 分类器的文档示例decision_function()),它会恢复到该方法,以计算y_pred随后将用于绘制 PR(和 ROC)曲线。
上面的内容可以说已经回答了您的编程问题,即在这种情况下 scikit-learn 究竟如何生成绘图和基础计算;关于是否以及为什么使用decision_function()非概率分类器确实是获得 PR(或 ROC)曲线的正确且合法的方法的进一步理论询问超出了 SO 的范围,如有必要,应将其解决到Cross Validated 。
| 归档时间: |
|
| 查看次数: |
543 次 |
| 最近记录: |