#集成学习#:bagging、boosting、stacking和blending

news2024/9/29 18:09:51

集成学习是一种机器学习方法,旨在提高单个模型的性能和鲁棒性。它基于这样一个假设:通过结合多个模型的预测结果,可以获得更好的预测性能,因为每个模型都可能从数据中提取不同的信息,因此他们的错误也可能是不同的,通过整合他们的预测结果可以减少这种错误的影响。

集成学习可以分为两类:bagging和boosting。

Bagging:是bootstrap aggregating的缩写,即自举汇聚法。它通过从原始数据集中进行有放回的随机抽样来创建多个训练集,每个训练集都用于训练一个独立的模型。这些模型的预测结果被组合起来,例如通过平均,以生成最终的集成模型的预测结果。Bagging可以用于降低模型方差,因为通过使用不同的训练集训练多个模型,我们可以减少模型对特定训练集的敏感性。

  1. Boosting:是一种迭代算法,它通过逐步改善模型的预测能力来构建一个强大的集成模型。每个迭代的模型都是在先前模型的基础上构建的,即每个模型都尝试学习之前模型的错误。通过这种方式,Boosting可以减少模型偏差,因为它们能够逐步拟合训练数据中更复杂的模式。

  2. 除了Bagging和Boosting,还有其他类型的集成学习方法,例如Stacking和Blending。Stacking通过训练多个不同类型的基本模型,并使用第二个元模型(或叫做“超级学习器”)来组合它们的预测结果。Blending是一种类似于Stacking的技术,它在训练数据集上训练多个不同的模型,并使用一个加权平均来组合它们的预测结果。

集成学习可以提高预测性能和鲁棒性,但需要更多的计算资源和时间。它适用于大型数据集和需要高度精确的预测的情况。

使用pytorch分别实现bagging、boosting、stacking和blending

下面是使用PyTorch实现集成学习的例子:

首先,我们需要准备数据。这里我们使用PyTorch的MNIST数据集作为例子。我们将训练集和测试集分别加载进来:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms

# 定义数据转换
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

# 加载数据集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)

# 定义数据加载器
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)

接下来,我们可以定义基本模型,这里使用简单的卷积神经网络:

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.dropout = nn.Dropout2d()
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = nn.functional.relu(nn.functional.max_pool2d(x, 2))
        x = self.conv2(x)
        x = nn.functional.relu(nn.functional.max_pool2d(self.dropout(x), 2))
        x = x.view(-1, 320)
        x = nn.functional.relu(self.fc1(x))
        x = self.dropout(x)
        x = self.fc2(x)
        return nn.functional.log_softmax(x, dim=1)

现在,我们可以使用这个基本模型来构建集成学习模型。

bagging

首先是Bagging。在Bagging中,我们通过随机抽样训练集数据来构建多个基本模型。每个模型都是独立训练的,我们可以将它们的预测结果平均得到集成模型的输出。

# Bagging
n_models = 5
models = []
for i in range(n_models):
    model = CNN()
    optimizer = optim.Adam(model.parameters(), lr=0.01)
    criterion = nn.CrossEntropyLoss()
    for epoch in range(10):
        for batch_idx, (data, target) in enumerate(train_loader):
            optimizer.zero_grad()
            output = model(data)
            loss = criterion(output, target)
            loss.backward()
            optimizer.step()
    models.append(model)

# 预测
def bagging_predict(models, data):
    outputs = torch.zeros(data.shape[0], 10)
    for model in models:
        output = torch.exp(model(data))
        outputs += output
    return outputs.argmax(dim=1)

# 评估
correct = 0
total = 0
with torch.no_grad():
    for data, target in test_loader:
        outputs = bagging_predict(models, data)
        total += target.size(0)
        correct += (outputs == target).sum().item()
print(f"Accuracy: {100 * correct / total:.2f}%")

boosting

