Bootstrap 聚合(或 Bagging)是一种集成方法,其中每个模型都在训练数据集的不同样本上进行训练。
Bagging 的思想可以推广到其他用于改变训练数据集并在每个改变后的数据版本上拟合相同模型的技术。一种方法是使用数据转换来改变输入变量的尺度和概率分布,作为训练 Bagging 类似集成的组成成员的基础。我们可以将其称为数据转换 Bagging 或数据转换集成。
在本教程中,您将学习如何开发数据转换集成。
完成本教程后,您将了解:
- 数据转换可以用作 Bagging 类型集成的基础,其中相同的模型在训练数据集的不同视图上进行训练。
- 如何开发用于分类的数据转换集成,并确认该集成表现优于任何组成成员。
- 如何开发和评估用于回归预测建模的数据转换集成。
使用我的新书《使用 Python 的集成学习算法》启动您的项目,其中包括所有示例的分步教程和 Python 源代码文件。
让我们开始吧。

使用不同数据转换开发 Bagging 集成
图片来自 Maciej Kraus,保留部分权利。
教程概述
本教程分为三个部分;它们是:
- 数据转换 Bagging
- 用于分类的数据转换集成
- 用于回归的数据转换集成
数据转换 Bagging
Bootstrap 聚合,简称 Bagging,是一种集成学习技术,其思想是在相同训练数据集的多个不同样本上拟合相同类型的模型。
希望用于拟合每个模型的训练数据集中的微小差异会导致模型能力上的微小差异。对于集成学习,这被称为集成成员的多样性,旨在消除每个组成成员所做预测(或预测误差)之间的相关性。
尽管它最初是为决策树设计的,并且每个数据样本都使用 bootstrap 方法(有放回抽样)生成,但该方法催生了一个拥有数百种变体的研究子领域。
我们可以通过以新颖独特的方式改变用于训练每个组成成员的数据集来构建我们自己的 Bagging 集成。
一种方法是对每个组成集成成员的数据集应用不同的数据准备转换。
这基于这样的前提:我们无法知道训练数据集的表示形式能够将未知的底层结构暴露给学习算法。这促使需要使用一系列不同的数据转换(例如改变尺度和概率分布)来评估模型,以发现哪些有效。
这种方法可以用于创建相同训练数据集的一系列不同转换,在每个转换上训练一个模型,并使用简单统计量(例如平均值)组合预测。
由于没有更好的名称,我们将此称为“数据转换 Bagging”或“数据转换集成”。
我们可以使用许多转换,但一个好的起点可能是一些改变尺度和概率分布的转换,例如
当与基于数据转换效果训练不同或非常不同的模型的基础模型一起使用时,这种方法可能更有效。
改变分布的尺度可能只适用于对输入变量尺度变化敏感的模型,例如计算加权和的模型(如逻辑回归和神经网络),以及使用距离度量的模型(如 k-最近邻和支持向量机)。
输入变量概率分布的变化可能会影响大多数机器学习模型。
现在我们熟悉了这种方法,接下来我们探讨如何为分类问题开发数据转换集成。
想开始学习集成学习吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
用于分类的数据转换集成
我们可以使用 scikit-learn 库开发用于分类的 Bagging 数据转换方法。
该库提供了一套可以直接使用的标准转换。每个集成成员都可以定义为管道,其中转换后跟着预测模型,以避免任何数据泄露,进而产生乐观的结果。最后,可以使用投票集成来组合来自每个管道的预测。
首先,我们可以定义一个合成二元分类数据集作为探索这种类型集成的基础。
下面的示例创建了一个包含 1,000 个示例的数据集,每个示例包含 20 个输入特征,其中 15 个特征包含用于预测目标的信息。
1 2 3 4 5 6 |
# 合成分类数据集 from sklearn.datasets import make_classification # 定义数据集 X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=1) # 汇总数据集 print(X.shape, y.shape) |
运行示例将创建数据集并汇总数据数组的形状,验证我们的预期。
1 |
(1000, 20) (1000,) |
接下来,我们使用打算在集成中使用的预测模型来建立问题基线。在 Bagging 集成中使用决策树是标准做法,因此在这种情况下,我们将使用具有默认超参数的 DecisionTreeClassifier。
我们将使用标准实践评估模型,在本例中是重复分层 k 折交叉验证,重复三次,10 折。性能将通过所有折叠和重复的分类准确率的平均值报告。
在合成分类数据集上评估决策树的完整示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 在合成分类数据集上评估决策树 from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.tree import DecisionTreeClassifier # 定义数据集 X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=1) # 定义模型 model = DecisionTreeClassifier() # 定义评估过程 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型 n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1) # 报告表现 print('Mean Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
运行示例将报告决策树在合成分类数据集上的平均分类准确率。
注意:由于算法或评估过程的随机性质,或数值精度差异,您的结果可能会有所不同。请考虑多次运行示例并比较平均结果。
在本例中,我们可以看到模型达到了约 82.3% 的分类准确率。
这个分数提供了一个性能基线,我们期望数据转换集成能够在此基础上有所改进。
1 |
平均准确率:0.823 (0.039) |
接下来,我们可以开发一个决策树集成,每个决策树都在输入数据的不同转换上进行拟合。
首先,我们可以将每个集成成员定义为一个建模管道。第一步是数据转换,第二步是决策树分类器。
例如,使用 MinMaxScaler 类的归一化转换管道如下所示:
1 2 3 |
... # 归一化 norm = Pipeline([('s', MinMaxScaler()), ('m', DecisionTreeClassifier())]) |
我们可以对我们想要使用的每个转换或转换配置重复此操作,并将所有模型管道添加到列表中。
可以使用 VotingClassifier 类来组合所有模型的预测。该类接受一个“estimators”参数,它是一个元组列表,每个元组包含一个名称和模型或建模管道。例如
1 2 3 4 5 6 7 |
... # 归一化 norm = Pipeline([('s', MinMaxScaler()), ('m', DecisionTreeClassifier())]) models.append(('norm', norm)) ... # 定义投票集成 ensemble = VotingClassifier(estimators=models, voting='hard') |
为了使代码更易读,我们可以定义一个函数 `get_ensemble()` 来创建成员和数据转换集成本身。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 获取模型投票集成 def get_ensemble(): # 定义基础模型 models = list() # 归一化 norm = Pipeline([('s', MinMaxScaler()), ('m', DecisionTreeClassifier())]) models.append(('norm', norm)) # 标准化 std = Pipeline([('s', StandardScaler()), ('m', DecisionTreeClassifier())]) models.append(('std', std)) # 鲁棒性 robust = Pipeline([('s', RobustScaler()), ('m', DecisionTreeClassifier())]) models.append(('robust', robust)) # 幂变换 power = Pipeline([('s', PowerTransformer()), ('m', DecisionTreeClassifier())]) models.append(('power', power)) # 分位数 quant = Pipeline([('s', QuantileTransformer(n_quantiles=100, output_distribution='normal')), ('m', DecisionTreeClassifier())]) models.append(('quant', quant)) # kbins kbins = Pipeline([('s', KBinsDiscretizer(n_bins=20, encode='ordinal')), ('m', DecisionTreeClassifier())]) models.append(('kbins', kbins)) # 定义投票集成 ensemble = VotingClassifier(estimators=models, voting='hard') return ensemble |
然后,我们可以像上面对决策树所做的那样,调用此函数并正常评估投票集成。
将这些结合起来,完整的示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# 在分类数据集上评估数据转换 Bagging 集成 from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold 从 sklearn.预处理 导入 MinMaxScaler from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import RobustScaler from sklearn.preprocessing import PowerTransformer from sklearn.preprocessing import QuantileTransformer from sklearn.preprocessing import KBinsDiscretizer from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import VotingClassifier from sklearn.pipeline import Pipeline # 获取模型投票集成 def get_ensemble(): # 定义基础模型 models = list() # 归一化 norm = Pipeline([('s', MinMaxScaler()), ('m', DecisionTreeClassifier())]) models.append(('norm', norm)) # 标准化 std = Pipeline([('s', StandardScaler()), ('m', DecisionTreeClassifier())]) models.append(('std', std)) # 鲁棒性 robust = Pipeline([('s', RobustScaler()), ('m', DecisionTreeClassifier())]) models.append(('robust', robust)) # 幂变换 power = Pipeline([('s', PowerTransformer()), ('m', DecisionTreeClassifier())]) models.append(('power', power)) # 分位数 quant = Pipeline([('s', QuantileTransformer(n_quantiles=100, output_distribution='normal')), ('m', DecisionTreeClassifier())]) models.append(('quant', quant)) # kbins kbins = Pipeline([('s', KBinsDiscretizer(n_bins=20, encode='ordinal')), ('m', DecisionTreeClassifier())]) models.append(('kbins', kbins)) # 定义投票集成 ensemble = VotingClassifier(estimators=models, voting='hard') return ensemble # 定义数据集 X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=1) # 获取模型 ensemble = get_ensemble() # 定义评估过程 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型 n_scores = cross_val_score(ensemble, X, y, scoring='accuracy', cv=cv, n_jobs=-1) # 报告表现 print('Mean Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
运行示例将报告数据转换集成在合成分类数据集上的平均分类准确率。
注意:由于算法或评估过程的随机性质,或数值精度差异,您的结果可能会有所不同。请考虑多次运行示例并比较平均结果。
在本例中,我们可以看到数据转换集成达到了约 83.8% 的分类准确率,这比单独使用决策树(准确率约为 82.3%)有所提升。
1 |
平均准确率:0.838 (0.042) |
尽管集成模型比单个决策树表现良好,但此测试的一个局限性在于我们不知道集成模型是否比任何单个组成成员表现更好。
这很重要,因为如果集成模型的某个组成成员表现更好,那么使用该成员本身作为模型将比使用集成模型更简单、更容易。
我们可以通过评估每个独立模型的性能并将结果与集成模型进行比较来检查这一点。
首先,我们可以更新 `get_ensemble()` 函数,使其返回一个模型列表,该列表由各个集成成员以及集成模型本身组成,以便进行评估。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# 获取模型投票集成 def get_ensemble(): # 定义基础模型 models = list() # 归一化 norm = Pipeline([('s', MinMaxScaler()), ('m', DecisionTreeClassifier())]) models.append(('norm', norm)) # 标准化 std = Pipeline([('s', StandardScaler()), ('m', DecisionTreeClassifier())]) models.append(('std', std)) # 鲁棒性 robust = Pipeline([('s', RobustScaler()), ('m', DecisionTreeClassifier())]) models.append(('robust', robust)) # 幂变换 power = Pipeline([('s', PowerTransformer()), ('m', DecisionTreeClassifier())]) models.append(('power', power)) # 分位数 quant = Pipeline([('s', QuantileTransformer(n_quantiles=100, output_distribution='normal')), ('m', DecisionTreeClassifier())]) models.append(('quant', quant)) # kbins kbins = Pipeline([('s', KBinsDiscretizer(n_bins=20, encode='ordinal')), ('m', DecisionTreeClassifier())]) models.append(('kbins', kbins)) # 定义投票集成 ensemble = VotingClassifier(estimators=models, voting='hard') # 返回一个元组列表,每个元组包含一个名称和一个模型 return models + [('ensemble', ensemble)] |
我们可以调用此函数并枚举每个模型,评估它,报告性能,并存储结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... # 获取模型 models = get_ensemble() # 评估每个模型 results = list() for name,model in models: # 定义评估方法 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # 在数据集上评估模型 n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1) # 报告性能 print('>%s: %.3f (%.3f)' % (name, mean(n_scores), std(n_scores))) results.append(n_scores) |
最后,我们可以并排绘制准确度分数的箱线图,并直接比较分数分布。
从视觉上看,我们希望集成模型的得分分布偏高,并且分布的中心趋势(均值和中位数)也高于任何单个成员。
1 2 3 4 |
... # 绘制结果以进行比较 pyplot.boxplot(results, labels=[n for n,_ in models], showmeans=True) pyplot.show() |
将这些结合起来,数据转换集成与每个组成成员的分类性能比较的完整示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# 数据转换集成与每个组成成员的分类比较 from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold 从 sklearn.预处理 导入 MinMaxScaler from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import RobustScaler from sklearn.preprocessing import PowerTransformer from sklearn.preprocessing import QuantileTransformer from sklearn.preprocessing import KBinsDiscretizer from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import VotingClassifier from sklearn.pipeline import Pipeline from matplotlib import pyplot # 获取模型投票集成 def get_ensemble(): # 定义基础模型 models = list() # 归一化 norm = Pipeline([('s', MinMaxScaler()), ('m', DecisionTreeClassifier())]) models.append(('norm', norm)) # 标准化 std = Pipeline([('s', StandardScaler()), ('m', DecisionTreeClassifier())]) models.append(('std', std)) # 鲁棒性 robust = Pipeline([('s', RobustScaler()), ('m', DecisionTreeClassifier())]) models.append(('robust', robust)) # 幂变换 power = Pipeline([('s', PowerTransformer()), ('m', DecisionTreeClassifier())]) models.append(('power', power)) # 分位数 quant = Pipeline([('s', QuantileTransformer(n_quantiles=100, output_distribution='normal')), ('m', DecisionTreeClassifier())]) models.append(('quant', quant)) # kbins kbins = Pipeline([('s', KBinsDiscretizer(n_bins=20, encode='ordinal')), ('m', DecisionTreeClassifier())]) models.append(('kbins', kbins)) # 定义投票集成 ensemble = VotingClassifier(estimators=models, voting='hard') # 返回一个元组列表,每个元组包含一个名称和一个模型 return models + [('ensemble', ensemble)] # 定义数据集 X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=1) # 获取模型 models = get_ensemble() # 评估每个模型 results = list() for name,model in models: # 定义评估方法 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # 在数据集上评估模型 n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1) # 报告性能 print('>%s: %.3f (%.3f)' % (name, mean(n_scores), std(n_scores))) results.append(n_scores) # 绘制结果以进行比较 pyplot.boxplot(results, labels=[n for n,_ in models], showmeans=True) pyplot.show() |
运行示例首先报告每个单独模型的平均分类准确率和标准差,最后是组合模型的集成性能。
注意:由于算法或评估过程的随机性质,或数值精度差异,您的结果可能会有所不同。请考虑多次运行示例并比较平均结果。
在这种情况下,我们可以看到许多单个成员表现良好,例如“_kbins_”达到了约 83.3% 的准确率,而“_std_”达到了约 83.1% 的准确率。我们还可以看到集成模型与任何组成成员相比,整体性能更好,准确率约为 83.4%。
1 2 3 4 5 6 7 |
> norm: 0.821 (0.041) > std: 0.831 (0.045) > robust: 0.826 (0.044) > power: 0.825 (0.045) > quant: 0.817 (0.042) > kbins: 0.833 (0.035) > ensemble: 0.834 (0.040) |
还创建了一个图,显示了每个单独模型以及数据转换集成的分类准确率的箱线图。
我们可以看到集成模型的分布向上倾斜,这是我们所希望的,并且均值(绿色三角形)略高于单个集成成员的均值。

