集成学习中的Boosting和Bagging

2023-05-16

集成学习是一大类模型融合策略和方法的统称,其中包含多种集成学习的思想。

Boosting

Boosting方法训练基分类器时采用串行的方式,各个基分类器之间有依赖。

它的基本思路是将基分类器层层叠加,每一层在训练的时候,对前一层基分类器分错的样本,给予更高的权重。测试时,根据各层分类器的结果的加权得到最终结果。

Boosting的过程很类似于人类学习的过程 (如图) ,我们学习新知识的过程往往是迭代式的,第一遍学习的时候,我们会记住一部分知识,但往往也会犯一些错误,对于这些错误,我们的印象会很深。第二遍学习的时候,就会针对犯过错误的知识加强学习,以减少类似的错误发生。不断循环往复,直到犯错误的次数减少到很低的程度。

Boosting主要思想:迭代式学习

Boosting算法的实现

import util
import numpy as np
import sys
import random

PRINT = True


random.seed(42)
np.random.seed(42)

def small_classify(y):
    classifier, data = y
    return classifier.classify(data)

class AdaBoostClassifier:
    """
    AdaBoost classifier.
    Note that the variable 'datum' in this code refers to a counter of features
    (not to a raw samples.Datum).
    
    """

    def __init__( self, legalLabels, max_iterations, weak_classifier, boosting_iterations):
        self.legalLabels = legalLabels
        self.boosting_iterations = boosting_iterations
        self.classifiers = [weak_classifier(legalLabels, max_iterations) for _ in range(self.boosting_iterations)]
        self.alphas = [0]*self.boosting_iterations

    def train( self, trainingData, trainingLabels):
        """
        The training loop trains weak learners with weights sequentially. 
        The self.classifiers are updated in each iteration and also the self.alphas 
        """
        
        self.features = trainingData[0].keys()
        
        size_sampled_data = int(len(trainingData))
        sampled_weights = [(1.0/size_sampled_data)] * size_sampled_data
        

        for i in range(self.boosting_iterations):
            self.classifiers[i].train(trainingData, trainingLabels, sampled_weights)
            error = 0
            for j in range(len(trainingData)):
                if self.classifiers[i].classify([trainingData[j]])[0] != trainingLabels[j]:
                    error = error + sampled_weights[j]

            for j in range(len(trainingData)):
                if self.classifiers[i].classify([trainingData[j]])[0] == trainingLabels[j]:
                    sampled_weights[j]  = sampled_weights[j] * (error/ (1 - error))

            # Normalize the sampled_weight list
            sum_of_weights = sum(sampled_weights)
            for p in range(len(sampled_weights)):
                sampled_weights[p]  = sampled_weights[p] / sum_of_weights

            self.alphas[i] = np.log((1 - error) / error)
            #print "training loop: ", i





    def classify( self, data):
        """
        Classifies each datum as the label that most closely matches the prototype vector
        for that label. This is done by taking a polling over the weak classifiers already trained.
        See the assignment description for details.
        Recall that a datum is a util.counter.
        The function should return a list of labels where each label should be one of legaLabels.
        """

        
        prediction = []
        for i in range(len(data)):
            guesses = []
            for j in range(self.boosting_iterations):
                guesses.append(self.classifiers[j].classify([data[i]])[0] * self.alphas[j])

            prediction.append(int(np.sign(sum(guesses))))

        return prediction

Bagging

Bagging与Boosting的串行训练方式不同,Bagging方法在训练过程中,各基分类器之间无强依赖,可以进行并行训练。其中很著名的算法之一是基于决策树基分类器的随机森林 (Random Forest) 。为了让基分类器之间互相独立,将训练集分为若干子集 (当训练样本数量较少时,子集之间可能有交叠)。Bagging方法更像是一个集体决策的过程,每个个体都进行单独学习,学习的内容可以相同,也可以不同,也可以部分重叠。但由于个体之间存在差异性,最终做出的判断不会完全一致。在最终做决策时,每个个体单独作出判断,再通过投票的方式做出最后的集体决策 (如图)。

Bagging主要思想:集体投票决策

我们再从消除基分类器的偏差和方差的角度来理解Boosting和Bagging方法的差异。基分类器,有时又被称为弱分类器,因为基分类器的错误率要大于集成分类器。基分类器的错误,是偏差和方差两种错误之和。偏差主要是由于分类器的表达能力有限导致的系统性错误,表现在训练误差不收敛。方差是由于分类器对于样本分布过于敏感,导致在训练样本数较少时,产生过拟合

Boosting方法是通过逐步聚焦于基分类器分错的样本,减小集成分类器的偏差。Bagging方法则是采取分而治之的策略,通过对训练样本多次采样,并分别训练出多个不同模型,然后做综合,来减小集成分类器的方差。假设所有基分类器出错的概率是独立的,在某个测试样本上,用简单多数投票方法来集成结果,超过半数基分类器出错的概率会随着基分类器的数量增加而下降。