下一步是Boosting。在Boosting中,我们构建多个基本模型,每个模型都在前一个模型训练的基础上进行训练。每个模型的训练都会依据之前模型的预测结果进行加权,以便更好地捕获错误分类的样本。

# Boosting
n_models = 5
models = []
train_dataset_boost = list(train_dataset)
for i in range(n_models):
    model = CNN()
    optimizer = optim.Adam(model.parameters(), lr=0.01)
    criterion = nn.CrossEntropyLoss()
    for epoch in range(10):
        for batch_idx, (data, target) in enumerate(train_loader):
            if i == 0:
                weights = torch.ones(len(train_dataset))
            else:
                outputs = torch.exp(models[-1](data))
                weights = torch.zeros(len(train_dataset))
                for j, (d, t) in enumerate(train_dataset_boost):
                    if t == outputs.argmax(dim=1)[j]:
                        weights[j] = 1 / (outputs[j][t] + 1e-6)
            weights = weights / weights.sum()
            sampler = torch.utils.data.sampler.WeightedRandomSampler(weights, len(weights), replacement=True)
            train_loader_boost = torch.utils.data.DataLoader(train_dataset_boost, batch_size=64, sampler=sampler)
            optimizer.zero_grad()
            output = model(data)
            loss = criterion(output, target)
            loss.backward()
            optimizer.step()
    models.append(model)

    # 更新训练集权重
    outputs = torch.exp(model(torch.stack([d for d, t in train_dataset_boost])))
    weights = torch.zeros(len(train_dataset))
    for j, (d, t) in enumerate(train_dataset_boost):
        if t == outputs.argmax(dim=1)[j]:
            weights[j] = 1 / (outputs[j][t] + 1e-6)
    weights = weights / weights.sum()
    train_dataset_boost = list(zip(train_dataset, weights))
    train_dataset_boost = [(d, t, w) for (d, t), w in train_dataset_boost]

# 预测
def boosting_predict(models, data):
    outputs = torch.zeros(data.shape[0], 10)
    for model in models:
        output = torch.exp(model(data))
        outputs += output
    return outputs.argmax(dim=1)

# 评估
correct = 0
total = 0
with torch.no_grad():
    for data, target in test_loader:
        outputs = boosting_predict(models, data)
        total += target.size(0)
        correct += (outputs == target).sum().item()
print(f"Accuracy: {100 * correct / total:.2f}%")

stacking

下一个集成方法是Stacking。在Stacking中,我们首先将训练集分成两部分,第一部分用于训练一组基本模型,第二部分用于为最终模型生成预测。对于第一部分,我们使用多个基本模型对其进行训练。对于第二部分,我们使用第一部分的基本模型的预测结果来训练一个最终的元模型,该元模型将基本模型的预测结果作为输入,并输出最终的预测结果。

# Stacking
n_models = 5
models = []
train_dataset_base, train_dataset_meta = torch.utils.data.random_split(train_dataset, [50000, 10000])
for i in range(n_models):
    model = CNN()
    optimizer = optim.Adam(model.parameters(), lr=0.01)
    criterion = nn.CrossEntropyLoss()
    for epoch in range(10):
        for batch_idx, (data, target) in enumerate(train_loader):
            optimizer.zero_grad()
            output = model(data)
            loss = criterion(output, target)
            loss.backward()
            optimizer.step()
    models.append(model)

# 构建元数据集
meta_data = []
with torch.no_grad():
    for data, target in train_loader:
        outputs = []
        for model in models:
            outputs.append(model(data))
        outputs = torch.stack(outputs, dim=1)
        meta_data.append((outputs, target))

