【问题标题】:Plotting Precision-Recall curve when using cross-validation in scikit-learn在 scikit-learn 中使用交叉验证时绘制 Precision-Recall 曲线
【发布时间】:2014-12-22 15:26:19
【问题描述】:

我正在使用交叉验证来评估具有 scikit-learn 的分类器的性能,并且我想绘制 Precision-Recall 曲线。我在 scikit-learn 的网站上找到了an example 来绘制 PR 曲线,但它没有使用交叉验证进行评估。

使用交叉验证时如何在 scikit learn 中绘制 Precision-Recall 曲线?

我做了以下,但我不确定这是否是正确的方法(伪代码):

for each k-fold:

   precision, recall, _ =  precision_recall_curve(y_test, probs)
   mean_precision += precision
   mean_recall += recall

mean_precision /= num_folds
mean_recall /= num_folds

plt.plot(recall, precision)

你怎么看?

编辑:

它不起作用,因为precisionrecall 数组的大小在每次折叠后都不同。

有人吗?

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    不是在每次折叠后记录精度和召回值,而是在每次折叠后存储测试样本的预测。接下来,收集所有测试(即袋外)预测并计算精度和召回率。

     ## let test_samples[k] = test samples for the kth fold (list of list)
     ## let train_samples[k] = test samples for the kth fold (list of list)
    
     for k in range(0, k):
          model = train(parameters, train_samples[k])
          predictions_fold[k] = predict(model, test_samples[k])
    
     # collect predictions
     predictions_combined = [p for preds in predictions_fold for p in preds]
    
     ## let predictions = rearranged predictions s.t. they are in the original order
    
     ## use predictions and labels to compute lists of TP, FP, FN
     ## use TP, FP, FN to compute precisions and recalls for one run of k-fold cross-validation
    

    在一次完整的 k 折交叉验证运行下,预测器对每个样本进行一个且仅一个预测。给定 n 个样本,您应该有 n 个测试预测。

    (注意:这些预测与训练预测不同,因为预测器对每个样本进行预测,而之前从未见过它。)

    除非您使用 leave-one-out 交叉验证,否则 k 折交叉验证通常需要对数据进行随机分区。理想情况下,您会进行重复(和分层)k-fold 交叉验证。然而,组合来自不同轮次的精确召回曲线并不简单,因为您不能在精确召回点之间使用简单的线性插值,这与 ROC 不同(请参阅 Davis and Goadrich 2006)。

    我个人使用 Davis-Goadrich 方法在 PR 空间中插值计算了 AUC-PR(随后进行数值积分),并使用来自重复分层 10 折交叉的 AUC-PR 估计值比较了分类器验证。

    为了绘制一个漂亮的图,我展示了其中一个交叉验证轮次的代表性 PR 曲线。

    当然,根据数据集的性质,还有许多其他评估分类器性能的方法。

    例如,如果您的数据集中(二进制)标签的比例没有偏差(即大约为 50-50),您可以使用更简单的 ROC 分析和交叉验证:

    从每个折叠中收集预测并构建 ROC 曲线(如前所述),收集所有 TPR-FPR 点(即取所有 TPR-FPR 元组的并集),然后绘制可能平滑的组合点集。可选地,使用简单的线性插值和复合梯形法进行数值积分计算AUC-ROC。

    【讨论】:

    • 对不平衡数据使用 PR 而不是 ROC 有什么解释吗?在不平衡的情况下,ROC 是无用的还是缺乏对模型的有意义的洞察力,为什么?感谢您的任何回复。
    • 我找到了相关论文,需要时间阅读:autonlab.org/icml_documents/camera-ready/…
    • ROC AUC 当然可以用于不平衡数据,事实上,即使在极端情况下,它通常也是不平衡的优选指标之一。它具有许多优于 PR 的统计特性。可以在此处查看 David Powers 的回答并参考 stats.stackexchange.com/questions/7207/…。然而,在大海捞针类型的问题中,我们非常关心在阳性分数中不会出现误报,PR 比 ROC 更敏感,尽管在 ROC 中,当 N>>P 时特异性会略有下降,这仍然会被拾起.
    【解决方案2】:

    这是目前使用交叉验证为 sklearn 分类器绘制 Precision Recall 曲线的最佳方法。最好的部分是,它绘制了所有类的 PR 曲线,因此您也可以获得多条外观整洁的曲线

    from scikitplot.classifiers import plot_precision_recall_curve
    import matplotlib.pyplot as plt
    
    clf = LogisticRegression()
    plot_precision_recall_curve(clf, X, y)
    plt.show()
    

    该函数自动负责交叉验证给定的数据集,连接所有不折叠的预测,并计算每个类的 PR 曲线 + 平均 PR 曲线。这是一个为您处理一切的单行函数。

    Precision Recall Curves

    免责声明:请注意,这使用了我构建的 scikit-plot 库。

    【讨论】:

    • 我们如何知道在 plot_precision_recall_curve() 中使用了多少折交叉验证?
    猜你喜欢
    • 2015-06-21
    • 2018-01-20
    • 2019-08-27
    • 2016-04-25
    • 2021-05-08
    • 2014-01-09
    • 2019-08-15
    • 2021-05-19
    • 2017-09-02
    相关资源
    最近更新 更多