使用 cross_validate 生成混淆矩阵
Posted
技术标签:
【中文标题】使用 cross_validate 生成混淆矩阵【英文标题】:Producing a confusion matrix with cross_validate 【发布时间】:2021-04-15 02:42:25 【问题描述】:我试图弄清楚如何。我可以使用目前的代码打印出分数。
# Instantiating model
model = DecisionTreeClassifier()
#Scores
scoring = 'accuracy' : make_scorer(accuracy_score),
'precision' : make_scorer(precision_score),
'recall' : make_scorer(recall_score),
'f1_score' : make_scorer(f1_score)
# 10-fold cross validation
scores = cross_validate(model, X, y, cv=10, scoring=scoring)
print("Accuracy (Testing): %0.2f (+/- %0.2f)" % (scores['test_accuracy'].mean(), scores['test_accuracy'].std() * 2))
print("Precision (Testing): %0.2f (+/- %0.2f)" % (scores['test_precision'].mean(), scores['test_precision'].std() * 2))
print("Recall (Testing): %0.2f (+/- %0.2f)" % (scores['test_recall'].mean(), scores['test_recall'].std() * 2))
print("F1-Score (Testing): %0.2f (+/- %0.2f)" % (scores['test_f1_score'].mean(), scores['test_f1_score'].std() * 2))
但我正在尝试将这些数据放入混淆矩阵中。我可以使用 cross_val_predict 制作混淆矩阵 -
y_train_pred = cross_val_predict(model, X, y, cv=10)
confusion_matrix(y, y_train_pred)
这很好,但由于它自己进行交叉验证,结果将不匹配。我只是在寻找一种方法来产生匹配的结果。
任何帮助或指示都会很棒。谢谢!
【问题讨论】:
另见***.com/q/22404668/10495893, ***.com/q/9734403/10495893 【参考方案1】:简短的回答是你不能。
混淆矩阵的思想是使用一个训练好的模型评估一个数据。结果是一个矩阵,而不是一个分数,例如准确度。所以你不能计算平均值或类似的东西。 cross_val_score
顾名思义,仅适用于 scores。混淆矩阵不是分数,它是对评估过程中发生的事情的一种总结。
cross_val_predict
与您正在寻找的内容相似。该函数将数据拆分为 K 个部分。每个部分都将使用您使用数据的其他部分获得的模型进行测试。所有测试的样本将被合并。但要小心这个功能:
“将这些预测传递到评估指标中可能不是衡量泛化性能的有效方法。结果可能与 cross_validate 和 cross_val_score 不同,除非所有测试集的大小都相同,并且指标在样本上分解。 "
【讨论】:
【参考方案2】:我认为最好的方法是将混淆矩阵定义为记分器,而不是或除了您定义的其他矩阵之外。幸运的是,这是用户指南中的一个示例;见第三个子弹here:
def confusion_matrix_scorer(clf, X, y):
y_pred = clf.predict(X)
cm = confusion_matrix(y, y_pred)
return 'tn': cm[0, 0], 'fp': cm[0, 1],
'fn': cm[1, 0], 'tp': cm[1, 1]
cv_results = cross_validate(svm, X, y, cv=5,
scoring=confusion_matrix_scorer)
然后cv_results['test_tp']
(等)是一个列表,每个折叠的真阳性数。现在您可以聚合最适合您的混淆矩阵。
首先想到了另一种方法,我将在此处添加它,以防它有助于理解 sklearn 如何处理事物。但我绝对认为第一种方法更好。
您可以在cross_validate
中设置return_estimator
,在这种情况下,返回的字典有一个键estimator
,其值为拟合模型列表。不过,您仍然需要能够找到相应的测试折叠。为此,您可以手动定义您的cv
对象(例如cv = StratifiedKFold(10)
和cross_validate(..., cv=cv)
;然后cv
仍将包含用于进行拆分的相关数据。因此您可以使用拟合的估计器对适当的测试折叠进行评分,生成混淆矩阵。或者你可以使用cross_val_predict(..., cv=cv)
,但此时你会重复拟合,所以你可能应该跳过cross_validate
并自己做循环。
【讨论】:
以上是关于使用 cross_validate 生成混淆矩阵的主要内容,如果未能解决你的问题,请参考以下文章
sklearn RandomizedSearchCV 提取不同折叠的混淆矩阵
使用 sklearn 使用 Keras 数据生成器绘制混淆矩阵