模型的准确度是 0.86 而 AUC 是 0.50?

Posted

技术标签:

【中文标题】模型的准确度是 0.86 而 AUC 是 0.50?【英文标题】:Accuracy of model is 0.86 while AUC is 0.50? 【发布时间】:2016-02-22 09:51:48 【问题描述】:

我在 sklearn 中运行了几个模型。这是相同的代码。

# Function for Stochastic Gradient Descent Logistic Regression with Elastic Net
def SGDlogistic(k_fold,train_X,train_Y):
        """Method to implement Multi-class SVM using 
        Stochastic Gradient Descent
        """

        from sklearn.linear_model import SGDClassifier
        scores_sgd_lr = []

        for train_indices, test_indices in k_fold:
            train_X_cv = train_X[train_indices]
            train_Y_cv= train_Y[train_indices]

            test_X_cv = train_X[test_indices]
            test_Y_cv= train_Y[test_indices]

            sgd_lr=SGDClassifier(loss='log',penalty='elasticnet')
            scores_sgd_lr.append(sgd_lr.fit(train_X_cv,train_Y_cv).score(test_X_cv,test_Y_cv))

        print("The mean accuracy of Stochastic Gradient Descent Logistic on CV data is:", np.mean(scores_sgd_lr)) 

        return sgd_lr



def test_performance(test_X,test_Y,classifier,name):
        """This method checks the performance of each algorithm on test data."""

        from sklearn import metrics

        # For SGD
        print ("The accuracy of "+ name + " on test data is:",classifier.score(test_X,test_Y))
        print 'Classification Metrics for'
        print metrics.classification_report(test_Y, classifier.predict(test_X))
        print "Confusion matrix"
        print metrics.confusion_matrix(test_Y, classifier.predict(test_X))




def plot_ROC(test_X,test_Y,classifier):
    """ This functions plots the ROC curve of the classifier"""

    from sklearn.metrics import roc_curve, auc
    false_positive_rate, true_positive_rate, thresholds =roc_curve(test_Y, classifier.predict(test_X))
    roc_auc= auc(false_positive_rate, true_positive_rate)
    plt.title('Receiver Operating Characteristic')
    plt.plot(false_positive_rate, true_positive_rate, 'b',label='AUC = %0.2f'% roc_auc)
    plt.legend(loc='lower right')
    plt.ylabel('True Positive Rate')
    plt.xlabel('False Positive Rate')

第一个函数使用弹性网络惩罚进行逻辑回归。 第二个功能是在测试数据上测试算法的性能。这给出了混淆矩阵和准确性。

而 plot_ROC 在测试数据上绘制 ROC 曲线。

这是我看到的。

('The accuracy of Logistic with Elastic Net on test data is:', 0.90566607467092586)
Classification Metrics for
             precision    recall  f1-score   support

          0       0.91      1.00      0.95    227948
          1       0.50      0.00      0.00     23743

avg / total       0.87      0.91      0.86    251691

Confusion matrix
[[227944      4]
 [ 23739      4]]

(array([ 0.        ,  0.00001755,  1.        ]),
 array([ 0.        ,  0.00016847,  1.        ]),
 array([2, 1, 0]))

如果您看到 ,测试数据的准确率达到 90%,甚至混淆矩阵也显示出良好的准确率和召回率。因此,可能误导的不仅仅是准确性。但是它给出的ROC和AUC就像0.50?。这太奇怪了。根据 ROC,它表现为随机猜测,而准确度和混淆矩阵则显示不同的画面。

请帮忙

编辑2:

好的。所以我添加了在 AUC 中使用概率而不是实际分类的代码。

这就是我现在得到的。

如您所见,AUC 为 0.71。我没有为班级不平衡做任何事情。一个问题。如何将预测分数转换为 SVM 等的概率。目前它只有对数损失或 Huber 损失函数的 predict_proba。这意味着我不能超越 Logistic 回归来获得 AUC?

【问题讨论】:

看起来您的模型几乎总是在预测 0 类。您的数据是 90% 的 0 类,这为您提供了 90% 的准确度。 如果您需要概率,SVM 并不是一个很好的算法。 modified_huber loss 可能是更好的选择。您可以尝试使用 svm_clf.decision_function() 而不是 proba。它应该可以为您提供可用于 ROC / AUC 的排序。 【参考方案1】:

您的结果似乎表明分类器在几乎所有情况下都是预测 0。

下面是一个示例,其中 90% 的数据属于 0 类,分类器始终预测为 0。它看起来与您的结果非常相似。

from sklearn.metrics import confusion_matrix, classification_report
y_true = [0] * 90 + [1] * 10 # 90% Class 0, 10% class 1
y_pred = [0] * 90 + [0] * 10 # All predictions are class 0

print classification_report(y_true, y_pred)

#             precision    recall  f1-score   support
#
#          0       0.90      1.00      0.95        90
#          1       0.00      0.00      0.00        10
#
# avg / total       0.81      0.90      0.85       100

print confusion_matrix(y_true, y_pred)

#[[90  0]
# [10  0]]

print roc_auc_score(y_true, y_pred)

# 0.5

此外,为了测量 AUC,您应该使用 predict_proba 预测概率,而不是预测标签。

probs = classifier.predict_proba(test_X).T[1]
false_positive_rate, true_positive_rate, thresholds = \
     roc_curve(test_Y, probs)

【讨论】:

是的。我有班级不平衡问题。正类占总数据的 10%。现在有什么建议吗? AUC 对于不平衡的数据更可靠。 IE。你的模型不工作。 @Anony-Mousse 我想看看 F 分数,它考虑了 Precision 和 Recall 都考虑了不平衡数据问题?还有任何建议如何考虑不平衡类的事情?我尝试使用 StratifiedKfold 而不是普通的 Kfold 进行交叉验证。请检查代码的编辑 II。代码抛出错误,指出索引超出范围。 @Manish:最重要的是你需要使用概率。 @Manish No. F1 同时考虑了准确率和召回率;但是如果你有 99% 的 A 类,并且总是预测 A 类,那么你的 F1 测量值为 99%(=precision=recall)。注意你的第二个班级的 F1 是 0,但总体 F1 是 0.86?

以上是关于模型的准确度是 0.86 而 AUC 是 0.50?的主要内容,如果未能解决你的问题,请参考以下文章

比较模型之间的 AUC、对数损失和准确度得分

gini基尼系数,累积准确度分布,AUC(风控模型核心指标)

模型评估PR|ROC|AUC

混淆矩阵准确率精确率/查准率召回率/查全率F1值ROC曲线的AUC值

如何在交叉验证时获得AUC-ROC而不是准确度?

AUC 评价指标详解,准确率(ACC),敏感性(sensitivity),特异性(specificity)计算 Python3TensorFlow2入门手册