【问题标题】:How to evaluate accuracy on highly unbalanced data (using Naive Bayes model)?如何评估高度不平衡数据的准确性(使用朴素贝叶斯模型)?
【发布时间】:2019-05-15 06:47:58
【问题描述】:

我在 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: bad input shape (71202, 2)

我如何正确计算这个的准确性?

谢谢!

【问题讨论】:

    标签: python machine-learning data-science


    【解决方案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

    【讨论】:

    • 根据数据集,我应该使用 AUPRC。 roc_auc_score 和这个一样吗?
    • 不,它们不一样。但这是一个不同的问题,我可以指点你this
    • 谢谢你!但是我仍然对为我的代码实现什么感到困惑?我不应该像你建议的那样使用 AUPRC 而不是 ROC AUC 吗?
    • 一些实现有一个额外的参数 eval_metric ,您可以在其中指定一堆指标,如 fscore,average-precision,roc_auc 。我知道 xgboost 有很多。也许看看那些模型。至于 GaussianNB,我不认为你可以添加 eval_metric。
    【解决方案2】:

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

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

    【讨论】:

    • 嗨!谢谢你。我不应该使用 AUPRC 而不是 roc_auc_score 吗? :o
    • 两者都可以使用。 ROC是最常用的一种!它也被称为模型的一致性度量。
    【解决方案3】:

    您可以使用下面的代码来做到这一点。

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

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

    【讨论】:

    • 嗨,但我们不应该使用 AUPRC 来评估指标,因为我们的数据不平衡吗? :)
    • 是的!你当然应该!或精度、召回率、F1-score 等
    【解决方案4】:

    首先,不能使用传统精度或AUC曲线的原因是因为你不平衡 假设您有 99 笔好的交易和 1 笔欺诈行为,并且您想要检测欺诈行为。

    通过只预测好的交易(100 笔好的交易),您将获得 99% 的准确率。这可不好,因为您错过了欺诈性交易。

    要评估不平衡数据集,您应该使用 precisionrecallf1-score 等指标来评估给定非多数类。

    召回率是您正确发现的欺诈数量超过整个数据集中的欺诈数量。例如。你用你的算法发现了 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 分数,有时是 te 精度,有时是召回率,具体取决于您的需要。

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

    更多信息,你可以看看维基百科:

    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 ])
    

    如何阅读?轻松一个!

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

    【讨论】:

      【解决方案5】:

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

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

      在应用特定决策阈值之前计算 ROC 曲线下面积(“AUC”或“AUROC”)和 PR 曲线下面积 (AUPRC)。您可以将它们视为您的分类器在许多决策阈值上的性能的总结。详情请见this article on AUROCthis article on AUPRC

      【讨论】:

        猜你喜欢
        • 2014-08-13
        • 2017-12-21
        • 2017-11-06
        • 1970-01-01
        • 2013-09-09
        • 2014-11-03
        • 2018-01-13
        • 2012-07-31
        • 2016-08-12
        相关资源
        最近更新 更多