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()
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
。