如何评估高度不平衡数据的准确性(使用朴素贝叶斯模型)?

问题描述 投票:2回答:5

我发现这个dataset在Kaggle中包含了由欧洲持卡人在2013年9月通过信用卡进行的交易,超过2天。该数据集非常不平衡,欺诈仅占所有交易的0.172%。

我想在这个数据集上实现一个(高斯)朴素贝叶斯分类器来识别欺诈性交易。

我已经做了以下事情:

  1. 将数据加载到数据框中
  2. 将数据拆分为X和y
  3. 标准化数据
  4. 使用ADASYN处理不平衡数据集
  5. 构建高斯朴素贝叶斯模型

现在,我想评估模型:

from sklearn import metrics
metrics.accuracy_score(y_test, y_pred_class)
# Output: 0.95973427712704695

metrics.confusion_matrix(y_test, y_pred_class)
# Output: 
# array([[68219,  2855],
#       [   12,   116]], dtype=int64)

from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred_class, digits=4))
# Output:
#              precision    recall  f1-score   support
#
#           0     0.9998    0.9598    0.9794     71074
#           1     0.0390    0.9062    0.0749       128

#   micro avg     0.9597    0.9597    0.9597     71202
#   macro avg     0.5194    0.9330    0.5271     71202
#weighted avg     0.9981    0.9597    0.9778     71202

但是,在数据集中注意到:

“鉴于等级不平衡比,我们建议使用精确回忆曲线下的面积(AUPRC)来测量精度。混淆矩阵精度对于不平衡分类没有意义。”

那么这是否意味着即使我已经完成了ADASYN并对数据进行了过采样,我还是应该用AUPRC来衡量准确度?

我尝试计算ROC_AUC的准确度(这与AUPRC相同吗?)但收到错误:

y_pred_prob = gaussian.predict_proba(X_test)
metrics.roc_auc_score(y_test, y_pred_prob)

ValueError:输入形状错误(71202,2)

如何正确计算此准确度?

谢谢!

python machine-learning data-science
5个回答
1
投票

您必须为每条记录提供第二类概率。试试这个!

y_pred_prob = np.array(gaussian.predict_proba(X_test))
metrics.roc_auc_score(y_test, y_pred_prob[:,1])

1
投票

首先,您不能使用传统准确度或AUC曲线的原因是因为您不平衡想象您有99个好交易和1个欺诈并且您想要检测欺诈。

通过预测只有良好的交易(100次良好交易),您将获得99%的准确率。哪个不好,因为你错过了欺诈交易。

要评估不平衡数据集,您应该为给定的非多数类使用精度,召回和f1分数等指标。

召回是您在整个数据集中的欺诈数量上正确发现的欺诈数量。例如。您在算法中发现了12个欺诈行为,数据集中有100个欺诈行为,因此您的回忆将是:

召回= 12/100 => 12%/ 0.12

精确度是您在找到的欺诈数量上正确找到的欺诈数量。例如。您的算法表明您发现了12个欺诈,但在这12个欺诈中,只有8个是真正的欺诈行为,因此您的精确度将是:

精度= 8/12 => 66%/ 0.66

F1-Score是前两个测量值之间的调和平均值:

F1 =(2 *精度*召回)/(精确+召回)

所以这里,F1 =(2 * 0.12 * 0.66)/(0.12 + 0.66)= 0.20 => 20%

20%不是很好。完全没有。

一般来说,目标是根据您的需要最大化F1分数,或者有时精确度或有时召回。

但这是一个权衡,当你改进一个,另一个降低,反之亦然。

有关更多信息,您可以查看维基百科:

https://en.wikipedia.org/wiki/Precision_and_recall

https://en.wikipedia.org/wiki/F1_score

它们也有sklearn(sklearn.metrics):

from sklearn.metrics import precision_score
>>> y_true = [0, 1, 2, 0, 1, 2]
>>> y_pred = [0, 2, 1, 0, 0, 1]
>>> precision_score(y_true, y_pred)  
0.22

from sklearn.metrics import recall_score
>>> y_true = [0, 1, 2, 0, 1, 2]
>>> y_pred = [0, 2, 1, 0, 0, 1]
>>> recall_score(y_true, y_pred, average='macro')  
0.33

from sklearn.metrics import f1_score
>>> y_true = [0, 1, 2, 0, 1, 2]
>>> y_pred = [0, 2, 1, 0, 0, 1]
>>> f1_score(y_true, y_pred, average='macro')  
0.26

另一个要遵循的指标是Precision-Recall曲线:

这是计算不同阈值的精确度与召回率。

import numpy as np
>>> from sklearn.metrics import precision_recall_curve
>>> y_true = np.array([0, 0, 1, 1])
>>> y_scores = np.array([0.1, 0.4, 0.35, 0.8])
>>> precision, recall, thresholds = precision_recall_curve(
...     y_true, y_scores)
>>> precision  
array([0.66666667, 0.5       , 1.        , 1.        ])
>>> recall
array([1. , 0.5, 0.5, 0. ])
>>> thresholds
array([0.35, 0.4 , 0.8 ])

enter image description here

怎么读这个?容易一个!

这意味着在0.6 Recall,你有0.9精度(或相反)和1召回,你有0.6精度等。

enter image description here


1
投票
y_pred_prob = gaussian.predict_proba(X_test)

将返回所有类的概率值。确保只将一个传递给roc_auc函数。

如果你想要正面类的roc_auc函数,假设它是1(通常是)。用这个:

metrics.roc_auc_score(y_test, y_pred_prob[:,1])

检查文档roc_auc_scorepredict_proba


1
投票

在您的部分问题中,您询问ROC曲线下的面积是否与AUPRC相同。他们不一样。使用真阳性率(回忆)和假阳性率构建ROC曲线。使用真阳性率(召回)和精确度构建PR曲线。当你的数据集有很多真正的负数时,AUPRC是一个更好的选择,因为它的公式中根本不使用真正的负数。

准确度,精确度,召回率和F1分数是在您将特定决策阈值应用于分类器的预测概率后计算的“点度量”。

在应用特定决策阈值之前,计算ROC曲线下面积(“AUC”或“AUROC”)和PR曲线下面积(AUPRC)。您可以将它们视为分类器在许多决策阈值中的性能摘要。有关更多详细信息,请参阅this article on AUROCthis article on AUPRC


0
投票

您可以使用以下代码执行此操作。

from sklearn import metrics
print("Accuracy: {0:.4f}".format(metrics.accuracy_score(y_test, y_pred_prob )))

避免在十进制后打印多位数。 (0:.4f)

© www.soinside.com 2019 - 2024. All rights reserved.