Stacking(堆叠泛化) 简介
目录
第一层:Base Learners / Level-0 Models
第二层:Meta Learner / Level-1 Model
7. Stacking 与 Bagging、Boosting 的区别
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 预测训练元模型,避免数据泄漏。




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


所有评论(0)