首页 > 解决方案 > 理解 Python 的 roc_curve、svm 例子

问题描述

我试图从概念上理解这个 Python 代码是如何工作的,所以我可以写一篇关于它的论文。我对随机森林算法有一个类似的问题;但也许如果我明白这一点,我也会明白这一点。这只是我认为与我的问题相关的部分:

from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import roc_curve, auc
from numpy import interp
statifiedFolds = StratifiedKFold(n_splits=5, shuffle=True)
tprs = []
aucs = []
mean_fpr = np.linspace(0, 1, 100)
i = 1

for train,test in statifiedFolds.split(x,y):

    svc = SVC(kernel = 'rbf', C = 10000, gamma = 0.1)
    x_train, x_test = x[train], x[test]
    y_train, y_test = y[train], y[test]
    svc.fit(x_train, y_train)
    y_pred = svc.decision_function(x_test)
    fpr, tpr, thresholds = roc_curve(y_test,y_pred)
    tprs.append(interp(mean_fpr, fpr, tpr))
    tprs[-1][0] = 0.0
    roc_auc = auc(fpr, tpr)
    aucs.append(roc_auc)
    i += 1

mean_tpr = np.mean(tprs, axis=0)
mean_tpr[-1] = 1.0
mean_auc = auc(mean_fpr, mean_tpr)

据我了解,ROC 曲线绘制了假阳性率与真阳性率。但是每次在测试集上运行 SVM 时,都会为每个测试点获得一个二进制预测。然后,您通过计算真阳性和假阳性来计算真阳性率和假阳性率。所以 tpr 应该只是一个数字,fpr 也应该是一个数字。因此 (tpr,fpr) 应该只是一个点。

这使我期望要获得 roc 曲线,应该在许多不同的参数下运行分类算法。如果幸运的话,该算法将有一个参数,使得较大的值往往会以牺牲特异性为代价来提高灵敏度,或者相反。但是 SVM 的参数(C 和 gamma)都没有做到这一点。所以我会认为你必须尝试许多 C 和 gamma 值,直到 roc 曲线的左、中和右区域都得到很好的表示。

但是这段代码看起来不像那样。只有一对参数值(C=10000,gamma = 0.1)被调用。并且 svm 只运行一次,然后在 5 折交叉验证的每一折中调用一个插值函数。

我的问题是:如何仅使用 1 个点对 roc 曲线进行插值?

标签: svmroc

解决方案


这种推理的错误在于svc.decision_function(x_test)没有返回二进制数据。

它实际上返回一个(有符号)值,与样本 X 到分离超平面的距离成正比。因此,您可以通过在默认值 0 附近调整阈值来绘制适当的 roc 曲线。

注意:有关详细信息,请参阅参考文档svc.decision_function根据.decision_function_shapesvc


推荐阅读