我正在尝试重现与此类似的灵敏度特异性图: 其中X轴是阈值
但我还没有找到如何去做,一些 skalern 指标如 ROC 曲线返回真阳性和假阳性,但我还没有找到任何选项来制作这个图。
我正在尝试将概率与实际标签进行比较以保持计数,我得到的情节是这样的:
因此 X 标签必须标准化,这样曲线才能真正上下移动。
最佳答案
我不认为该情节显示了您认为它显示的内容。随着阈值降至零,灵敏度将接近 1,因为 100% 的观察值将被归类为阳性,假阴性率将降至零。同样,当阈值接近 1 时,选择性将接近 1,因为每个观察结果都将被归类为阴性,误报率将为零。所以这个图没有显示灵敏度或选择性。
要在 x 轴上绘制选择性和灵敏度作为阈值的函数,我们可以使用内置的 ROC 功能并从中提取值以我们自己的方式绘制它们。给定二进制标签向量 test_y
、相关预测变量矩阵 test_x
和适合的 RandomForestClassifier
对象 rfc
:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import precision_score, recall_score
# Get the estimated probabilities of each observation being categorized as positive
# [:,1] for probabilities of negative
predicted_y_probs = rfc.predict_proba(test_x)[:,0]
thresholds = np.linspace(0,1,20) # or however many points you want
sensitivities = [recall_score(test_y, predicted_y_probs >= t) for t in thresholds]
selectivities = [precision_score(test_y, predicted_y_probs >= t) for t in thresholds]
plt.plot(thresholds, sensitivies, label='sensitivity')
plt.plot(thresholds, selectivities, label='selectivity')
plt.legend()
但是,这将不会重新创建您作为引用提供的图,它似乎显示了每个观察被归类为正的估计概率的分布。换句话说,该图中的阈值是一个常数,x 轴向我们显示每个预测相对于该(固定)阈值的位置。它没有直接告诉我们灵敏度或选择性。如果您真的想要这样的情节,请继续阅读。
我想不出重建这些平滑曲线的方法,因为密度图会延伸到零以下和 1 以上,但我们可以使用直方图显示信息。使用与之前相同的变量:
# Specify range to ensure both groups show up the same width.
bins = np.linspace(0,1,10)
# Show distributions of estimated probabilities for the two classes.
plt.hist(predicted_y_probs[test_y == 1], alpha=0.5, color='red', label='positive', bins=bins)
plt.hist(predicted_y_probs[test_y == 0], alpha=0.5, color='green', label='negative', bins=bins)
# Show the threshold.
plt.axvline(0.5, c='black', ls='dashed')
# Add labels
plt.legend()
我只使用三个物种中的两个物种为经典 Iris 数据集运行此代码,并获得以下输出。 Versicolor 是“阳性”,viriginica 是“阴性”,而 setosa 被忽略以产生二元分类。请注意,我的模型具有完美的召回率,因此云芝的所有概率都非常接近 1.0。由于只有 100 个样本,其中大部分都被正确分类,因此它相当 block 状,但希望它能理解这个想法。
关于python - 灵敏度特异性图 python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57280577/