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

Python 如何评估高度不平衡数据的准确性(使用朴素贝叶斯模型)?,python,machine-learning,data-science,Python,Machine Learning,Data Science,我在Kaggle上发现了这封信,其中包含2013年9月欧洲持卡人在2天内通过信用卡进行的交易。数据集高度不平衡,欺诈仅占所有交易的0.172% 我想在这个数据集上实现一个(高斯)朴素贝叶斯分类器来识别欺诈交易 我已经做了以下工作: 将数据加载到数据帧中 将数据拆分为X和y 数据标准化 使用ADASYN处理不平衡的数据集 建立高斯朴素贝叶斯模型 现在,我想对模型进行评估: from sklearn import metrics metrics.accuracy_score(y_test, y_pr

我在Kaggle上发现了这封信,其中包含2013年9月欧洲持卡人在2天内通过信用卡进行的交易。数据集高度不平衡,欺诈仅占所有交易的0.172%

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

我已经做了以下工作:

  • 将数据加载到数据帧中

  • 将数据拆分为X和y

  • 数据标准化

  • 使用ADASYN处理不平衡的数据集

  • 建立高斯朴素贝叶斯模型

  • 现在,我想对模型进行评估:

    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)

    我如何正确计算这个的准确度

    谢谢大家!

    y_pred_prob = gaussian.predict_proba(X_test)
    
    将返回所有类的概率值。确保只向
    roc\u auc
    函数传递一个

    如果你想要正数类的roc_auc函数,假设它是1(通常是)。使用以下命令:

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

    检查文档,你必须给出每条记录的二级概率。试试这个

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

    您可以使用下面的代码来实现这一点

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

    避免在小数点后打印多个数字。(0.4f)

    首先,您不能使用传统精度或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成绩,有时是te精度,有时是召回率,这取决于您的需要

    但这是一种权衡,当你提高一个时,另一个会降低,反之亦然

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

    它们也可以在sklearn()中找到:

    另一个要遵循的指标是精度召回曲线:

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

    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次召回时,精度为0.6等


    在你的部分问题中,你问ROC曲线下的面积是否与AUPRC相同。它们不一样。利用真阳性率(召回率)和假阳性率构造ROC曲线。使用真实阳性率(召回率)和精确度构建PR曲线。AUPRC是一个更好的选择,当您的数据集有许多真正的消极因素,因为它不使用真正的消极因素在其公式

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


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

    根据数据集,我应该使用AUPRC。roc_auc_的分数和这个一样吗?不,他们不一样。但这是一个不同的问题,我可以指出你为此感谢你!但是我仍然不知道我的代码应该实现什么?我不应该像你建议的那样使用AUPRC而不是ROC AUC吗?有些实现有一个额外的参数eval_metric,你可以指定一系列指标,比如fscore、平均精度、ROC_AUC。我知道xgboost有很多优点。也许看看那些模型。至于高斯b,我不知道';我不认为您可以添加一个eval_度量。嗨,但是我们不应该使用AUPRC来评估度量,因为我们的数据是不平衡的吗?:)是的!你当然应该!或者精确性,回忆,F1成绩。。艾奇!谢谢你。我不应该使用AUPRC而不是roc\u auc\u分数吗可以使用oBoth。ROC是最常用的一个!它也称为模型的一致性度量。
    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 ])