BootstrapOutOfBag:scikit-learn 兼容版本的袋外自助法

袋外自助法的实现,用于评估监督学习算法。

from mlxtend.evaluate import BootstrapOutOfBag

概述

最初,自助法的目的是在底层分布未知且没有额外样本可用时,确定估计器的统计属性。现在,为了利用此方法评估预测模型(例如用于分类和回归的假设),我们可能偏向于使用所谓的袋外 (OOB) 或留一法自助 (LOOB) 技术对自助法稍作修改。在此,我们使用袋外样本作为测试集进行评估,而不是在训练数据上评估模型。袋外样本是未用于模型拟合的独特实例集合,如下图 [1] 所示。

上图说明了如何从一个示例性的十样本数据集()中抽取三个随机自助样本及其用于测试的袋外样本可能是什么样子。实际上,Bradley Efron 和 Robert Tibshirani 建议抽取 50 到 200 个自助样本,认为这足以获得可靠的估计 [2]。

参考文献

  • [1] https://sebastianraschka.com/blog/2016/model-evaluation-selection-part2.html
  • [2] Efron, Bradley, and Robert J. Tibshirani. An introduction to the bootstrap. CRC press, 1994. Management of Data (ACM SIGMOD '97), pages 265-276, 1997.

示例 1 -- 评估模型的预测性能

BootstrapOutOfBag 类模仿了 scikit-learn 交叉验证类(例如 KFold)的行为

from mlxtend.evaluate import BootstrapOutOfBag
import numpy as np


oob = BootstrapOutOfBag(n_splits=3)
for train, test in oob.split(np.array([1, 2, 3, 4, 5])):
    print(train, test)
[4 2 1 3 3] [0]
[2 4 1 2 1] [0 3]
[4 3 3 4 1] [0 2]

因此,我们可以通过 cross_val_score 方法使用 BootstrapOutOfBag 对象

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score

iris = load_iris()
X = iris.data
y = iris.target
lr = LogisticRegression()

print(cross_val_score(lr, X, y))
[ 0.96078431  0.92156863  0.95833333]
print(cross_val_score(lr, X, y, cv=BootstrapOutOfBag(n_splits=3, random_seed=456)))
[ 0.92727273  0.96226415  0.94444444]

实际上,建议运行至少 200 次迭代,尽管

print('Mean accuracy: %.1f%%' % np.mean(100*cross_val_score(
    lr, X, y, cv=BootstrapOutOfBag(n_splits=200, random_seed=456))))
Mean accuracy: 94.8%

使用自助法,我们可以使用百分位数法计算性能估计的置信区间。我们选择上下置信区间如下:

  • = 的百分位数分布
  • = 的百分位数分布

其中,以及用于计算置信区间的置信度。例如,要计算 95% 的置信区间,我们选择,以获取 b 个自助样本分布的第 2.5 个和第 97.5 个百分位数作为上下置信区间。

import matplotlib.pyplot as plt
%matplotlib inline
accuracies = cross_val_score(lr, X, y, cv=BootstrapOutOfBag(n_splits=1000, random_seed=456))
mean = np.mean(accuracies)

lower = np.percentile(accuracies, 2.5)
upper = np.percentile(accuracies, 97.5)

fig, ax = plt.subplots(figsize=(8, 4))
ax.vlines(mean, [0], 40, lw=2.5, linestyle='-', label='mean')
ax.vlines(lower, [0], 15, lw=2.5, linestyle='-.', label='CI95 percentile')
ax.vlines(upper, [0], 15, lw=2.5, linestyle='-.')

ax.hist(accuracies, bins=11,
        color='#0080ff', edgecolor="none", 
        alpha=0.3)
plt.legend(loc='upper left')



plt.show()

png

API

BootstrapOutOfBag(n_splits=200, random_seed=None)

参数

  • n_splits : int (默认值=200)

    自助法迭代次数。必须大于 1。

  • random_seed : int (默认值=None)

    如果为 int,则 random_seed 是随机数生成器使用的种子。

返回值

  • train_idx : ndarray

    该分割的训练集索引。

  • test_idx : ndarray

    该分割的测试集索引。

示例

有关使用示例,请参阅 https://mlxtend.cn/mlxtend/user_guide/evaluate/BootstrapOutOfBag/

方法


get_n_splits(X=None, y=None, groups=None)

返回交叉验证器中的分割迭代次数

参数

  • X : object

    始终被忽略,存在是为了与 scikit-learn 兼容。

  • y : object

    始终被忽略,存在是为了与 scikit-learn 兼容。

  • groups : object

    始终被忽略,存在是为了与 scikit-learn 兼容。

返回值

  • n_splits : int

    返回交叉验证器中的分割迭代次数。


split(X, y=None, groups=None)

y : 类数组或 None (默认值: None) 参数未使用,仅作为参数包含以实现兼容性,类似于 scikit-learn 中的 KFold

  • groups : 类数组或 None (默认值: None)

    参数未使用,仅作为参数包含以实现兼容性,类似于 scikit-learn 中的 KFold