模型的准确度是 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?的主要内容,如果未能解决你的问题,请参考以下文章
gini基尼系数,累积准确度分布,AUC(风控模型核心指标)
混淆矩阵准确率精确率/查准率召回率/查全率F1值ROC曲线的AUC值
AUC 评价指标详解,准确率(ACC),敏感性(sensitivity),特异性(specificity)计算 Python3TensorFlow2入门手册