目录

1. 基本结构

第一层:Base Learners / Level-0 Models

第二层:Meta Learner / Level-1 Model

2. Stacking 的核心流程

第一步:划分 K 折

第二步:生成 OOF 预测

第三步:训练元模型

第四步:预测测试集

3. Stacking 框架示意

4. sklearn 实现示例:分类任务

5. 回归任务示例

6. 关键注意点

1. 必须防止数据泄漏

2. 基模型要有差异性

3. 元模型不要太复杂

4. 分类任务优先使用概率输出

7. Stacking 与 Bagging、Boosting 的区别

8. 适合使用 Stacking 的场景

Stacking(堆叠泛化)是一种集成学习框架,核心思想是:
先训练多个不同的基础模型,再把这些模型的预测结果作为新的特征,交给一个二层模型学习如何组合它们。


1. 基本结构

Stacking 通常分为两层:

第一层:Base Learners / Level-0 Models

这一层包含多个基础模型,例如:

Logistic Regression

Random Forest​​​​​​​

XGBoost / LightGBM​​​​​​​

SVM​​​​​​​

KNN​​​​​​​

Neural Network

它们分别对同一份训练数据进行学习。

第二层:Meta Learner / Level-1 Model

第二层模型不直接使用原始特征,而是使用第一层模型的预测结果作为输入。

例如:

样本

模型A预测

模型B预测

模型C预测

真实标签

x1

0.72

0.66

0.81

1

x2

0.21

0.35

0.18

0

然后用这些预测值训练一个元模型,例如 Logistic Regression、Ridge、XGBoost 等。


2. Stacking 的核心流程

假设有训练集 X_train, y_train 和测试集 X_test。

第一步:划分 K 折

将训练集分成 K 份,例如 5 折。

第二步:生成 OOF 预测

OOF 指 Out-of-Fold Prediction

对每个基础模型:

用 K-1 折训练模型;​​​​​​​

用剩下的 1 折预测;​​​​​​​

重复 K 次;​​​​​​​

得到每个训练样本的“非自身训练模型”预测结果。

这样可以避免数据泄漏。

第三步:训练元模型

将所有基础模型的 OOF 预测拼接成新的训练集:

meta_train = [

    model_1_oof,

    model_2_oof,

    model_3_oof,

    ...

]

然后训练元模型:

meta_model.fit(meta_train, y_train)

第四步:预测测试集

每个基础模型对测试集进行预测,得到:

meta_test = [

    model_1_test_pred,

    model_2_test_pred,

    model_3_test_pred,

    ...

]

最后:

final_pred = meta_model.predict(meta_test)


3. Stacking 框架示意

原始特征 X

   │

   ├── 模型 1:Random Forest

   ├── 模型 2:XGBoost

   ├── 模型 3:SVM

   └── 模型 4:Logistic Regression

          │

          ▼

各模型预测结果

[pred1, pred2, pred3, pred4]

          │

          ▼

元模型 Meta Learner

          │

          ▼

最终预测结果


4. sklearn 实现示例:分类任务

from sklearn.datasets import load_breast_cancer

from sklearn.model_selection import train_test_split

from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier, StackingClassifier

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC

from sklearn.metrics import accuracy_score

# 数据

X, y = load_breast_cancer(return_X_y=True)

X_train, X_test, y_train, y_test = train_test_split(

    X, y, test_size=0.2, random_state=42

)

# 第一层基础模型

base_models = [

    ("rf", RandomForestClassifier(n_estimators=100, random_state=42)),

    ("gbdt", GradientBoostingClassifier(random_state=42)),

    ("svc", SVC(probability=True, random_state=42))

]

# 第二层元模型

meta_model = LogisticRegression()

# Stacking 模型

stacking_model = StackingClassifier(

    estimators=base_models,

    final_estimator=meta_model,

    cv=5,

    stack_method="predict_proba"

)

# 训练

