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

时间:2018-12-14 01:11:07

标签: python machine-learning data-science

我在Kaggle上发现了此dataset,其中包含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)

如何正确计算精度?

谢谢!

5 个答案:

答案 0 :(得分:2)

首先,您无法使用传统的准确性或AUC曲线的原因是,您不平衡 想象一下,您有99笔良好的交易和1笔欺诈,并且您想检测出欺诈。

通过仅愚蠢地预测良好交易(100笔良好交易),您将具有99%的准确性。那样不好,因为您错过了欺诈性交易。

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

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

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

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

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

F1-分数是这两个先前度量之间的谐波均值:

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

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

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

通常,目标是最大化 F1分数,或者有时根据您的需要精确度或召回率。

但这是一个权衡,当您提高一个时,另一个就降低,反之亦然。

有关更多信息,您可以查看Wikipedia:

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

遵循的另一个指标是精确调用曲线:

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

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时,您的精度为0.9(或者相反) 并且在1次调用时,您的精度为0.6等。

enter image description here

答案 1 :(得分:1)

y_pred_prob = gaussian.predict_proba(X_test)

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

如果您想将roc_auc函数用于肯定类,则假定它为1(通常为1)。使用这个:

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

检查文档roc_auc_scorepredict_proba

答案 2 :(得分:1)

您必须为每条记录给出二等概率。试试吧!

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

答案 3 :(得分:1)

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

准确性,准确性,召回率和F1分数是“分数指标”,是在将特定决策阈值应用于分类器的预测概率之后计算出来的。

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

答案 4 :(得分:0)

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

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

为避免在小数点后打印许多数字。 (0:.4f)