下图是Bagging算法的示意图,Model 1、Model 2、Model 3都是用训练集的个子集训练出来的,单独来看,它们的决策边界都很曲折,有过拟合的倾向。集成之后的模型(红线所示) 的决策边界就比各个独立的模型平滑了,这是由于集成的加权投票方法,减小了方差

Bagging算法的一个示意图

Bagging算法的实现

import util
import numpy as np
import sys
import random

PRINT = True

random.seed(42)
np.random.seed(42)

class BaggingClassifier:
    """
    Bagging classifier.
    Note that the variable 'datum' in this code refers to a counter of features
    (not to a raw samples.Datum).
    
    """

    def __init__( self, legalLabels, max_iterations, weak_classifier, ratio, num_classifiers):

        self.ratio = ratio
        self.num_classifiers = num_classifiers
        self.classifiers = [weak_classifier(legalLabels, max_iterations) for _ in range(self.num_classifiers)]

    def train( self, trainingData, trainingLabels):
        """
        The training loop samples from the data "num_classifiers" time. Size of each sample is
        specified by "ratio". So len(sample)/len(trainingData) should equal ratio. 
        """

        self.features = trainingData[0].keys()
        
        sample_size = int(self.ratio * len(trainingData))
        for i in range(self.num_classifiers):
            random_integers = np.random.randint(len(trainingData), size = sample_size)
            sampled_data = []
            sampled_labels = []
            for choosen_element in random_integers:
                sampled_data.append(trainingData[choosen_element])
                sampled_labels.append(trainingLabels[choosen_element])

            self.classifiers[i].train(sampled_data, sampled_labels, None)






    def classify( self, data):
        """
        Classifies each datum as the label that most closely matches the prototype vector
        for that label. This is done by taking a polling over the weak classifiers already trained.
        See the assignment description for details.
        Recall that a datum is a util.counter.
        The function should return a list of labels where each label should be one of legaLabels.
        """

       
        prediction = []
        for i in range(len(data)):
            guesses = []
            for j in range(self.num_classifiers):
                guesses.append(self.classifiers[j].classify([data[i]])[0])

            prediction.append(int(np.sign(sum(guesses))))

        return prediction
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

集成学习中的Boosting和Bagging 的相关文章

  • Ubuntu 14.04安装openwrt

    OpenWRT 编译环境搭建 配置编译环境 必须使用非root用户 xff0c ArchLinux需要创建新用户 安装依赖包 Ubuntu 14 04 必选 apt get install asciidoc bash bc binutils
  • MDK debug时出现*** error 65: access violation at

    简介 本文针对的是访问内存权限的问题 xff0c 其他问题暂时不讨论 问题描述 使用mdk arm调试keil工程的时候遇到错误 error 65 access violation at 0xE0042004 no write permis
  • CreateSemaphore函数

    创建或打开命名或未命名的信号量对象 要指定对象的访问掩码 xff0c 请使用CreateSemaphoreEx函数 语法 HANDLE WINAPI CreateSemaphore xff08 In opt LPSECURITY ATTRI
  • 什么是underlay和overlay?

    1 什么是underlay和overlay xff1f 常规解释 xff1a underlay 现实的物理基础层网络设备 数据中心基础转发架构的网络 以太网最初设计的时候就是一个分布式的网络架构 xff0c 没有中心控制节点 xff0c 网
  • 分布式脑裂问题分析

    1 34 脑裂 34 定义 在一个高可用系统中 xff0c 当联系着的节点断开联系时 xff0c 本来为一个整体的系统 xff0c 分裂成两个独立节点 xff0c 两个节点开始争抢共享资源造成系统混乱 数据损坏的现象 xff0c 成为 脑裂