stacking_model.fit(X_train, y_train)

# 预测

y_pred = stacking_model.predict(X_test)

# 评估

print("Accuracy:", accuracy_score(y_test, y_pred))

from sklearn.datasets import load_breast_cancer

from sklearn.model_selection import train_test_split

from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier, StackingClassifier

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC

from sklearn.metrics import accuracy_score

# 数据

X, y = load_breast_cancer(return_X_y=True)

X_train, X_test, y_train, y_test = train_test_split(

    X, y, test_size=0.2, random_state=42

)

# 第一层基础模型

base_models = [

    ("rf", RandomForestClassifier(n_estimators=100, random_state=42)),

    ("gbdt", GradientBoostingClassifier(random_state=42)),

    ("svc", SVC(probability=True, random_state=42))

]

# 第二层元模型

meta_model = LogisticRegression()

# Stacking 模型

stacking_model = StackingClassifier(

    estimators=base_models,

    final_estimator=meta_model,

    cv=5,

    stack_method="predict_proba"

)

# 训练

stacking_model.fit(X_train, y_train)

# 预测

y_pred = stacking_model.predict(X_test)

# 评估

print("Accuracy:", accuracy_score(y_test, y_pred))

5. 回归任务示例

from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, StackingRegressor

from sklearn.linear_model import Ridge

from sklearn.svm import SVR

base_models = [

    ("rf", RandomForestRegressor(n_estimators=100, random_state=42)),

    ("gbr", GradientBoostingRegressor(random_state=42)),

    ("svr", SVR())

]

meta_model = Ridge()

stacking_regressor = StackingRegressor(

    estimators=base_models,

    final_estimator=meta_model,

    cv=5

)

from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, StackingRegressor

from sklearn.linear_model import Ridge

from sklearn.svm import SVR

base_models = [

    ("rf", RandomForestRegressor(n_estimators=100, random_state=42)),

    ("gbr", GradientBoostingRegressor(random_state=42)),

    ("svr", SVR())

]

meta_model = Ridge()

stacking_regressor = StackingRegressor(

    estimators=base_models,

    final_estimator=meta_model,

    cv=5

)

6. 关键注意点

1. 必须防止数据泄漏

元模型不能直接使用基础模型在自身训练样本上的预测结果。
应该使用 K 折 OOF 预测。

2. 基模型要有差异性

Stacking 的效果依赖模型之间的互补性。

比较好的组合是:

线性模型 + 树模型 + 核方法 + 神经网络

如果所有模型都很相似,Stacking 提升有限。

3. 元模型不要太复杂

元模型常用:

Logistic Regression​​​​​​​

Linear Regression​​​​​​​

Ridge​​​​​​​

Lasso

LightGBM​​​​​​​

XGBoost

数据量较小时,推荐用简单模型,避免过拟合。

4. 分类任务优先使用概率输出

分类任务中,通常使用:

predict_proba()

而不是:

predict()

因为概率信息比类别标签更丰富。

7. Stacking 与 Bagging、Boosting 的区别

方法

核心思想

代表算法

Bagging

多个模型并行训练,降低方差

Random Forest

Boosting

模型串行训练,逐步纠错

AdaBoost, XGBoost, LightGBM

Stacking

多模型预测结果再学习组合方式

StackingClassifier

8. 适合使用 Stacking 的场景

Stacking 适合:

比赛建模,如 Kaggle、天池;​​​​​​​

单模型效果已接近瓶颈;​​​​​​​

数据量较充足;​​​​​​​

不同模型表现互补;​​​​​​​

追求更高预测精度。

不太适合:

数据量很小;​​​​​​​

模型解释性要求极高;​​​​​​​

训练时间非常受限;​​​​​​​

基模型之间高度相似。

一句话总结:

Stacking 是一种“让模型学习如何组合多个模型”的集成学习方法,关键在于用 OOF 预测训练元模型,避免数据泄漏。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