我正在使用Sklearn处理具有不平衡数据集的分类。我想当我想计算AUC分数时,Sklearn错误地计算了误报率和正确率,结果与我从混淆矩阵中得出的结果有所不同。
从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. ]))
结果与混淆矩阵不同。我根据表格发现,FPR实际上是FNR,而TPR实际上是TNR。然后我检查了confusion matrix document,发现:
因此,在二进制分类中,真实否定计数为C0,0,错误否定计数为C1,0,真实正计数为C1,1,错误阳性计数为C0,1。
这意味着Sklearn的混淆矩阵看起来像这样:
+-----------------------------------+---------------------------+
| | Predicted | Predicted |
+-----------------------------------+---------------------------+
| Actual | True positive = 320068 | False negative = 109007 |
| Actual | False positive = 4320 | True negative = 9100 |
+--------+--------------------------+---------------------------+
根据该理论,对于二进制分类,稀有类别被表示为肯定类别。
为什么斯克莱恩(Sklearn)将多数阶层视为正面?
答案 0 :(得分:1)
经过一些实验,我发现当 const findCharacters = marvel.characters.findAll()
.then(console.log)
.fail(console.error)
.done();
return (
<View style={styles.container}>
<VirtualizedList
data={/* what to pass here? */}
renderItem={/* what to pass here? */} />
</View>
);
}
from IsolationForest
用于不平衡数据时,如果你检查sklearn
,可以看出confusion_matrix
将多数(正常)类视为正类,而次要类应该是欺诈/异常值/异常检测任务中的positive class。
为了克服这一挑战,有两种解决方案:
IsolationForest
代替 FP
和 FN
代替 TP
。通常 IF 对异常值返回 -1,对内部值返回 1,因此如果在 TN
的输出中将 1 替换为 -1,然后将 -1 替换为 1,那么您可以在此正确使用标准度量计算案例。
IsolationForest
考虑到混淆矩阵 documentation 和问题定义 here,上述技巧应该可以工作,并且是基于文献 Ref.1 的欺诈/异常值/异常检测或二元分类器的混淆矩阵的正确形式, Ref.2、Ref.3 如下:
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
+----------------------------+---------------+--------------+
| | 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)