0

我正在使用 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。然后我检查了混淆矩阵文档,我发现:

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

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

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

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

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

4

1 回答 1

1

经过一些实验,我发现当IsolationForestfromsklearn用于不平衡数据时,如果检查confusion_matrix,可以看出IsolationForest将多数(Normal)类视为正类,而次要类应该是Fraud /Outlier/Anomaly中的正类检测任务。

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

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

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

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

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

+----------------------------+---------------+--------------+
|                            |  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"]))
于 2021-06-05T12:37:37.860 回答