
在机器学习中,集成学习(Ensemble Learning)是通过将多个学习器的预测结果结合起来,从而提升模型的性能。集成方法有很多种,其中 堆叠集成(Stacking Ensemble) 是一种非常强大且灵活的集成方法,它通过将多个模型的输出作为特征输入到下一级模型中,从而让最终模型做出更准确的预测。
本文将详细介绍多层堆叠集成模型的概念、原理、优缺点,并结合具体代码示例帮助大家更好地理解如何实现和使用堆叠集成。

堆叠集成(Stacking,简称Stacking)是一种通过训练多个不同的基学习器(Base Learners),然后再将这些基学习器的预测结果作为新特征,交给一个新的学习器(称为元学习器,Meta Learner)进行训练的集成方法。堆叠集成可以看作是一个层叠结构,其中每一层包含一个或多个模型。
堆叠集成模型一般分为两层:
在传统的堆叠集成中,我们只使用两层:基模型层和元模型层。但在多层堆叠集成中,我们通过增加更多的“中间层”模型,形成一个更加深度的堆叠结构。每一层都使用上一层的预测结果作为输入特征,直到最终通过最顶层的元模型得到最终的预测结果。
我们来看一个简单的多层堆叠集成模型的实现。下面是基于Python的代码示例,演示了如何利用sklearn和optuna库实现多层堆叠集成。
from sklearn.model_selection import KFold
from sklearn.metrics import mean_squared_error
import numpy as np
import optuna
import lightgbm as lgb
import xgboost as xgb
from catboost import CatBoostRegressor
from sklearn.linear_model import LinearRegression
from sklearn.base import clone
class StackingEnsemble:
def __init__(self, base_models, meta_models, n_layers=2, n_splits=5):
"""
多层堆叠集成模型
参数:
base_models: 基模型列表(第一层)
meta_models: 元模型列表(后续各层)
n_layers: 堆叠层数
n_splits: K折交叉验证数
"""
self.base_models = base_models
self.meta_models = meta_models
self.n_layers = n_layers
self.n_splits = n_splits
self.layers = []
def _generate_oof(self, X, y, models, test_data=None, layer_idx=0):
"""生成堆叠特征"""
kf = KFold(n_splits=self.n_splits, shuffle=True, random_state=42)
oof_train = np.zeros((X.shape[0], len(models))) # 训练集的OOF预测
oof_test = np.zeros((test_data.shape[0], len(models))) if test_data is not None else None
# 对每个模型进行交叉验证训练
for model_idx, model in enumerate(models):
model_oof_train = np.zeros(X.shape[0]) # 每个模型对训练集的预测
model_oof_test = np.zeros(test_data.shape[0]) if test_data is not None else None
for fold_idx, (train_idx, val_idx) in enumerate(kf.split(X)):
X_train, y_train = X.iloc[train_idx], y.iloc[train_idx]
X_val = X.iloc[val_idx]
# 克隆模型以避免参数污染
cloned_model = clone_model(model, layer_idx, fold_idx)
cloned_model.fit(X_train, y_train)
# 在验证集上预测,并更新训练集的OOF值
model_oof_train[val_idx] = cloned_model.predict(X_val)
# 如果有测试集,进行预测并平均
if test_data is not None:
model_oof_test += cloned_model.predict(test_data)
# 平均测试集预测
if test_data is not None:
model_oof_test /= self.n_splits
oof_train[:, model_idx] = model_oof_train
if test_data is not None:
oof_test[:, model_idx] = model_oof_test
return oof_train, oof_test
def fit_predict(self, X_train, y_train, X_test):
"""多层堆叠处理"""
current_X_train = X_train.copy() # 当前层的训练集
current_X_test = X_test.copy() # 当前层的测试集
# 逐层训练
for layer in range(self.n_layers):
print(f"Training Layer {layer+1}/{self.n_layers}")
# 第一层使用基模型
if layer == 0:
models = self.base_models
else:
models = self.meta_models
# 生成堆叠特征
oof_train, oof_test = self._generate_oof(
current_X_train, y_train,
models,
test_data=current_X_test,
layer_idx=layer
)
# 保存当前层结果
self.layers.append({
'train': oof_train,
'test': oof_test
})
# 更新下一层输入
current_X_train = np.hstack([current_X_train, oof_train])
current_X_test = np.hstack([current_X_test, oof_test])
return current_X_train, current_X_test
def clone_model(model, layer_idx, fold_idx):
"""克隆模型并设置随机种子"""
params = model.get_params() # 获取模型的参数
if 'random_state' in params:
params['random_state'] = 42 + layer_idx * 100 + fold_idx
return model.__class__(**params)StackingEnsemble类:
__init__:初始化堆叠集成模型,接受基模型(base_models)、元模型(meta_models)、堆叠层数(n_layers)以及K折交叉验证次数(n_splits)。fit_predict:用于训练多层堆叠集成模型,返回最终的训练集和测试集的堆叠特征。_generate_oof:用于生成堆叠特征(即Out-of-Fold特征),每个基模型对训练集进行K折交叉验证,并生成其在验证集上的预测结果,这些预测结果将作为下一层的输入特征。clone_model函数:用于克隆模型,确保每个模型在不同的交叉验证折中使用不同的随机种子,从而避免参数污染,保证每个模型的训练独立性。
如果我们已经使用Optuna等方法调优了三个模型(LGBM、XGBoost和CatBoost),并希望使用多层堆叠集成进行组合。
if __name__ == "__main__":
# 初始化基模型(使用优化后的参数)
lgb_model = lgb.LGBMRegressor(**best_lgb)
xgb_model = xgb.XGBRegressor(**best_xgb)
cat_model = CatBoostRegressor(**best_cat)
# 定义多层堆叠结构
ensemble = StackingEnsemble(
base_models=[lgb_model, xgb_model, cat_model], # 第一层模型
meta_models=[ # 后续层模型(可不同)
lgb.LGBMRegressor(),
xgb.XGBRegressor(),
CatBoostRegressor(verbose=False),
LinearRegression() # 添加线性模型作为元模型
],
n_layers=3, # 总层数(包含基模型层)
n_splits=5 # K折交叉验证数
)
# 使用堆叠集成进行训练和预测
X_train_stack, X_test_stack = ensemble.fit_predict(X_train, y_train, X_test)多层堆叠集成模型是一种非常强大的集成学习方法,它通过多层次的模型训练,不仅能够结合多个模型的优势,还能通过复杂的层次结构进一步提升预测性能。虽然它在计算上比较消耗资源,但它对于高维度、复杂问题有着非常好的表现。如果你有多个不同类型的模型,并且想要最大化它们的性能,堆叠集成无疑是一个非常有效的选择。