个体模型和数据转换集成的准确率分布箱线图
现在我们已经熟悉了如何为分类开发数据转换集成,接下来我们看看如何为回归做同样的事情。
用于回归的数据转换集成
在本节中,我们将探讨为回归预测建模问题开发数据转换集成。
首先,我们可以定义一个合成二元回归数据集作为探索这种类型集成的基础。
下面的示例创建了一个包含 1,000 个示例的数据集,每个示例包含 100 个输入特征,其中 10 个包含用于预测目标的信息。
1 2 3 4 5 6 |
# 合成回归数据集 from sklearn.datasets import make_regression # 定义数据集 X, y = make_regression(n_samples=1000, n_features=100, n_informative=10, noise=0.1, random_state=1) # 汇总数据集 print(X.shape, y.shape) |
运行示例将创建数据集并确认数据具有预期的形状。
1 |
(1000, 100) (1000,) |
接下来,我们可以通过拟合和评估我们打算在集成中使用的基础模型(在本例中为 DecisionTreeRegressor)来建立合成数据集的性能基线。
该模型将使用重复的 k 折交叉验证进行评估,重复三次,共 10 折。数据集上的模型性能将使用平均绝对误差 (MAE) 进行报告。scikit-learn 会反转分数(使其变为负数),以便框架可以最大化分数。因此,我们可以忽略分数上的符号。
下面的示例评估了合成回归数据集上的决策树。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 在合成回归数据集上评估决策树 from numpy import mean from numpy import std from sklearn.datasets import make_regression from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedKFold from sklearn.tree import DecisionTreeRegressor # 定义数据集 X, y = make_regression(n_samples=1000, n_features=100, n_informative=10, noise=0.1, random_state=1) # 定义模型 模型 = DecisionTreeRegressor() # 定义评估过程 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型 n_scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1) # 报告表现 print('MAE: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
运行示例将报告决策树在合成回归数据集上的 MAE。
注意:由于算法或评估过程的随机性质,或数值精度差异,您的结果可能会有所不同。请考虑多次运行示例并比较平均结果。
在本例中,我们可以看到模型达到了约 139.817 的 MAE。这提供了一个性能下限,我们期望集成模型在此基础上有所改进。
1 |
MAE: -139.817 (12.449) |
接下来,我们可以开发和评估集成模型。
我们将使用上一节中的相同数据转换。VotingRegressor 将用于组合预测,这适用于回归问题。
下面定义的 get_ensemble() 函数创建了单个模型和集成模型,并将所有模型组合成一个元组列表以供评估。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# 获取模型投票集成 def get_ensemble(): # 定义基础模型 models = list() # 归一化 norm = Pipeline([('s', MinMaxScaler()), ('m', DecisionTreeRegressor())]) models.append(('norm', norm)) # 标准化 std = Pipeline([('s', StandardScaler()) , ('m', DecisionTreeRegressor())]) models.append(('std', std)) # 鲁棒性 robust = Pipeline([('s', RobustScaler()) , ('m', DecisionTreeRegressor())]) models.append(('robust', robust)) # 幂变换 power = Pipeline([('s', PowerTransformer()) , ('m', DecisionTreeRegressor())]) models.append(('power', power)) # 分位数 quant = Pipeline([('s', QuantileTransformer(n_quantiles=100, output_distribution='normal')) , ('m', DecisionTreeRegressor())]) models.append(('quant', quant)) # kbins kbins = Pipeline([('s', KBinsDiscretizer(n_bins=20, encode='ordinal')) , ('m', DecisionTreeRegressor())]) models.append(('kbins', kbins)) # 定义投票集成 ensemble = VotingRegressor(estimators=models) # 返回一个元组列表,每个元组包含一个名称和一个模型 return models + [('ensemble', ensemble)] |
然后,我们可以调用此函数并独立评估每个贡献的建模管道,并将结果与管道集成进行比较。
我们的期望,和以前一样,是集成模型在性能上比任何单个模型都有提升。如果不是,则应选择性能最佳的单个模型。
将这些结合起来,评估回归数据集的数据转换集成的完整示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# 数据转换集成与每个组成成员的回归比较 from numpy import mean from numpy import std from sklearn.datasets import make_regression from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedKFold 从 sklearn.预处理 导入 MinMaxScaler from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import RobustScaler from sklearn.preprocessing import PowerTransformer from sklearn.preprocessing import QuantileTransformer from sklearn.preprocessing import KBinsDiscretizer 来自 sklearn.tree 导入 DecisionTreeRegressor from sklearn.ensemble import VotingRegressor from sklearn.pipeline import Pipeline from matplotlib import pyplot # 获取模型投票集成 def get_ensemble(): # 定义基础模型 models = list() # 归一化 norm = Pipeline([('s', MinMaxScaler()), ('m', DecisionTreeRegressor())]) models.append(('norm', norm)) # 标准化 std = Pipeline([('s', StandardScaler()) , ('m', DecisionTreeRegressor())]) models.append(('std', std)) # 鲁棒性 robust = Pipeline([('s', RobustScaler()) , ('m', DecisionTreeRegressor())]) models.append(('robust', robust)) # 幂变换 power = Pipeline([('s', PowerTransformer()) , ('m', DecisionTreeRegressor())]) models.append(('power', power)) # 分位数 quant = Pipeline([('s', QuantileTransformer(n_quantiles=100, output_distribution='normal')) , ('m', DecisionTreeRegressor())]) models.append(('quant', quant)) # kbins kbins = Pipeline([('s', KBinsDiscretizer(n_bins=20, encode='ordinal')) , ('m', DecisionTreeRegressor())]) models.append(('kbins', kbins)) # 定义投票集成 ensemble = VotingRegressor(estimators=models) # 返回一个元组列表,每个元组包含一个名称和一个模型 return models + [('ensemble', ensemble)] # 生成回归数据集 X, y = make_regression(n_samples=1000, n_features=100, n_informative=10, noise=0.1, random_state=1) # 获取模型 models = get_ensemble() # 评估每个模型 results = list() for name,model in models: # 定义评估方法 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 在数据集上评估模型 n_scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1) # 报告性能 print('>%s: %.3f (%.3f)' % (name, mean(n_scores), std(n_scores))) results.append(n_scores) # 绘制结果以进行比较 pyplot.boxplot(results, labels=[n for n,_ in models], showmeans=True) pyplot.show() |
运行示例首先报告每个单独模型的 MAE,最后是组合模型的集成性能。
注意:由于算法或评估过程的随机性质,或数值精度差异,您的结果可能会有所不同。请考虑多次运行示例并比较平均结果。
我们可以看到每个模型的性能大致相同,MAE 误差分数都在 140 左右,都高于单独使用的决策树。有趣的是,集成模型表现最好,优于所有单个成员和未进行任何转换的树,MAE 约为 126.487。
这个结果表明,尽管每个管道的性能都比没有转换的单棵树差,但每个管道都犯了不同的错误,并且这些模型的平均值能够利用和利用这些差异以获得更低的误差。
1 2 3 4 5 6 7 |
>norm: -140.559 (11.783) >std: -140.582 (11.996) >robust: -140.813 (11.827) >power: -141.089 (12.668) >quant: -141.109 (11.097) >kbins: -145.134 (11.638) >ensemble: -126.487 (9.999) |
一个图表被创建,比较了每个管道和集成的 MAE 分布。
正如我们所希望的,集成模型的分布比所有其他模型都向上倾斜,并且具有更高的(更小的)中心趋势(均值和中位数分别由绿色三角形和橙色线表示)。

个体模型和数据转换集成的 MAE 分布箱线图
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
教程
书籍
- 使用集成方法进行模式分类, 2010.
- 集成方法, 2012.
- 集成机器学习, 2012.
API
总结
在本教程中,您学习了如何开发数据转换集成。
具体来说,你学到了:
- 数据转换可以用作 Bagging 类型集成的基础,其中相同的模型在训练数据集的不同视图上进行训练。
- 如何开发用于分类的数据转换集成,并确认该集成表现优于任何组成成员。
- 如何开发和评估用于回归预测建模的数据转换集成。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
我们能否将其用于特征数量较少的序列预测(回归)问题
我看不出为什么不。
尊敬的Jason博士,
感谢您的教程。
我尝试用住房数据集进行估计器实验,发现 xgboost 回归器在未见数据上取得了最佳结果,而不是决策树。PolynomialFeatures() 作为额外的转换器也提高了分数。
不客气。
干得好!
非常感谢。这太棒了。
不客气!
尊敬的Jason博士
我可以用这种方式来处理我编写的数据转换器吗?
我有股票数据,想用这种方式来处理从数据创建的不同技术指标
你好 Mehdi……理论上没有问题。请澄清您模型的目的,以便我们更好地协助您。