如何计算所有折叠的平均分类报告?

Posted

技术标签:

【中文标题】如何计算所有折叠的平均分类报告?【英文标题】:How to calculate average classification report across all folds? 【发布时间】:2019-12-13 20:01:09 【问题描述】:

我正在尝试进行二元类分类。因为我有一个小数据集(275 个样本),所以我进行了 Leave-one-out 交叉验证,并希望获得所有折叠的平均分类报告和 AUROC/AUPRC。

我已密切关注this link 得出我的结果,但我无法理解最后一行的代码在做什么。

for i in classifiers:
    print(i)
    originalclass = []
    predictedclass = []
    model=i
    loo = LeaveOneOut()
    print('Scores before feature selection')
    scores = cross_val_score(model, subset, y,cv=loo,scoring=make_scorer(classification_report_with_accuracy_score))
    print("CV score",np.mean(cross_val_score(model,subset,y,cv=loo,scoring='roc_auc')))
    print(classification_report(originalclass, predictedclass))
    print('Scores after feature selection')
    X_reduced=feature_reduction_using_RFECV(model,subset,y)
    scores = cross_val_score(model, X_reduced, y,cv=loo,scoring=make_scorer(classification_report_with_accuracy_score))
    print("CV score",np.mean(cross_val_score(model,X_reduced,y,cv=loo,scoring='roc_auc')))
    print(classification_report(originalclass, predictedclass))

上述代码中的平均发生在哪里?我正在计算平均 CV 分数并打印出来。但那之后的那一行最让我困惑。我一开始就初始化了 originalclass 和 predictableclass 变量,但是在最后一行打印之前它在哪里使用?

print(classification_report(originalclass, predictedclass))

修改后的代码

for i in classifiers:
    print(i)
    originalclass = y
    model=i
    loo = LeaveOneOut()
    print('Scores before feature selection')
    y_pred = cross_val_predict(model, subset, y, cv=loo)
    print(classification_report(originalclass, y_pred))
    print("CV score",np.mean(cross_val_score(model,subset,y,cv=loo,scoring='roc_auc')))
    print(classification_report(originalclass, y_pred))
    print('Scores after feature selection')
    X_reduced=feature_reduction_using_RFECV(model,subset,y)
    y_pred = cross_val_predict(model, X_reduced, y, cv=loo)
    classification_report(originalclass, y_pred)
    print("CV score",np.mean(cross_val_score(model,X_reduced,y,cv=loo,scoring='roc_auc')))
    print(classification_report(originalclass, y_pred))

【问题讨论】:

你的问题没有任何意义;您当然可以平均 CV 分数(此处为 np.mean),但您不能“平均”分类报告。请参阅docs 以准确了解分类报告的具体含义 在交叉验证中,我们对每 n-1 折进行训练并在第 n 折进行测试。作为每次运行的结果,我们得到一个混淆矩阵,从而得到分类报告。我不能平均每个折叠的敏感性/特异性等吗? 【参考方案1】:

当你使用时

print("CV score",np.mean(cross_val_score(model,X_reduced,y,cv=loo,scoring='roc_auc'))) 

您在 cv 即 LeaveOneOut 方案下打印模型的平均交叉验证 roc_auc 指标。


下一条命令:

print(classification_report(originalclass, predictedclass))

用于打印完整的分类报告,而不仅仅是上一行中的平均 roc_auc 指标。

此命令将以下内容作为输入参数:

classification_report(y_true, y_pred)

y_true 对你来说是 originalclass,ground truth 和 y_pred 应该是预测的交叉验证标签/类。


你应该有这样的东西:

y_pred = cross_val_predict(model, X_reduced, y, cv=loo)
classification_report(originalclass, y_pred)

现在,y_pred 已经是标签的交叉验证预测,因此分类报告将根据分类指标打印交叉验证的结果。


用于说明上述内容的玩具示例:

from sklearn.metrics import classification_report

originalclass = [0, 1, 2, 2, 2]
y_pred = [0, 0, 2, 2, 1]
print(classification_report(originalclass, y_pred))

          precision    recall  f1-score   support

       0       0.50      1.00      0.67         1
       1       0.00      0.00      0.00         1
       2       1.00      0.67      0.80         3

 micro avg       0.60      0.60      0.60         5
 macro avg       0.50      0.56      0.49         5
 weighted avg       0.70      0.60      0.61         5

【讨论】:

感谢您的回复。所以为了澄清一下,我上面粘贴的代码并没有计算所有折叠的平均分类报告? 您的初始代码根本不起作用。 originalclass, predictedclass 是在哪里构造的?他们是空的 现在看来没问题。 originalclass = y 当然可以在循环之外。考虑支持并接受我的回答 所以最后我们使用交叉验证模型预测我们的标签并获得分类报告,对吧? 完全正确。 cross_val_predict 使用交叉验证预测标签。

以上是关于如何计算所有折叠的平均分类报告?的主要内容,如果未能解决你的问题,请参考以下文章

如何在同一折叠上使用多个分类器运行 scikit 的交叉验证

SKlearn中具有嵌套交叉验证的分类报告(平均值/个体值)

如何使用 scikit-learn 计算用于情感分析的分类报告

如何折叠类别或重新分类变量?

评分预测问题计算方法

计算多标签分类问题的ROC曲线、分类报告和混淆矩阵