【机器学习】集成学习——Stacking模型融合(理论+图解)

本文涉及的产品
交互式建模 PAI-DSW,每月250计算时 3个月
模型训练 PAI-DLC,100CU*H 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
简介: 【机器学习】集成学习——Stacking模型融合(理论+图解)

2021人工智能领域新星创作者,带你从入门到精通,该博客每天更新,逐渐完善机器学习各个知识体系的文章,帮助大家更高效学习。


一、引言

对于单个模型来说很难拟合复杂的数据,而且对于单模型来说,模型的抗干扰能力较低,所以我们希望可以集成多个模型,结合多个模型的优缺点提高模型的泛化能力。

针对于集成学习一般有两种方式,第一种为Boosting架构,利用基学习器之间串行的方式进行构造强学习器,第二种是Bagging架构,通过构造多个独立的模型,然后通过选举或者加权的方式构造强学习器。

然而还有一种方式就是Stacking,它结合了Boosting和Bagging两种集成方式,它是利用多个基学习器学习原数据,然后将这几个基学习学习到的数据交给第二层模型进行拟合。

说白了就是将第一层模型的输出作为第二层模型的输入。

二、Stacking集成模型

1.Stacking原理

所谓的Stacking就是通过模型对原数据拟合的堆叠进行建模,他首先通过基学习器学习原数据,然后这几个基学习器都会对原数据进行输出,然后将这几个模型的输出按照列的方式进行堆叠,构成了 ( m , p ) (m,p)(m,p) 维的新数据,m代表样本数,p代表基学习器的个数,然后将新的样本数据交给第二层模型进行拟合。

上幅图就是Stacking思想的原理示意图,但是有些时候网上看到的图会有切分训练集和验证集,那是为了防止模型过拟合,所以使用K折交叉验证,没有一次全部训练。

上图的意思就是首先将特征x和标签y分别输入到3个模型中,然后这3个模型分别学习,然后针对于x给出预测值,有时也会给出proba概率,这里我们使用预测值,然后将3个模型的输出值按照列的防止进行堆叠,这就形成了新的样本数据,然后将新的样本数据作为标签x,新数据的标签仍然为原数据的标签y,将新数据的x,y交给第二层的模型进行拟合,这个模型是用来融合前一轮3个模型结果的。

但是这样模型往往会过拟合,所以将上述方法进行改进,使用K折交叉验证的方式,不同的地方就是上面的示意图每个模型训练了所有的数据,然后输出y形成新的数据,使用K折交叉验证,每次只训练k-1折,然后将剩下1折的预测值作为新的数据,这就有效的防止了过拟合。

如果每个模型训练所有的数据,然后再用这个模型去预测y值,那么生成新数据的y非常精确和真实值差不多,为了增强模型的泛化能力,我们每次只训练其中一部分数据,然后用剩余一部分数据进行预测。

首先利用K折交叉验证,将数据分成4折切分,那么就会形成4组数据集,其中黄色代表训练集,绿色的为验证集,然后将每组的训练集交给模型进行训练,然后对验证集进行预测,就会得到对应验证集的输出,因为4折交叉验证,将数据分成4组,所以我们会形成4个验证集,然后将每个模型对各自组的验证集预测的结果进行按照行的方式堆叠,就会获得完整样本数据的预测值,这只是针对于一个模型,不同学习器同理,每个模型按照这个方式获得预测值,然后再将其按照列合并。

2.实现代码

