孤立森林的ROC曲线

4

我正在尝试绘制ROC曲线以评估孤立森林算法在乳腺癌数据集上的准确性。我从混淆矩阵中计算了真阳性率(TPR)和假阳性率(FPR)。然而,我不理解TPR和FPR为什么是矩阵形式,而不是单个整数值。此外,ROC曲线似乎只能使用矩阵形式的FPR和TPR(我也尝试手动编写计算FPR和TPR的代码)。

TPR和FPR的值是否总是以矩阵形式出现?

无论如何,我的ROC曲线呈直线。为什么会这样呢?

混淆矩阵:

from sklearn.metrics import confusion_matrix
cnf_matrix = confusion_matrix(y, y_pred_test1)

输出:
>     [[  5  25]
>      [ 21 180]]

真正例和假正例:(此外,为什么这些值直接从混淆矩阵中取出?)
F_P = cnf_matrix.sum(axis=0) - np.diag(cnf_matrix)  
F_N = cnf_matrix.sum(axis=1) - np.diag(cnf_matrix)
T_P = np.diag(cnf_matrix)
T_N = cnf_matrix.sum() - (FP + FN + TP)

F_P = F_P.astype(float)
F_N = F_N.astype(float)
T_P = T_P.astype(float)
T_N = T_N.astype(float)

输出:

False Positive [21. 25.] 
False Negative [25. 21.] 
True Positive [  5. 180.] 
True Negative [180.   5.]

TPR 和 FPR:

tp_rate = TP/(TP+FN)
fp_rate = FP/(FP+TN)

输出:
TPR :  [0.16666667 0.89552239]
FPR [0.10447761 0.83333333]

ROC 曲线:

from sklearn import metrics
import matplotlib.pyplot as plt

plt.plot(fp_rate,tp_rate)
plt.show()

O/P:

图片描述在此输入


这是一个关于IT技术的图片,您可以点击链接查看。

当你说矩阵时,你是想说列表/数组吗?而且在图上有两个点时,它总是一条直线... - Frayal
1
有一个可能会有帮助的事情是查看内置的sklearn roc_curve函数。您会注意到输出是fpr,tpr,thresh,也就是说,对于每个阈值,您都会得到真正和假正的比率,而不仅仅是整个预测器的比率。 - G. Anderson
3个回答

4

confusion_matrix()函数只提供正确/错误分类的点,但不提供模型在误分类数据点时的置信度信息。

这些信息用于创建ROC曲线(用于衡量模型根据其对特定类别的可能性对每个数据点进行排名的能力)。

相反,使用decision_function()score_samples()函数来计算模型对每个数据点是(或不是)异常的置信度。然后,使用roc_curve()获取绘制曲线所需的点。

以下是乳腺癌数据集的示例。

from sklearn.datasets import load_breast_cancer
X, y  = load_breast_cancer(return_X_y=True)
# to make malignant as ones
y = (y == 0).astype(int)
from sklearn.ensemble import IsolationForest

clf = IsolationForest(max_samples=100,
                        random_state=0, contamination='auto')
clf.fit(X)
y_pred = clf.score_samples(X)

from sklearn.metrics import roc_curve
fpr, tpr, thresholds = roc_curve(y,y_pred)
import matplotlib.pyplot as plt
plt.plot(fpr, tpr, 'k-', lw=2)
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()

enter image description here


y_pred需要被取反(孤立森林特定问题),并且还需要添加pos_label=0(乳腺癌数据集特定问题)。请参见我的答案:https://dev59.com/T7Lma4cB1Zd3GeqPa3F6#75721259。现在ROC曲线沿着[0,1; 1;0]对角线翻转。 - qertoip

2
混淆矩阵本质上给出了ROC曲线上的一个点。要构建完整的ROC曲线,您需要一个概率列表,然后可以通过改变用于确定类预测的“阈值”来确定每个实例属于哪个类,并绘制ROC曲线。
在您的简单情况下(当您只有ROC曲线上的一个点时),您可以通过外推到原点和点(1,1)来绘制ROC曲线。
# compare to your confusion matrix to see values.
TP = 180
FN = 21

tpr = TP/(TP+FN)
fpr = 1-tpr

tpr_line = [0, tpr, 1]
fpr_line = [0, fpr 1]

plt.plot(fpr, tpr, 'k-', lw=2)
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.xlim(0, 1)
plt.ylim(0, 1)

并且ROC曲线如下图所示:

example_single_point_roc_curve

最初的回答。


1

对于IsolationForest的ROC曲线,每个人似乎都会给出错误的答案。这是因为decision_function/score_samples返回与人们期望的相反的值(这里命中/阳性是低值,阴性是高值)。这使得ROC翻转。

你必须对decision_function/score_samples的结果进行否定,才能得到正确的ROC

此外,对于这个特定的数据集(breast_cancer),还需要将阳性标签设置为0。

请注意,这两个问题在最佳答案中是不相关的,而且彼此并不能抵消。

正确和错误ROC的比较:

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import IsolationForest
from sklearn.metrics import roc_curve
import matplotlib.pyplot as plt

X, y = load_breast_cancer(return_X_y=True)

clf = IsolationForest(max_samples=100,
                      random_state=0, contamination='auto')
clf.fit(X)
y_pred = clf.score_samples(X)

fpr_wrong, tpr_wrong, _ = roc_curve(y, y_pred)
fpr_correct, tpr_correct, _ = roc_curve(y, -y_pred, pos_label=0)

plt.plot(fpr_correct, tpr_correct, 'green', lw=1)
plt.plot(fpr_wrong, tpr_wrong, 'red', lw=1)
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接