- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想比较 Python 中不同的二元分类器。为此,我想计算 ROC AUC 分数、测量 95% 置信区间 (CI) 和 p 值 以访问统计信息意义。
下面是 scikit-learn 中的一个最小示例,它在二元分类数据集上训练三个不同的模型,绘制 ROC 曲线并计算 AUC 分数。
以下是我的具体问题:
.
import numpy as np
np.random.seed(2018)
from sklearn.datasets import load_breast_cancer
from sklearn.metrics import roc_auc_score, roc_curve
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier
import matplotlib
import matplotlib.pyplot as plt
data = load_breast_cancer()
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=17)
# Naive Bayes Classifier
nb_clf = GaussianNB()
nb_clf.fit(X_train, y_train)
nb_prediction_proba = nb_clf.predict_proba(X_test)[:, 1]
# Ranodm Forest Classifier
rf_clf = RandomForestClassifier(n_estimators=20)
rf_clf.fit(X_train, y_train)
rf_prediction_proba = rf_clf.predict_proba(X_test)[:, 1]
# Multi-layer Perceptron Classifier
mlp_clf = MLPClassifier(alpha=1, hidden_layer_sizes=150)
mlp_clf.fit(X_train, y_train)
mlp_prediction_proba = mlp_clf.predict_proba(X_test)[:, 1]
def roc_curve_and_score(y_test, pred_proba):
fpr, tpr, _ = roc_curve(y_test.ravel(), pred_proba.ravel())
roc_auc = roc_auc_score(y_test.ravel(), pred_proba.ravel())
return fpr, tpr, roc_auc
plt.figure(figsize=(8, 6))
matplotlib.rcParams.update({'font.size': 14})
plt.grid()
fpr, tpr, roc_auc = roc_curve_and_score(y_test, rf_prediction_proba)
plt.plot(fpr, tpr, color='darkorange', lw=2,
label='ROC AUC={0:.3f}'.format(roc_auc))
fpr, tpr, roc_auc = roc_curve_and_score(y_test, nb_prediction_proba)
plt.plot(fpr, tpr, color='green', lw=2,
label='ROC AUC={0:.3f}'.format(roc_auc))
fpr, tpr, roc_auc = roc_curve_and_score(y_test, mlp_prediction_proba)
plt.plot(fpr, tpr, color='crimson', lw=2,
label='ROC AUC={0:.3f}'.format(roc_auc))
plt.plot([0, 1], [0, 1], color='navy', lw=1, linestyle='--')
plt.legend(loc="lower right")
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('1 - Specificity')
plt.ylabel('Sensitivity')
plt.show()
最佳答案
您想对数据的多次重采样重复分析。在一般情况下,假设您有一个函数 f(x)
可以从数据 x
中确定您需要的任何统计信息,并且您可以像这样引导:
def bootstrap(x, f, nsamples=1000):
stats = [f(x[np.random.randint(x.shape[0], size=x.shape[0])]) for _ in range(nsamples)]
return np.percentile(stats, (2.5, 97.5))
这会为您提供 95% 置信区间的所谓插件估计(即,您只需采用 bootstrap 分布的百分位数)。
在你的情况下,你可以像这样编写一个更具体的函数
def bootstrap_auc(clf, X_train, y_train, X_test, y_test, nsamples=1000):
auc_values = []
for b in range(nsamples):
idx = np.random.randint(X_train.shape[0], size=X_train.shape[0])
clf.fit(X_train[idx], y_train[idx])
pred = clf.predict_proba(X_test)[:, 1]
roc_auc = roc_auc_score(y_test.ravel(), pred.ravel())
auc_values.append(roc_auc)
return np.percentile(auc_values, (2.5, 97.5))
这里,clf
是你想要测试性能的分类器,X_train
, y_train
, X_test
,y_test
就像在您的代码中一样。
这给了我以下置信区间(四舍五入到三位数,1000 个 bootstrap 样本):
从技术上讲,排列测试会遍历您的观察序列的所有排列,并使用排列后的目标值评估您的 roc 曲线(特征未排列)。如果你有一些观察,这没问题,但如果你有更多的观察,它就会变得非常昂贵。因此,对排列的数量进行子采样并简单地进行一些随机排列是很常见的。在这里,实现更多地取决于您要测试的具体内容。以下函数为您的 roc_auc 值执行此操作
def permutation_test(clf, X_train, y_train, X_test, y_test, nsamples=1000):
idx1 = np.arange(X_train.shape[0])
idx2 = np.arange(X_test.shape[0])
auc_values = np.empty(nsamples)
for b in range(nsamples):
np.random.shuffle(idx1) # Shuffles in-place
np.random.shuffle(idx2)
clf.fit(X_train, y_train[idx1])
pred = clf.predict_proba(X_test)[:, 1]
roc_auc = roc_auc_score(y_test[idx2].ravel(), pred.ravel())
auc_values[b] = roc_auc
clf.fit(X_train, y_train)
pred = clf.predict_proba(X_test)[:, 1]
roc_auc = roc_auc_score(y_test.ravel(), pred.ravel())
return roc_auc, np.mean(auc_values >= roc_auc)
此函数再次将您的分类器作为 clf
并返回未改组数据的 AUC 值和 p 值(即观察到的 AUC 值大于或等于您在未打乱的数据)。
用 1000 个样本运行此程序,所有三个分类器的 p 值为 0。请注意,由于采样的原因,这些并不准确,但它们表明所有这些分类器的性能都优于偶然性。
这就容易多了。给定两个分类器,您可以预测每个观察结果。您只需像这样在预测和分类器之间打乱分配
def permutation_test_between_clfs(y_test, pred_proba_1, pred_proba_2, nsamples=1000):
auc_differences = []
auc1 = roc_auc_score(y_test.ravel(), pred_proba_1.ravel())
auc2 = roc_auc_score(y_test.ravel(), pred_proba_2.ravel())
observed_difference = auc1 - auc2
for _ in range(nsamples):
mask = np.random.randint(2, size=len(pred_proba_1.ravel()))
p1 = np.where(mask, pred_proba_1.ravel(), pred_proba_2.ravel())
p2 = np.where(mask, pred_proba_2.ravel(), pred_proba_1.ravel())
auc1 = roc_auc_score(y_test.ravel(), p1)
auc2 = roc_auc_score(y_test.ravel(), p2)
auc_differences.append(auc1 - auc2)
return observed_difference, np.mean(auc_differences >= observed_difference)
通过这个测试和 1000 个样本,我发现三个分类器之间没有显着差异:
其中 diff 表示两个分类器之间的 roc 曲线差异,p(diff>) 是在打乱的数据集上观察到较大差异的经验概率。
关于python - 如何比较不同二元分类器的 ROC AUC 分数并评估 Python 中的统计显着性? (p 值,置信区间),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52373318/
我在 Mac OsX 10.11 上使用 Xcode 7.0.1 (7A1001) 我使用 carthage 0.9.2 通过以下购物车文件下载reactivecocoa github“Reactiv
我正在将一个对象从属性“模型”(我从 Laravel 中的 Blade 属性模型中获得)分配给数据属性模型。后来数据属性模型发生变化,因为它绑定(bind)到表单输入字段。但 Prop “模型”也发生
当我更新数组内对象的属性然后作为组件的 Prop 传递时,在 svelte 中触发 react 性的正确方法是什么? let items = [{ id: 1, name: 'first'
我是 DRY principle 的坚定拥护者: Every piece of knowledge must have a single, unambiguous, authoritative rep
我正在实现一个需要以下功能的线程: 及时响应终止请求 推送消息 在等待消息时保持对 SendMessage 请求的响应 我对消息泵的初始实现使用了 GetMessage,如下所示: while not
在我的应用程序中,用户获得了一份已到达她的文档列表,并且可以对每个文档执行操作。 文件是分批提交的,当这种情况发生时,列表会增加。这一切都很好,这是预期的行为,但最好有一个按钮“暂停实时数据”,它会忽
我有一个属性为 的数据对象 displaySubtotal 我可以通过以下方式更新该属性的值: data.displaySubtotal = numPad.valueAsAString(); 我的方法
我需要一个垂直 slider 输入。由于内置的 sliderInput 函数无法做到这一点,因此我选择自己实现。根据this thread可以 (I) 使用 CSS 旋转 sliderInput
我正在从自定义用户权限管理系统迁移到 Alanning:roles v2.0 .我有一个非常基本的结构: 基本用户 用户组,每个用户组都有特定的设置。我将它们存储在一个“组”集合中。 管理群组的用户的
Shiny 中的响应式(Reactive)表达式将更改传播到需要去的地方。我们可以使用 isolate 来抑制一些这种行为。 ,但是我们可以抑制基于我们自己的逻辑表达式传播的更改吗? 我给出的例子是一
是否有(或可能有) react 性 Parsec (或任何其他纯函数式解析器)在 Haskell 中? 简而言之,我想逐个字符地为解析器提供数据,并获得与我提供的足够多的结果一样多的结果。 或者更简单
HTML(JADE) p#result Lorem ipsum is javascript j s lo 1 2 4 this meteor thismeteor. meteor input.sear
我有一个被导入函数更改的对象。 https://svelte.dev/repl/e934087af1dc4a25a1ee52cf3fd3bbea?version=3.12.1 我想知道如何使我的更改反
我有一个YUV 420半平面格式的图像,其中字节以这种方式存储: [Y1 Y2 ... [U1 V1.... Yk Yk+1...] Uk' Uk'+1] 其中Y平面的大小是UV平面的两倍,并
如何使用 ReactiveCocoa 订阅从 NSMutableDictionary 添加和删除的对象?另外,我想在它发生变化时广播通知。我的猜测是可以使用 RACMulticastConnectio
我正在构建一个带有多个选项卡的应用程序,其中一些选项卡涉及过多的计算,而另一些选项卡的计算速度很快。一个允许用户在 react 性或手动更新之间进行选择的复选框,与“刷新”按钮结合使用,将是理想的选择
我知道您可以在获取集合时使用 reactive: false 关闭 react 性。如何在内容可编辑区域内的集合字段中实现相同的效果?示例: Template.documentPage.events(
我想在 z3 中表示一个哈希函数,比如 SHA(x)。在做了一些研究之后,似乎 z3 不能很好地支持注入(inject)性,所以我不能有像这样的约束(虽然我意识到这并不是严格意义上的碰撞,但作为一种启
我正在解决一个问题,我想在仪表板中将数据显示为图表(通过 perak:c3 )和表格(通过 aslagle:reactive-table )。我的问题是数据是从 MongoDB 中的集合中提取的,它的
我的 ViewModel 中有这个函数,它返回一个信号,但内部 block 不起作用,我尝试添加断点,但它没有中断。这是我的代码。 func executeLoginAPI() -> RACSigna
我是一名优秀的程序员,十分优秀!