# 构建元模型
class MetaModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(5*10, 100)
        self.fc2 = nn.Linear(100, 10)

    def forward(self, x):
        x = x.view(x.shape[0], -1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

meta_model = MetaModel()
optimizer = optim.Adam(meta_model.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss()

# 元训练
for epoch in range(10):
    for data, target in meta_data:
        optimizer.zero_grad()
        output = meta_model(data.view(data.shape[0], -1))
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

# 预测
def stacking_predict(models, meta_model, data):
    outputs = []
    with torch.no_grad():
        for model in models:
            output = model(data)
            outputs.append(output)
        outputs = torch.stack(outputs, dim=1)
        meta_output = meta_model(outputs.view(outputs.shape[0], -1))
    return meta_output.argmax(dim=1)

# 评估
correct = 0
total = 0
with torch.no_grad():
    for data, target in test_loader:
        outputs = stacking_predict(models, meta_model, data)
        total += target.size(0)
        correct += (outputs == target).sum().item()
print(f"Accuracy: {100 * correct / total:.2f}%")

blending

最后一个集成方法是Blending。Blending类似于Stacking,但它只使用一部分训练数据进行元模型的训练,而不是使用训练集的全部数据。在Blending中,我们首先将训练集分成两部分,第一部分用于训练多个基本模型,第二部分用于为最终模型生成预测。对于第二部分,我们使用第一部分的基本模型的预测结果来训练一个最终的元模型,该元模型将基本模型的预测结果作为输入,并输出最终的预测结果。

# Blending
n_models = 5
models = []
train_dataset_base, train_dataset_blend = torch.utils.data.random_split(train_dataset, [50000, 10000])
for i in range(n_models):
    model = CNN()
    optimizer = optim.Adam(model.parameters(), lr=0.01)
    criterion = nn.CrossEntropyLoss()
    for epoch in range(10):
        for batch_idx, (data, target) in enumerate(train_loader):
            if batch_idx < len(train_loader) // 2:
                optimizer.zero_grad()
                output = model(data)
                loss = criterion(output, target)
                loss.backward()
                optimizer.step()
            else:
                break
    models.append(model)

# 生成元数据
meta_data = []
with torch.no_grad():
    for data, target in train_loader:
        outputs = []
        for model in models:
            output = model(data)
            outputs.append(output)
        meta_data.append((torch.cat(outputs, dim=1), target))

# 构建元模型
class MetaModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(5*10, 100)
        self.fc2 = nn.Linear(100, 10)

    def forward(self, x):
        x = x.view(x.shape[0], -1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

meta_model = MetaModel()
optimizer = optim.Adam(meta_model.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss()


# 元训练
for epoch in range(10):
    for data, target in meta_data:
        optimizer.zero_grad()
        output = meta_model(data.view(data.shape[0], -1))
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

# 预测
def blending_predict(models, meta_model, data):
    outputs = []
    with torch.no_grad():
        for model in models:
            output = model(data)
            outputs.append(output)
        meta_output = meta_model(torch.cat(outputs, dim=1))
    return meta_output.argmax(dim=1)

# 评估
correct = 0
total = 0
with torch.no_grad():
    for data, target in test_loader:
        outputs = blending_predict(models, meta_model, data)
        total += target.size(0)
        correct += (outputs == target).sum().item()
print(f"Accuracy: {100 * correct / total:.2f}%")

这就是如何使用PyTorch实现Bagging、Boosting、Stacking和Blending的代码示例。这些集成方法是机器学习中非常有用的工具,可以帮助我们提高模型的准确性和稳健性,尤其是在处理大规模、高维度数据时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/373402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年三月份图形化三级打卡试题

活动时间 从2023年3月1日至3月21日&#xff0c;每天一道编程题。 本次打卡的规则如下&#xff1a; 小朋友每天利用10~15分钟做一道编程题&#xff0c;遇到问题就来群内讨论&#xff0c;我来给大家答疑。 小朋友做完题目后&#xff0c;截图到朋友圈打卡并把打卡的截图发到活动群…

Vue 3第三章:模板语法及指令介绍

文章目录1. 插值表达式1.1. 声明变量可直接在模板中使用&#xff0c;采用{{变量名称}}的方式1.2. 模板语法支持三元表达式1.3. 模板语法支持运算1.4. 模板语法支持方法调用2. 指令2.1. v-bind&#xff1a;用于绑定属性或动态绑定对象的值到元素上。2.2. v-if、v-else-if、v-els…

C#学习记录——接口的实现

一小部分知识精英依旧直面核心困难&#xff0c;努力地进行深度钻研&#xff0c;生产内容&#xff1b;而大多数信息受众始终在享受轻度学习&#xff0c;消费内容。如果我们真的希望在时代潮流中占据一席之地&#xff0c;那就应该尽早抛弃轻松学习的幻想&#xff0c;锤炼深度学习…

Burp Suite 常用模块简介

Burp Suite 常用模块分为 目标站点(target)模块 代理(proxy)模块 攻击(Intruder)模块 重放(Repeater) 模块 Target模块是对站点资源的收集&#xff0c;与站点各资源包发出和相应包的记录 Proxy模块是核心模块&#xff0c;可以拦截数据包发送往浏览器&#xff0c;进行修改后再…

网络协议分析(2)判断两个ip数据包是不是同一个数据包分片

一个节点收到两个IP包的首部如下&#xff1a;&#xff08;1&#xff09;45 00 05 dc 18 56 20 00 40 01 bb 12 c0 a8 00 01 c0 a8 00 67&#xff08;2&#xff09;45 00 00 15 18 56 00 b9 49 01 e0 20 c0 a8 00 01 c0 a8 00 67分析并判断这两个IP包是不是同一个数据报的分片&a…

Android JetPack之启动优化StartUp初始化组件的详解和使用

一、背景 先看一下Android系统架构图 在Android设备中&#xff0c;设备先通电&#xff08;PowerManager&#xff09;&#xff0c;然后加载内核层&#xff0c;内核走完&#xff0c;开始检查硬件&#xff0c;以及为硬件提供的公开接口&#xff0c;然后进入到库的加载。库挂载后开…

Winform控件开发(16)——Timer(史上最全)

前言: Timer控件的作用是按用户定义的时间间隔引发事件的计时器,说的直白点就是,他就像一个定时炸弹一样到了一定时间就爆炸一次,区别在于定时炸弹炸完了就不会再次爆炸了,但是Timer这个计时器到了下一个固定时间还会触发一次,上面那张图片就是一个典型的计时器,该定时器…

【Java】Spring Boot 配置文件

文章目录SpringBoot 配置文件1. 配置文件的作用2. 配置文件的格式3. properties配置文件说明3.1 properties基本语法3.2 读取配置文件3.3 properties缺点分析4. yml配置文件说明4.1 yml基本语法4.2 yml使用进阶4.2.1 yml配置不同的数据类型及null4.2.1 yml配置的读取4.2.2 配置…

Python蓝桥杯训练:基本数据结构 [哈希表]

Python蓝桥杯训练&#xff1a;基本数据结构 [哈希表] 文章目录Python蓝桥杯训练&#xff1a;基本数据结构 [哈希表]一、哈希表理论基础知识1、开放寻址法2、链式法二、有关哈希表的一些常见操作三、力扣上面一些有关哈希表的题目练习1、[有效的字母异位词](https://leetcode.cn…

0101基础概念-图-数据结构和算法(Java)

文章目录1 图1.1 定义1.2 4种图模型2 无向图2.1 定义2.2 术语后记1 图 1.1 定义 图是一种非线性的数据结构&#xff0c;表示多对多的关系。 图&#xff08;Graph&#xff09;是由顶点的有穷非空集合和顶点之间边的集合组成&#xff0c;通常表示为&#xff1a;G(V, E)&#xf…

ecology9-谷歌浏览器下-pdf.js在渲染时部分发票丢失文字 问题定位及解决

问题 问题描述 &#xff1a; 在谷歌浏览器下&#xff0c;pdf.js在渲染时部分发票丢失文字&#xff1b;360浏览器兼容模式不存在此问题 排查思路&#xff1a;1、对比谷歌浏览器的css样式和360浏览器兼容模式下的样式&#xff0c;没有发现关键差别 2、✔使用Fiddler修改网页js D…

什么是线程死锁?如何解决死锁问题

死锁&#xff0c;一组互相竞争的资源的线程之间相互等待&#xff0c;导致永久阻塞的现象。 如下图所示&#xff1a; 与死锁对应的&#xff0c;还有活锁&#xff0c;是指线程没有出现阻塞&#xff0c;但是无限循环。 有一个经典的银行转账例子如下&#xff1a; 我们有个账户类…

操作系统权限提升(十四)之绕过UAC提权-基于白名单AutoElevate绕过UAC提权

系列文章 操作系统权限提升(十二)之绕过UAC提权-Windows UAC概述 操作系统权限提升(十三)之绕过UAC提权-MSF和CS绕过UAC提权 注&#xff1a;阅读本编文章前&#xff0c;请先阅读系列文章&#xff0c;以免造成看不懂的情况&#xff01;&#xff01; 基于白名单AutoElevate绕过…

2-MATLAB APP Design-下拉菜单栏的使用

一、APP 界面设计展示 1.新建一个空白的APP,在此次的学习中,我们会用到编辑字段(文本框)、下拉菜单栏、坐标区,首先在界面中拖入一个编辑字段(文本框),在文本框中输入内容:下拉菜单栏的使用,调整背景颜色,字体的颜色为黑色,字体的大小调为26. 2.在左侧组件库常用栏…

Qt音视频开发17-vlc内核回调拿图片进行绘制

一、前言 在众多播放器中&#xff0c;支持的种类格式众多&#xff0c;并支持DVD影音光盘&#xff0c;VCD影音光盘及各类流式协议&#xff0c;提供了sdk进行开发&#xff0c;这点是至关重要的&#xff0c;尽管很多优秀的播放器很牛逼&#xff0c;由于没有提供sdk第三方开发&…

【网络编程套接字(一)】

网络编程套接字&#xff08;一&#xff09;理解源IP地址和目的IP地址理解源MAC地址和目的MAC地址理解源端口号和目的端口号PORT VS PID认识TCP协议和UDP协议网络字节序socket编程接口socket常见APIsockaddr结构简单的UDP网络程序服务端创建套接字服务端绑定字符串IP VS 整数IP客…

面试官: 你知道 JWT、JWE、JWS 、JWK嘛?

想起了 之前做过的 很多 登录授权 的项目 它相比原先的session、cookie来说&#xff0c;更快更安全&#xff0c;跨域也不再是问题&#xff0c;更关键的是更加优雅 &#xff0c;所以今天总结了一篇文章来介绍他 JWT 指JSON Web Token&#xff0c;如果在项目中通过 jjwt 来支持 J…

Springboot整合 Thymeleaf增删改查一篇就够了

很早之前写过Thymeleaf的文章&#xff0c;所以重新温习一下&#xff0c;非前后端分离&#xff0c;仅仅只是学习 官网&#xff1a; https://www.thymeleaf.org/ SpringBoot可以快速生成Spring应用&#xff0c;简化配置&#xff0c;自动装配&#xff0c;开箱即用。 JavaConfigur…

【java基础】枚举类(enum)

文章目录基本介绍快速使用字段、方法、构造器枚举类方法toString方法valueOf方法values方法ordinal方法基本介绍 在java中有一种特殊的类型就是枚举类&#xff0c;对于一个有限的有固定值的集合&#xff0c;我们就可以考虑使用枚举类来进行表示&#xff0c;例如服装的大小为 小…

linux shell 入门学习笔记15 shell 条件测试

概念 shell的条件测试目的是得出真和假。 shell 提供的条件测试语法 test 命令 [] 中括号命令 语法*&#xff1a; test条件测试 test命令用来评估一个表达式&#xff0c;他的结果是真&#xff0c;还是假&#xff0c;如果条件为真&#xff0c;那么命令执行状态结果就为0&…