【问题标题】: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 折进行测试。作为每次运行的结果,我们得到一个混淆矩阵,从而得到分类报告。我不能平均每个折叠的敏感性/特异性等吗?

标签: scikit-learn classification cross-validation


【解决方案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 使用交叉验证预测标签。
猜你喜欢
  • 2020-08-03
  • 1970-01-01
  • 2012-10-27
  • 2011-05-29
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多