混淆矩阵显示错误信息?

Posted

技术标签:

【中文标题】混淆矩阵显示错误信息?【英文标题】:confusion matrix shows wrong info? 【发布时间】:2020-07-25 15:34:32 【问题描述】:

更新:附上数据的链接,以防您想重现:

https://github.com/amandawang-dev/credit-worthiness-analysis/blob/master/credit_train.csv

https://github.com/amandawang-dev/credit-worthiness-analysis/blob/master/credit_test.csv

我正在尝试使用 sklearn 的逻辑回归模型来预测该人的银行帐户信用是好还是坏。初始数据集如下所示:


然后我将第一列“Class”二值化('Good'=1, 'Bad'=0),数据集如下所示:

所以我使用sklearn逻辑模型来预测测试数据(测试数据与预测数据集相同,'Class'列也被二值化),并尝试计算混淆矩阵,代码如下,然后混淆矩阵I得到的是

[[  0  54]
 [  0 138]]

准确度得分为 0.71875,我认为混淆矩阵结果是错误的,因为没有真正的正值。有人知道如何解决这个问题吗?谢谢!

from sklearn.linear_model import LogisticRegression
import numpy as np
import pandas as pd

credit_train = pd.read_csv('credit_train.csv')
credit_test = pd.read_csv('credit_test.csv')
credit_train["Class"] = (credit_train["Class"] =="Good").astype(int)
credit_test["Class"] = (credit_test["Class"] =="Good").astype(int)
X=credit_train[['CreditHistory.Critical']]
y=credit_train['Class']
clf = LogisticRegression(random_state=0).fit(X, y)

X_test=credit_test[['CreditHistory.Critical']]
y_test=credit_test['Class']
y_pred=clf.predict(X_test)

from sklearn.metrics import confusion_matrix

cm=confusion_matrix(y_pred=y_pred, y_true=y_test)
score = clf.score(X_test, y_test)
print(score)
print(cm)

每一列的数据类型:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 808 entries, 0 to 807
Data columns (total 17 columns):
Class                             808 non-null int64
Duration                          808 non-null int64
Amount                            808 non-null int64
InstallmentRatePercentage         808 non-null int64
ResidenceDuration                 808 non-null int64
Age                               808 non-null int64
NumberExistingCredits             808 non-null int64
NumberPeopleMaintenance           808 non-null int64
Telephone                         808 non-null int64
ForeignWorker                     808 non-null int64
CheckingAccountStatus.lt.0        808 non-null int64
CheckingAccountStatus.0.to.200    808 non-null int64
CheckingAccountStatus.gt.200      808 non-null int64
CreditHistory.ThisBank.AllPaid    808 non-null int64
CreditHistory.PaidDuly            808 non-null int64
CreditHistory.Delay               808 non-null int64
CreditHistory.Critical            808 non-null int64
dtypes: int64(17)
memory usage: 107.4 KB

【问题讨论】:

类和“CreditHistory.Critical”有什么关系?如果相关性较低,分类器可能只会学习更常见的类 很可能你有严重的类不平衡(负样本比正样本多得多),而不是混淆矩阵“错误”,类不平衡需要特殊处理。 能否提供数据链接?如果没有数据集的链接,没有人可以重现您的结果.. ? github.com/amandawang-dev/credit-worthiness-analysis/blob/… github.com/amandawang-dev/credit-worthiness-analysis/blob/… 【参考方案1】:

首先你的类稍微不平衡,大约 71% 是 1:

credit_test["Class"].value_counts()

1    138
0     54

当您运行逻辑回归时,它会估计平均值,即为 1 的对数几率,然后是与您的因变量相关联的对数几率。如果你看一下系数:

[clf.intercept_,clf.coef_]
[array([0.59140229]), array([[0.9820343]])]

截距似乎是正确的,这意味着平均值约为 exp(0.59140229)/(1+exp(0.59140229)) = 0.643。你的自变量 CreditHistory.Critical 只能是 0 或 1,你的系数在那里是 0.9820343,结果总是 p > 0.5,意味着所有标签 1。

你可以拟合一个没有截距的模型,现在看到预测没有偏差,但基本上不是很准确:

clf = LogisticRegression(random_state=0,fit_intercept=False).fit(X, y)
y_pred=clf.predict(credit_test[['CreditHistory.Critical']])
confusion_matrix(y_pred=y_pred, y_true=y_test)

array([[42, 12],
       [84, 54]])

您可以尝试使用其他一些变量来拟合模型以获取信息,它应该会给您带来更好的结果。

【讨论】:

感谢您的澄清,这非常有帮助,还有一个问题,“因为您的变量 CreditHistory.Critical 也是正相关的,所以结果总是 p > 0.5,意味着所有标签都为 1。”,对于这部分,我不太明白,对于 p>0.5,如果 x 为 1 则 y 为 1 的概率是 p 吗?此外,您是否可以推荐任何文档/书籍/参考资料来解释您的解释,以便我可以阅读更多内容?谢谢! 嗨@AmandaWang,那部分不是很清楚。我已经更新了答案。我的意思是,该术语的系数是正的。您的回答是截距 + 系数 * 变量。因此,如果截距为正,系数为正,变量全部 > 0,则 p > 0.5 faculty.marshall.usc.edu/gareth-james/ISL/… 中有一个逻辑回归部分 .. 或者这个,有更多的编码realpython.com/logistic-regression-python

以上是关于混淆矩阵显示错误信息?的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow:创建混淆矩阵时无法将图像转换为浮点数

我在尝试创建混淆矩阵时遇到错误

混淆矩阵-MATLAB代码详解

混淆矩阵中的错误数据的级别不能多于参考

混淆矩阵

在 KFold 交叉验证的情况下如何显示平均分类报告和混淆矩阵