import numpy as np
from sklearn.model_selection import KFold
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
class MyStacking:
    # 初始化模型参数
    def __init__(self, estimators, final_estimator, cv=5, method='predict'):
        self.cv = cv
        self.method = method
        self.estimators = estimators
        self.final_estimator = final_estimator
    # 模型训练
    def fit(self, X, y):
        # 获得一级输出
        dataset_train = self.stacking(X, y)
        # 模型融合
        self.final_estimator.fit(dataset_train, y)
    # 堆叠输出
    def stacking(self, X, y):
        kf = KFold(n_splits=self.cv, shuffle=True, random_state=2021)
        # 获得一级输出
        dataset_train = np.zeros((X.shape[0], len(self.estimators)))
        for i, model in enumerate(self.estimators):
            for (train, val) in kf.split(X, y):
                X_train = X[train]
                X_val = X[val]
                y_train = y[train]
                y_val_pred = model.fit(X_train, y_train).predict(X_val)
                dataset_train[val, i] = y_val_pred
            self.estimators[i] = model
        return dataset_train
    # 模型预测
    def predict(self, X):
        datasets_test = np.zeros((X.shape[0], len(self.estimators)))
        for i, model in enumerate(self.estimators):
            datasets_test[:, i] = model.predict(X)
        return self.final_estimator.predict(datasets_test)
    # 模型精度
    def score(self, X, y):
        datasets_test = np.zeros((X.shape[0], len(self.estimators)))
        for i, model in enumerate(self.estimators):
            datasets_test[:, i] = model.predict(X)
        return self.final_estimator.score(datasets_test, y)
if __name__ == '__main__':
    X, y = load_iris(return_X_y=True)
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, train_size=0.7, random_state=0)
    estimators = [
        RandomForestClassifier(n_estimators=10),
        GradientBoostingClassifier(n_estimators=10)
    ]
    clf = MyStacking(estimators=estimators,
                     final_estimator=LogisticRegression())
    clf.fit(X_train, y_train)
    print(clf.score(X_train, y_train))
    print(clf.score(X_test, y_test))


目录
相关文章
|
6月前
|
机器学习/深度学习 Python
堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能
本文深入探讨了堆叠集成策略的原理、实现方法及Python应用。堆叠通过多层模型组合,先用不同基础模型生成预测,再用元学习器整合这些预测,提升模型性能。文章详细介绍了堆叠的实现步骤,包括数据准备、基础模型训练、新训练集构建及元学习器训练,并讨论了其优缺点。
353 3
|
7月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
923 1
|
7月前
|
Java Spring
springboot 学习十一:Spring Boot 优雅的集成 Lombok
这篇文章是关于如何在Spring Boot项目中集成Lombok,以简化JavaBean的编写,避免冗余代码,并提供了相关的配置步骤和常用注解的介绍。
273 0
|
7月前
|
机器学习/深度学习 算法 前端开发
集成学习任务七和八、投票法与bagging学习
集成学习任务七和八、投票法与bagging学习
116 0
|
7月前
|
Java Maven Docker
gitlab-ci 集成 k3s 部署spring boot 应用
gitlab-ci 集成 k3s 部署spring boot 应用
|
6月前
|
消息中间件 监控 Java
您是否已集成 Spring Boot 与 ActiveMQ?
您是否已集成 Spring Boot 与 ActiveMQ?
222 0
|
10月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
392 6
|
10月前
|
Java 关系型数据库 MySQL
如何实现Springboot+camunda+mysql的集成
【7月更文挑战第2天】集成Spring Boot、Camunda和MySQL的简要步骤: 1. 初始化Spring Boot项目,添加Camunda和MySQL驱动依赖。 2. 配置`application.properties`,包括数据库URL、用户名和密码。 3. 设置Camunda引擎属性,指定数据源。 4. 引入流程定义文件(如`.bpmn`)。 5. 创建服务处理流程操作,创建控制器接收请求。 6. Camunda自动在数据库创建表结构。 7. 启动应用,测试流程启动,如通过服务和控制器开始流程实例。 示例代码包括服务类启动流程实例及控制器接口。实际集成需按业务需求调整。
644 4
|
10月前
|
消息中间件 Java 测试技术
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
【RocketMQ系列八】SpringBoot集成RocketMQ-实现普通消息和事务消息
651 1
|
11月前
|
消息中间件 Java Kafka
springboot集成kafka
springboot集成kafka
260 2

热门文章

最新文章

相关产品

  • 人工智能平台 PAI