【问题标题】:Does majority class treated as positive in Sklearn? Sklearn calculate False positive rate as False negative rateSklearn 中的多数类是否被视为积极的? Sklearn 将误报率计算为误报率
【发布时间】:2019-10-20 21:57:54
【问题描述】:

我正在使用 Sklearn 对不平衡数据集进行分类。 Sklearn 计算了false_positive_ratetrue_positive_rate 错误;当我想计算 AUC 分数时,结果与我从混淆矩阵中得到的结果不同。

从 Sklearn 我得到以下混淆矩阵:

confusion = confusion_matrix(y_test, y_pred)
array([[  9100,   4320],
       [109007, 320068]], dtype=int64)

当然,我将输出理解为:

+-----------------------------------+------------------------+
|        |       Predicted          |        Predicted       |
+-----------------------------------+------------------------+
| Actual | True positive = 9100     |  False-negative = 4320 |                       
| Actual | False-positive = 109007  |  True negative = 320068|
+--------+--------------------------+------------------------+

但是,对于 FPR 和 TPR,我得到了以下结果:

false_positive_rate, true_positive_rate, thresholds = roc_curve(y_test, y_pred)
(false_positive_rate, true_positive_rate)
(array([0.        , 0.3219076, 1.        ]),
 array([0.        , 0.7459488, 1.        ]))

结果与confusion_matrix 不同。根据我的表格,FPR实际上是FNR,而TPR实际上是TNR。然后我检查了confusion matrix document,我发现:

因此,在二元分类中,真负数为 C0,0,假负数为 C1,0,真正数为 C1,1,假正数为 C0,1。

这意味着根据 Sklearn,confusion_matrix 看起来像这样:

+-----------------------------------+---------------------------+
|        |       Predicted          |        Predicted          |
+-----------------------------------+---------------------------+
| Actual | True-Positive  = 320068  | False-Negative = 109007   |                       
| Actual | False-Positive = 4320    | True-Negative  = 9100     |
+--------+--------------------------+---------------------------+

根据理论,对于二元分类,稀有类表示为正类。

为什么 Sklearn 将多数类视为积极的?

【问题讨论】:

  • 你的实际类标签是什么?
  • 少数群体的类别标签为0,多数群体为1。
  • 我现在切换了这两个类的类标签,得到了正确的答案。似乎 Sklearn 将 1 视为正类,将 0 视为负类。
  • 是的,这正是原因——不出所料,1 被视为正类

标签: machine-learning scikit-learn confusion-matrix


【解决方案1】:

经过一些实验,我发现当sklearn中的IsolationForest用于不平衡数据时,如果检查confusion_matrix,可以看出IsolationForest对待大多数(正常)类作为正类,而次要类应该是 Fraud/Outlier/Anomaly detection 任务中的positive class

要克服这一挑战,有两种解决方案:

  1. 解释混淆矩阵结果,反之亦然。 FP 而不是 FNTP 而不是 TN
  2. 如果由于对不平衡数据的 IF 处理不当,您想正确传递结果,您可以使用以下技巧:

通常,如果在IsolationForest 的输出中将 1 替换为 -1,然后将 -1 替换为 1,则 IF 为异常值返回 -1,为内部值返回 1,那么在这种情况下,您可以正确使用标准度量计算。

IF_model = IsolationForest(max_samples="auto",
                           random_state=11,
                           contamination = 0.1,
                           n_estimators=100,
                           n_jobs=-1)



IF_model.fit(X_train_sf, y_train_sf)
y_pred_test = IF_model.predict(X_test_sf)

counts = np.unique(y_pred_test, return_counts=True)
#(array([-1,  1]), array([44914,  4154]))

#replace 1 with -1 and then -1 with 1
if (counts[1][0] < counts[1][1] and counts[0][0] == -1) or (counts[1][0] > counts[1][1] and counts[0][0] == 1): y_pred_test = -y_pred_test

考虑到混淆矩阵documentation 和问题定义here,上述技巧应该有效,并且对于欺诈/异常值/异常检测或基于文献Ref.1Ref.2、@987654326 的二进制分类器的正确形式的混淆矩阵@如下:

+----------------------------+---------------+--------------+
|                            |  Predicted    |  Predicted   |
+----------------------------+---------------+--------------+
| Actual (Positive class)[1] |      TP       |      FN      |                       
| Actual (Negative class)[-1]|      FP       |      TN      |
+----------------------------+---------------+--------------+
tn, fp, fn, tp = confusion_matrix(y_test_sf, y_pred_test).ravel()
print("TN: ",tn,"\nFP: ", fp,"\nFN: " ,fn,"\nTP: ", tp)
print("Number of positive class instances: ",tp+fn,"\nNumber of negative class instances: ", tn+fp)

检查评估:

print(classification_report(y_test_sf, y_pred_test, target_names=["Anomaly", "Normal"]))

【讨论】:

  • 你好@Mario,只有当我们使用confusion_matrix 时才会出现这种情况,或者我们应该在训练时告诉 Isolution Forest 学习器哪个类具有哪个标签?
  • @Perl 基本上 IF 是一个 un 监督模型(尽管如此,它可以与监督设置一起用于最终模型评估)。来自 Sklearn 的confusion_matrix可能抛出这个问题/不好的处理。
猜你喜欢
  • 1970-01-01
  • 2015-02-13
  • 2013-10-24
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 2019-07-31
  • 2014-08-12
相关资源
最近更新 更多