随机推荐

  • idea必备插件01-代码智能补全插件codota

    代码智能补全插件 codota 01 idea插件下载地址 02 codota在线网站 03 codota官方指导 Codota这个插件可以用于代码的智能补全功能 xff0c 它基于百万级github仓库java程序 xff0c 能根据程序
  • 04-spring-boot-resttemplate netty定制使用

    04 spring boot resttemplate netty定制使用 rest template可以使用netty定制的工厂类 Netty4ClientHttpRequestFactory xff0c 完成相关rest接口访问工作 x
  • sshuttle工具简介

    1 sshuttle简介 最近在k8s配置用到shuttle xff0c 只知道公司用它完成远端k8s集群环境网络环境打通环境工作 xff0c 于是决定研究一下它 xff0c 了解这个穷人代理究竟魅力何在 01 github链接 sshut
  • 日志无法打印问题总结

    日志无法打印问题总结 现象 log4j2运行环境可以生成日志 xff0c 但是没有任何打印信息 1 日志无法打印 最近新开发的服务 xff0c k8s容器部署后 xff0c 发现log4j2的日志无法打印 xff0c 定义的日志都生成了相关
  • 元空间过大与intern方法探究

    1 问题 所负责服务需要保存大量字符串 xff0c 通过写入大量数据 xff0c 发现元空间持续变大 xff0c 于是想到之前每位研发的的建议 xff0c 使用intern方法来优化字符串存储 xff0c 于是做了如下的测试 2 测试int
  • Spring Cloud Tencent和alibaba备忘

    1 Spring Cloud Tencent简介 服务注册与发现 Spring Cloud Tencent Polaris Discovery 命名空间服务服务实例 配置中心 Spring Cloud Tencent Polaris Con
  • Java Se 、JavaEE、JavaME区别

    1 Java Se JavaEE JavaME区别 Java SE Java SE xff08 Java Platform xff0c Standard Edition xff09 J2SE 它允许开发和部署在桌面 服务器 嵌入式环境和实时
  • STM32通用定时器实现pwm输出、输入捕获

    简介 以stm32f103rct6为例 xff0c 下面说明如何使用通用定时器实现pwm输出 详细 stm32的定时器有多种类型 xff0c 有RTC 基本定时器 通用定时器 高级定时器 下面我们选择通用定时器来实现pwm输出功能 利用比较
  • Flex Ethernet (FlexE) 初识

    Flex Ethernet FlexE 初识 1 初识FlexE Flexible Ethernet 由OIF组织制定了其统一标准 xff0c 通过OIF FLEXE 01可以了解到其基本信息 xff1b 摘录其标准的一个概要说明 xff1
  • .adoc使用说明

    开发过程中 xff0c 部分开源代码文档中出现了 adoc文件 xff0c 为了了解并使用这个文件 xff0c 简单记录以下功能和用法 xff0c 方便后续查阅使用 what xff1a AsciiDoc file 标记语言 why xff
  • 【开源推介01-flameshot】-这或许是linux最好用的截图软件

    文章目录 1 介绍flameshot2 安装flameshot3 使用flameshot3 1 命令行3 2 图形化截屏3 3 操作快捷键3 4 图形化配置 4 进阶玩转flameshot4 1 设置系统启动快捷键4 2 下拉菜单截屏 延时
  • 【开源推介02-pyang】-你离yang模型只差一个pyang工具

    文章目录 1 yang建模语言及pyang背景简介2 pyang工具特性3 pyang安装及命令行简介4 pyang的yin yang模型转化5 pyang生成tree文件6 yang语法校验7 pyang小结 你离懂yang模型只差一个p
  • 【高精度定位】关于GPS、RTK、PPK三种定位技术的探讨

    高精度定位通常是指亚米级 厘米级以及毫米级的定位 xff0c 从市场需求来看 xff0c 定位的精度越高往往越好 高精度 低成本 的定位方案无疑将是未来市场的趋势 在物联网时代 xff0c 大多数的应用或多或少都与位置服务相关联 xff0c
  • top 默认使用内存排序的命令

    linux下 xff0c top默认使用cpu来排序 xff0c 如果希望改用内存占用情况或其他项来排序 xff0c 可以通过 o选项 top o MEM 通过 man top 查看其用法 xff0c 里面描述了 o 选项 xff0c 用于
  • 寻找两个点云重叠部分

    目录 方法1 xff1a 方法1实验效果 xff1a 方法2 c 43 43 xff1a 方法2 python 方法2实验效果 xff1a 结论 xff1a 网上大部分寻找重叠区域都是对一个点云建立kdtree xff0c 然后在r半径内搜
  • 防火墙firewalld

    RHEL7中有几种防火墙共存 xff1a firewalld iptables ebtables等 基于iptables的防火墙默认不启动 xff0c 但仍然可以继续使用 RHEL7默认使用firewalld作为防火墙 xff0c 管理工具
  • 仿真平台sumo:随机生成车流的randomTrips.py的较便捷使用方法(新手用)

    Step1 xff1a 首先把需要的地图文件 xff08 net xml xff09 放入自己认为方便操作的文件夹中 此处我的地图文件为demo net 我将其放在一个桌面新建的文件夹里 xff0c 该文件夹叫sumo random 图1
  • 个人面试经验总结

    1 xff0c 海投 2 xff0c 一定要强调自己能留到该地 xff08 这个城市 这个公司 xff09 发展 3 xff0c 简历上出现的技能和项目面试前一天一定要复习 xff0c 因为面试官大部分问题会以简历为主 4 xff0c 要有
  • stm32通用定时器pwm输入模式

    简介 stm32通用定时器有多种输入模式 xff0c 其他包括了pwm输入模式 原理 pwm输入模式是在输入捕获的基础上使用两组输入捕获通道对同一个TIM引脚进行捕获 如下图所示 TIMx CH1引脚输入一个pwm信号 xff0c 经过输入
  • 集成学习中的Boosting和Bagging

    集成学习是一大类模型融合策略和方法的统称 xff0c 其中包含多种集成学习的思想 Boosting Boosting方法训练基分类器时采用串行的方式 xff0c 各个基分类器之间有依赖 它的基本思路是将基分类器层层叠加 xff0c 每一层在