当前位置: 首页 > news >正文

机器学习之Boosting和AdaBoost

1 Boosting和AdaBoost介绍

1.1 集成学习

集成学习 (Ensemble Learning) 算法的基本思想就是将多个分类器组合,从而实现一个预测效果更好的集成分类器。

  • 集成学习通过建立几个模型来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测。
  • 集成学习是一种思想,不是某一个算法

 1.1.1 集成学习分类

集成算法大致可以分为:BaggingBoostingStacking等类型。

  • bagging:并行,多个学习器互不相关 可以并行训练
  • boosting:串行,后一个学习器依赖于前一个学习器
  • stacking:多个学习器的输出作为后面一个学习器的输入

1.1.2 Boosting和Bagging

Boosting和Bagging都是流行的集成学习技术,用于通过多个基学习器的组合来提高机器学习模型的性能。虽然两种方法的目标都是减少过拟合并增加泛化能力,但它们具有不同的方法和特点。

(1)Boosting(提升)

提升是一种迭代的集成技术,在这种方法中,基学习器按顺序训练,每个后续模型都专注于纠正前面模型的错误。它给予训练集中被错误分类的实例更高的权重,迫使下一个模型专注于这些难以处理的情况。

  • 基学习器: 通常,提升算法使用弱学习器,这些模型的性能仅比随机猜测略好。例如,使用深度有限的决策树(通常称为“树桩”)或简单的线性模型。
  • 加权投票: 在预测时,根据每个基学习器的性能和在先前迭代中的重要性对其进行加权。在后续迭代中,被错误分类的实例得到更高的权重。

AdaBoost(自适应提升)和梯度提升机(GBM)是常见的提升算法。

(2)Bagging(装袋):

装袋是一种集成技术,它使用并行训练多个基学习器,每个学习器在随机选择的训练数据子集上独立训练,有放回地采样。最终的预测通过对所有基学习器的预测进行平均(回归问题)或投票(分类问题)得到。

  • 基学习器: 装袋通常对每个模型使用相同的基础学习算法,每个模型在不同的数据子集上独立训练。
  • 自助采样: 对于每个基学习器,使用有放回地随机抽样训练数据的子集。这意味着一些实例可能在子集中出现多次,而其他实例可能根本不出现。 

随机森林是一种常见的装袋算法,它使用决策树作为基学习器。

(3)两种技术的不同点

基学习器的多样性:

  • 提升:通常使用一系列弱学习器,每个模型纠正其前任的错误。这种顺序性为集成引入多样性。
  • 装袋:通过对数据的随机采样,每个模型独立训练,获得集成的多样性。

加权投票与简单平均/投票:

  • 提升:最终预测通过结合所有模型的预测,并根据其性能进行加权得到。更准确的模型在最终预测中具有更大的影响力。
  • 装袋:所有模型对最终预测的贡献相等,因为它们只是被平均(回归问题)或投票(分类问题)。

对过拟合的鲁棒性:

  • 提升:如果弱学习器过于复杂以至于记住训练数据,提升更容易过拟合。需要仔细调整参数、限制弱学习器的复杂性并进行早停止来防止过拟合。
  • 装袋:装袋通过平均各个模型的偏差和错误有助于减少过拟合。通常能提供更稳定和可靠的预测结果。

性能:

  • 提升:如果弱学习器选择得当且训练适当,通常比装袋获得更高的准确性。
  • 装袋:虽然不一定与提升一样准确,但通常提供更一致和可靠的结果。

计算复杂度:

  • 提升:由于模型是顺序训练且有加权实例,与装袋相比,计算上更昂贵。
  • 装袋:模型可以并行训练,因此在处理大型数据集时更加高效。

提升和装袋都是有效的集成方法,选择哪种方法取决于具体问题、数据的性质以及准确性与计算资源之间的权衡。提升更专注于纠正错误,可能导致更高的准确性;而装袋更简单且计算效率更高,提供更稳定且不易过拟合的预测结果。

1.2 Boosting算法

boosting算法是一类将弱学习器提升为强学习器的集成学习算法,它通过改变训练样本的权值,学习多个分类器,并将这些分类器进行线性组合,提高泛化性能。

Boosting系列算法的工作机制类似,大致思路为:先从初始训练集中训练出一个基学习器,再根据基学习器的表现对训练样本的分布进行调整,使得先前基学习器做错的训练样本在后续受到更多关注,然后基于调整后的样本分布来训练下一个基学习器;如此重复进行,直至基学习器数目达到事先指定的值或者组合学习器的精度达到100%,最终将这些基学习器进行线性组合,得到最终的学习器。

从Boosting的工作机制中我们可以发现,对于提升方法来说有两个关键问题需要解决:

  • 在每轮的训练中如何改变训练数据的权值分布
  • 如何将弱学习器结合成强学习器

1.3 Adaboost算法

Adaboost(adaptive boosting),又称为自适应提升算法,是最著名的Boosting算法。经典的Adaboost算法只能用于二分类问题,因此,我们在这里只讨论adaboost算法在二分类任务中的应用。其基本思想为:一开始,将训练数据的权重初始化为相等的值,训练出第一个弱分类器(这里的弱学习器一般是单层决策树,也就是决策树桩,它通过一个判断条件直接把数据一分为二),并且计算该分类器的错误率。从第二次训练开始,将会根据上一次训练所得的弱分类器的效果重新调整每个样本的权重,具体做法为降低上一次分对的样本的权重,提高上一次分错的样本的权重,然后训练出下一个弱分类器。如此循环,直到弱分类器数量达到一个给定值或者集成模型预测正确率达到100%,然后把这些弱分类器结合起来,结合策略为给分类误差率小的弱分类器分配较大的权重,给分类误差率大的弱分类器分配较小的权重,构成一个更强的最终分类器(强分类器)。

根据Adaboost算法的基本思想我们可以知道:

  • Adaboost采用重赋值法来改变训练样本的权值分布,提高那些被前一轮弱分类器错误分类样本的权值,而降低那些被前一轮弱分类器正确分类样本的权值。这样一来,那些没有被正确分类的数据就会因为权值的加大而受到后一轮弱分类器的更大关注。于是,分类问题被一系列的弱分类器“分而治之”。
  • Adaboost采取线性组合将弱学习器结合成强学习器,给分类误差率小的弱分类器一个较大的权重,使其在最后的表决中起较大的作用,给分类误差率大的弱分类器一个较小的权重,使其在表决中起较小的作用。

1.3.1 AdaBoost分类问题

以二分类为例,假设给定一个二类分类的训练数据集\chi = \left \{ (x_{1}, y_{1}), (x_{2}, y_{2}),...,(x_{n}, y_{n})\right \},其中x_{i}表示样本点,y_{i}表示样本对应的类别,其可取值为{-1,1}。AdaBoost算法利用如下的算法,从训练数据中串行的学习一系列的弱学习器,并将这些弱学习器线性组合为一个强学习器。AdaBoost算法描述如下:

输入:训练数据集\chi = \left \{ (x_{1}, y_{1}), (x_{2}, y_{2}),...,(x_{n}, y_{n})\right \}

输出:最终的强分类器G(x)

(1)初始化训练数据的权重分布值:(D_{m} 表示第m个弱学习器的样本点的权值),也就是说初始化的权重都是 (1/n)

 D_{1}=(w_{11},...,w_{1i},...,w_{1N}),       w_{1i}=1/N,     i=1,2,...,N

(2)对M个弱学习器,m=1,2,...,M:

        a)使用具有权值分布D{_{m}}的训练数据集进行学习,得到基本分类器 G{_{m}}(x) ,其输出值为{-1,1};

        b)计算弱分类器G{_{m}}(x)在训练数据集上的分类误差率e{_{m}},其值越小的基分类器在最终分类器中的作用越大

其中,I(G{_{m}}(x{_{i}})\neq y{_{i}})取值为0或1,取0表示分类正确,取1表示分类错误。其中就等于分类错误的权重*分类错误的个数

        c)计算弱分类器G{_{m}}(x)的权重系数\alpha {_{m}}:(这里的对数是自然对数)

一般情况下 em 的取值应该小于0.5,因为若不进行学习随机分类的话,由于是二分类错误率等于0.5,当进行学习的时候,错误率应该略低于0.5。当 em 减小的时候 am 的值增大,而我们希望得到的是分类误差率越小的弱分类器的权值越大,对最终的预测产生的影响也就越大,所以将弱分类器的权值设为该方程式从直观上来说是合理地,具体的证明 am 为上式请继续往下读

        d)更新训练数据集的样本权值分布:

对于二分类,弱分类器G{_{m}}(x)的输出值取值为{-1,1},y{_{i}}的取值为{-1,1},所以对于正确的分类 y{_{i}}G{_{m}}(x)>0,对于错误的分类y{_{i}}G{_{m}}(x)<0,由于样本权重值在[0,1]之间,当分类正确时w{_{m+1,i}}取值较小,而分类错误时w{_{m+1,i}}取值较大,而我们希望得到的是权重值高的训练样本点在后面的弱学习器中会得到更多的重视。

其中,Z{_{m}}是规范化因子,主要作用是将W{_{mi}}的值规范到0-1之间,使得\sum_{i=1}^{N}{W{_{mi}}} = 1

(3)上面我们介绍了弱学习器的权重系数α如何计算,样本的权重系数W如何更新,学习的误差率e如何计算,接下来是最后一个问题,各个弱学习器采用何种结合策略了,AdaBoost对于分类问题的结合策略是加权平均法。如下,利用加权平均法构建基本分类器的线性组合:

得到最终的分类器:

1.3.2 AdaBoost回归问题

AdaBoost回归问题有许多变种,这里我们以AdaBoost R2算法为准

(1)我们先看看回归问题的误差率问题,对于第m个弱学习器,计算他在训练集上的最大误差(也就是每次训练后,计算预测值和真实值的差的最大值):

                       E{_{m}}=max|y{_{i}}-G{_{m}}(x{_{i}})|    i=1,2,...,N

然后计算每个样本的相对误差:(计算相对误差的目的是将误差规范化到[0,1]之间)

  e{_{mi}}=\frac{|y{_{i}}-G{_{m}}(x{_{i}})|}{E{_{m}}}  ,  显然 0\leq e{_{mi}}\leq 1

这里是误差损失为线性时的情况,如果我们用平方误差,则e{_{mi}}=\frac{|y{_{i}}-G{_{m}}(x{_{i}})|}{E{_{m}}^2}^2,如果我们用指数误差,则e{_{mi}}=1-exp(\frac{-y{_{i}}+G{_{m}}(x{_{i}})}{E{_{m}}})

最终得到第k个弱学习器的误差率为:  e{_{m}}=\sum_{i=1}^{N}{w{_{mi}}e{_{mi}}},表示每个样本点的加权误差的总和即为该弱学习器的误差。

(2)我们再来看看弱学习器的权重系数α,如下公式:

                   \alpha {_{m}}=\frac{e{_{m}}}{1-e{_{m}}}

(3)对于如何更新回归问题的样本权重,第k+1个弱学习器的样本权重系数为:

                w{_{m+i,i}}=\frac{w{_{mi}}}{Z{_{m}}}\alpha {_{m}}^{1-e{_{mi}}}

其中Z{_{k}}是规范化因子:Z{_{m}}=\sum_{i=1}^{N}{w{_{mi}}\alpha {_{m}}^{1-e{_{mi}}}}

(4)最后是结合策略,和分类问题不同,回归问题的结合策略采用的是对加权弱学习器取中位数的方法,最终的强回归器为: G(x)=\sum_{m=1}^{M}{g(x)ln\frac{1}{\alpha {_{m}}}},其中g(x)是所有\alpha {_{m}}G{_{m}}(x)的中位数(m=1,2,...,M)。

这就是AdaBoost回归问题的算法介绍,还有一个问题没有解决,就是在分类问题中我们的弱学习器的权重系数\alpha {_{m}}是如何通过计算严格的推导出来的。

1.3.3 AdaBoost前向分步算法

在上两节中,我们介绍了AdaBoost的分类与回归问题,但是在分类问题中还有一个没有解决的就是弱学习器的权重系数\alpha {_{m}}=\frac{1}{2}ln{\frac{1-e{_{m}}}{e{_{m}}}}是如何通过公式推导出来的。这里主要用到的就是前向分步算法,接下来我们就介绍该算法。

从另一个角度讲,AdaBoost算法是模型为加法模型,损失函数为指数函数,学习算法为前向分步算法时的分类问题。其中,加法模型表示我们的最终得到的强分类器是若干个弱分类器加权平均得到的,如下:

f(x)=\sum_{m=1}^{M}{\alpha {_{m}}G{_{m}}(x)}

损失函数是指数函数,如下:

L(y,f(x))=exp(-yf(x))

学习算法为前向分步算法,下面就来介绍AdaBoost是如何利用前向分布算法进行学习的:

(1)假设进过m-1轮迭代前向分布算法已经得到f{_{m-1}}(x)

f{_{m-1}}=f{_{m-2}}(x)+\alpha {_{m-1}}G{_{m-1}}(x)

                    =\alpha {_{1}}G{_{1}}(x)+...+\alpha {_{m-1}}G{_{m-1}}(x)

在第m轮的迭代得到\alpha {_{m}}G{_{m}}(x)f{_{m}}(x).

          f{_{m}}(x)=f{_{m-1}}(x)+\alpha {_{m}}G{_{m}}(x)

目标是使前向分布算法得到的\alpha {_{m}}G{_{m}}(x)使f{_{m}}(x)在训练数据集T上的指数损失最小,即

         (\alpha {_{m}},G{_{m}}(x))=arg \underset{\alpha ,G}{min}\sum_{i=1}^{N}exp(-y{_{i}}(f{_{m-1}}(x{_{i}})+\alpha G(x{_{i}})))

                               =arg\underset{\alpha ,G}{min}\sum_{i=1}^{N}\bar{w}{_{mi}}exp(-y{_{i}}\alpha G(x{_{i}}))          {\color{Red} (1)}

上式即为我们利用前向分步学习算法得到的损失函数。其中,\bar{w}{_{mi}}=exp(-y{_{i}}f{_{m-1}}(x{_{i}}))。因为\bar{w}{_{mi}}既不依赖\alpha也不依赖于G,所以在第m轮迭代中与最小化无关。但\bar{w}{_{mi}}依赖于f{_{m-1}}(x),随着每一轮的迭代而发生变化。

上式达到最小时所取的\alpha ^{_{*}}{_{m}}G ^{_{*}}{_{m}}(x)就是AdaBoost算法所得到的\alpha {_{m}}G{_{m}}(x)

(2)首先求分类器G ^{_{*}}{_{m}}(x)

我们知道,对于二分类的分类器G(x)的输出值为-1和1,y{_{i}}\neq G{_{m}}(x{_{i}})表示预测错误,y{_{i}}= G{_{m}}(x{_{i}})表示正确,每个样本点都有一个权重值,所以对于一个弱分类器的输出则为:G{_{m}}(x)=\sum_{i=1}^{N}\bar{w}{_{mi}}I(y{_{i}}\neq G{_{m}}(X{_{i}})),我们的目标是使损失最小化,所以我们的具有损失最小化的第m个弱分类器即为:

G^{_{*}}{_{m}}(x)=arg \underset{G}{min}\sum_{i=1}^{N}\bar{w}{_{mi}}I(y{_{i}}\neq G(x{_{i}}))   其中,\bar{w}{_{mi}}=exp(-y{_{i}}f{_{m-1}}(x{_{i}}))

为什么用I(y{_{i}}\neq G(x{_{i}}))表示一个弱分类器的输出呢?因为我们的AdaBoost并没有限制弱学习器的种类,所以它的实际表达式要根据使用的弱学习器类型来定。

此分类器即为Adaboost算法的基本分类器G{_{m}}(x),因为它是使第m轮加权训练数据分类误差率最小的基本分类器。

(3)然后就是来求\alpha ^{_{*}}{_{m}}

G ^{_{*}}{_{m}}(x)代入损失函数(1)式中,得:

\alpha {_{m}}=\sum_{i=1}^{N}\bar{w}{_{mi}}exp(-y{_{i}}\alpha{_{m}} G^{_{*}}{_{m}}(x{_{i}}))

我们的目标是最小化上式,求出对应的\alpha ^{_{*}}{_{m}}

              \sum_{i=1}^{N}\bar{w}{_{mi}}exp(-y{_{i}}\alpha{_{m}} G^{_{*}}{_{m}}(x{_{i}}))

         =\sum_{y{_{i}}=G{_{m}}(x{_{i}})}\bar{w{_{mi}}}e^{_{-\alpha }}+\sum_{y{_{i}}\neq G{_{m}}(x{_{i}})}\bar{w{_{mi}}}e^{_{\alpha }}

        =e^{_{-\alpha }}\sum_{y{_{i}}=G{_{m}}(x{_{i}})}\bar{w}{_{mi}}+e^{_{\alpha }}\sum_{y{_{i}}\neq G{_{m}}(x{_{i}})}\bar{w}{_{mi}}

        =e^{_{-\alpha }}(\sum_{i=1}^{N}\bar{w}{_{mi}}-\sum_{y{_{i}}\neq G{_{m}}(x{_{i}})}\bar{w}{_{mi}})+e^{_{\alpha }}\sum_{y{_{i}}\neq G{_{m}}(x{_{i}})}\bar{w}{_{mi}}

        =(e^{_{\alpha }}-e^{_{-\alpha }})\sum_{y{_{i}}\neq G{_{m}}(x{_{i}})}\bar{w}{_{mi}}+e^{_{-\alpha }}\sum_{i=1}^{N}\bar{w}{_{mi}}

        =(e^{_{\alpha }}-e^{_{-\alpha }})\sum_{i=1}^{N}\bar{w}{_{mi}}I(y{_{i}}\neq G{_{m}}(x{_{i}}))+e^{_{-\alpha }}\sum_{i=1}^{N}\bar{w}{_{mi}}        {\color{Red} (2)}

由于,e{_{m}}=\frac{\sum_{i=1}^{N}\bar{w}{_{mi}}I(y{_{i}}\neq G{_{m}}(x{_{i}}))}{\sum_{i=1}^{N}\bar{w}{_{mi}}}

注意:这里我们的样本点权重系数\bar{w}{_{mi}}并没有进行规范化,所以\sum_{i=1}^{m}\bar{w}{_{mi}}\neq 1

(2)式为:   (e^{_{\alpha }}-e^{_{-\alpha }})e{_{m}}\sum_{i=1}^{N}\bar{w}{_{mi}}+e^{_{-\alpha }}\sum_{i=1}^{N}\bar{w}{_{mi}}

则我们的目标是求:

         \alpha {_{m}}=arg\underset{\alpha }{min}(e^{_{\alpha }}-e^{_{-\alpha }})e{_{m}}\sum_{i=1}^{N}\bar{w}{_{mi}}+e^{_{-\alpha }}\sum_{i=1}^{N}\bar{w}{_{mi}}

上式求\alpha偏导,并令偏导等于0,得:

       (e^{_{\alpha }}+e^{_{-\alpha }})e{_{m}}\sum_{i=1}^{N}\bar{w}{_{mi}}-e^{_{-\alpha }}\sum_{i=1}^{N}\bar{w}{_{mi}}=0,进而得到:

       (e^{_{\alpha }}+e^{_{-\alpha }})e{_{m}}-e^{_{-\alpha }}=0,求得:\alpha ^{_{*}}{_{m}}=\frac{1}{2}ln\frac{1-e{_{m}}}{e{_{m}}},其中e{_{m}}为误差率:

       e{_{m}}=\frac{\sum_{i=1}^{N}\bar{w}{_{mi}}I(y{_{i}}\neq G{_{m}}(x{_{i}}))}{\sum_{i=1}^{N}\bar{w}{_{mi}}}=\sum_{i=1}^{N}w{_{mi}}I(y{_{i}}\neq G(x{_{i}}))

(4)最后看样本权重的更新。

利用前面所讲的f{_{m}}(x)=f{_{m-1}}(x)+\alpha {_{m}}G{_{m}}(x),以及权值 \bar{w}{_{mi}}=exp(-y{_{i}}f{_{m-1}}(x))

可以得到如下式子:

       \bar{w}{_{m+1,i}}=\bar{w}{_{mi}}exp(-y{_{i}}\alpha {_{m}}G{_{m}}(x{_{i}}))

这样就得到了我们前面所讲的样本权重更新公式。

1.3.4 AdoBoost算法的正则化

为了防止过拟合,AdaBoost算法中也会加入正则化项,这个正则化项我们称之为步长也就是学习率。定义为v,对于前面的弱学习器的迭代有:

f{_{m}}(x)=f{_{m-1}}(x)+\alpha {_{m}}G{_{m}}(x)

加入正则化项,就变成如下:

f{_{m}}(x)=f{_{m-1}}(x)+v\alpha {_{m}}G{_{m}}(x)

v的取值范围为(0,1]。对于同样的训练集学习效果,较小的v意味着我们需要更多的弱学习器的迭代次数。通常我们用学习率和迭代最大次数一起来决定算法的拟合效果。

2 AdaBoost的优缺点

AdaBoost(自适应增强)是一种集成学习方法,它将弱学习器(通常是决策树)组合起来创建一个强分类器。它通过在每次迭代中给予被错误分类的数据点更大的权重来专注于难以分类的实例。AdaBoost具有一些优点和缺点:

2.1 AdaBoost的优点

  • 提高准确性:与单个学习算法相比,AdaBoost通常能够实现更好的分类准确性。通过结合多个弱学习器,它可以有效处理复杂的分类问题。

  • 多样性:它可以与各种学习算法一起使用作为弱学习器,因此在选择适合当前问题的基础模型时具有灵活性。

  • 减少过拟合:AdaBoost减少了过拟合的风险,因为它更专注于错误分类的样本,使得算法在未见过的数据上具有更好的泛化能力。

  • 不需要调整许多超参数:与某些其他复杂模型不同,AdaBoost通常只有较少的超参数需要调整,使得使用和实现更加简单。

  • 有效处理不平衡数据集:即使在一个类别明显比其他类别更普遍的不平衡数据集上,AdaBoost的表现也很好。

2.2 AdaBoost的缺点

  • 对噪声数据敏感:AdaBoost对噪声数据和异常值很敏感。噪声数据可能导致过拟合,从而降低模型的性能。

  • 计算复杂度高:由于算法需要迭代训练多个弱学习器,因此可能计算上比较昂贵。

  • 需要足够的训练数据:如果训练数据不足或者弱学习器无法优于随机猜测,AdaBoost的性能可能会下降。

  • 可能导致过拟合:尽管AdaBoost在一定程度上减少了过拟合,但如果弱学习器过于复杂或者迭代次数(boosting轮数)过高,仍有可能过拟合。

  • 对复杂模型的偏好:AdaBoost倾向于偏好复杂的弱学习器,这可能导致较长的训练时间,并且如果控制不当可能导致过拟合。

AdaBoost是一种强大的集成学习技术,通过组合多个弱学习器可以显著提高分类准确性。然而,它需要仔细处理噪声数据,调整boosting轮数,并选择合适的弱学习器才能达到最佳效果。

3 AdaBoost的应用场景

AdaBoost在许多领域和应用场景中都表现出色,特别是在处理分类问题时。以下是一些AdaBoost的常见应用场景:

  • 图像识别和计算机视觉: AdaBoost可以用于图像分类、物体检测和人脸识别等计算机视觉任务,通过结合多个弱分类器来提高图像识别的准确性。

  • 自然语言处理(NLP): 在文本分类、情感分析和垃圾邮件过滤等NLP任务中,AdaBoost可以用于提高文本分类的性能。

  • 医学诊断: 在医学图像处理和诊断中,AdaBoost可用于辅助医生诊断,如肿瘤检测和疾病分类。

  • 金融领域: AdaBoost可以应用于信用风险评估、欺诈检测和股票市场预测等金融领域的问题。

  • 推荐系统: 在电子商务和在线推荐系统中,AdaBoost可以用于个性化推荐和用户行为预测。

  • 语音识别: 在语音识别应用中,AdaBoost可以用于声纹识别和语音分类等任务。

  • 生物信息学: 在分析生物数据、DNA序列分类和蛋白质结构预测等生物信息学问题中,AdaBoost可以发挥重要作用。

  • 遥感图像分析: AdaBoost可用于遥感图像分类和地物识别,如土地利用分类和环境监测。

  • 行为识别: 在行为分析和行为识别应用中,AdaBoost可以用于识别动作、行为和活动等。

虽然AdaBoost在许多场景中表现优秀,但并不是适用于所有问题。在实际应用中,需要根据具体问题的特点和数据集的特征选择合适的机器学习算法及参数调整方法。

4 AdaBoost代码实现

4.1 数据集介绍

乳腺癌数据集,是sklearn中经典的二分类数据集:

包含569个样本,每个样本30个特征,阳性样本357,阴性样本212

4.2 代码实现

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import numpy as np
from tqdm import tqdmclass CancerAdaboost:def __init__(self, n_estimators):self.n_estimators = n_estimatorsself.clfs = [lambda x: 0 for i in range(self.n_estimators)]self.alphas = [0 for i in range(self.n_estimators)]self.weights = None# 构造弱分类器的决策函数g(X)def _G(self, fi, fv, direct):assert direct in ["positive", "nagetive"]def _g(X):if direct == "positive":predict = (X[:, fi] <= fv) * -1  # which <= value assign -1 else 0else:predict = (X[:, fi] > fv) * -1  # which > value assign 0 else -1predict[predict == 0] = 1return predictreturn _g# 选择最佳的划分点,即求出fi和fvdef _best_split(self, X, y, w):best_err = 1e10best_fi = Nonebest_fv = Nonebest_direct = Nonefor fi in range(X.shape[1]):series = X[:, fi]for fv in np.sort(series):predict = np.zeros_like(series, dtype=np.int32)# direct = postivepredict[series <= fv] = -1predict[series > fv] = 1err = np.sum((predict != y) * 1 * w)#                 print("err = {} ,fi={},fv={},direct={}".format(err,fi,fv,"postive"))if err < best_err:best_err = errbest_fi = fibest_fv = fvbest_direct = "positive"# direct = nagetivepredict = predict * -1err = np.sum((predict != y) * 1 * w)if err < best_err:best_err = errbest_fi = fibest_fv = fvbest_direct = "nagetive"#                 print("err = {} ,fi={},fv={},direct={}".format(err,fi,fv,"nagetive"))return best_err, best_fi, best_fv, best_directdef fit(self, X_train, y_train):self.weights = np.ones_like(y_train) / len(y_train)for i in tqdm(range(self.n_estimators)):err, fi, fv, direct = self._best_split(X_train, y_train, self.weights)# 计算G(x)的系数alphaalpha = 0.5 * np.log((1 - err) / err) if err != 0 else 1#             print("alpha:",alpha)self.alphas[i] = alpha# 求出Gg = self._G(fi, fv, direct)self.clfs[i] = gif err == 0: break# 更新weightsself.weights = self.weights * np.exp(-1 * alpha * y_train * g(X_train))self.weights = self.weights / np.sum(self.weights)def predict(self, X_test):y_p = np.array([self.alphas[i] * self.clfs[i](X_test) for i in range(self.n_estimators)])y_p = np.sum(y_p, axis=0)y_predict = np.zeros_like(y_p, dtype=np.int32)y_predict[y_p >= 0] = 1y_predict[y_p < 0] = -1return y_predictdef score(self, X_test, y_test):y_predict = self.predict(X_test)return np.sum(y_predict == y_test) / len(y_predict)if __name__ == "__main__":breast_cancer = load_breast_cancer()X = breast_cancer.datay = breast_cancer.targety[y == 0] = -1# 划分数据X_train, X_test, y_train, y_test = train_test_split(X, y)print(X_train.shape, X_test.shape)clf = CancerAdaboost(200)clf.fit(X_train, y_train)print(clf.score(X_test, y_test))

4.3 结果展示

(1)n_estimators=50,分类结果达到了93%的准确率 

  0%|          | 0/50 [00:00<?, ?it/s](426, 30) (143, 30)
100%|██████████| 50/50 [00:24<00:00,  2.04it/s]
0.9300699300699301

 (2)n_estimators=100,分类结果达到了94%的准确率 

  0%|          | 0/100 [00:00<?, ?it/s](426, 30) (143, 30)
100%|██████████| 100/100 [00:54<00:00,  1.83it/s]
0.9440559440559441

(3)n_estimators=200时,分类结果达到了97%的准确率 

(426, 30) (143, 30)
100%|██████████| 200/200 [02:09<00:00,  1.54it/s]
0.972027972027972

n_estimators数量越大,需要的计算时间也越长,准确率也越高

相关文章:

机器学习之Boosting和AdaBoost

1 Boosting和AdaBoost介绍 1.1 集成学习 集成学习 (Ensemble Learning) 算法的基本思想就是将多个分类器组合&#xff0c;从而实现一个预测效果更好的集成分类器。 集成学习通过建立几个模型来解决单一预测问题。它的工作原理是生成多个分类器/模型&#xff0c;各自独立地学…...

汇编语言预定义寄存器和协处理器

ARM汇编器对ARM的寄存器和协处理器进行了预定义&#xff08;包括APCS对r0&#xff5e;r15寄存器的定义&#xff09;&#xff0c;所有的寄存器和协处理器名都是大小写敏感的。 &#xff08;1&#xff09;预定义寄存器名 下面列出了被ARM汇编器预定义的寄存器名。 r0&#xff…...

【前缀和】974. 和可被 K 整除的子数组

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 974. 和可被 K 整除的子数组 题目:示例:题解: 题目: 示例: 题解: 本题与560.和为K的子数组高度相似 同样的,本题利用了前缀和的定理.当(pre[i]-…...

linux页框回收之shrink_node函数源码剖析

概述 《Linux内存回收入口_nginux的博客-CSDN博客》前文我们概略的描述了几种内存回收入口&#xff0c;我们知道几种回收入口最终都会调用进入shrink_node函数&#xff0c;本文将以Linux 5.9源码来描述shrink_node函数的源码实现。 函数调用流程图 scan_control数据结构 str…...

网络运维基础问题及解答

前言 本篇文章是对于网络运维基础技能的一些常见问题的解答&#xff0c;希望能够为进行期末复习或者对网络运维感兴趣的同学或专业人员提供一定的帮助。 问题及解答 1. 列举 3 种常用字符编码&#xff0c;简述怎样在 str 和 bytes 之间进行编码和解码。 答&#xff1a;常用的…...

【RabbitMQ】之保证数据不丢失方案

目录 一、数据丢失场景二、数据可靠性方案 1、生产者丢失消息解决方案2、MQ 队列丢失消息解决方案3、消费者丢失消息解决方案 一、数据丢失场景 MQ 消息数据完整的链路为&#xff1a;从 Producer 发送消息到 RabbitMQ 服务器中&#xff0c;再由 Broker 服务的 Exchange 根据…...

插入排序算法

插入排序 算法说明与代码实现&#xff1a; 以下是使用Go语言实现的插入排序算法示例代码&#xff1a; package mainimport "fmt"func insertionSort(arr []int) {n : len(arr)for i : 1; i < n; i {key : arr[i]j : i - 1for j > 0 && arr[j] > …...

Linux标准库API

目录 1.字符串函数 2.数据转换函数 3.格式化输入输出函数 4.权限控制函数 5.IO函数 6.进程控制函数 7.文件和目录函数 1.字符串函数 2.数据转换函数 3.格式化输入输出函数 #include<stdarg.h>void test(const char * format , ...){va_list ap;va_start(ap,format…...

腾讯云—自动挂载云盘

腾讯云&#xff0c;稍微麻烦了点。 腾讯云服务器&#xff0c;镜像为opencloudos 8。 ### 1、挂载云盘bash #首先通过以下命令&#xff0c;能够看到新的数据盘&#xff0c;如果不能需要通过腾讯云控制台卸载后&#xff0c;重新挂载&#xff0c;并重启服务器。 fdisk -l#为 /dev…...

为Win12做准备?微软Win11 23H2将集成AI助手:GPT4免费用

微软日前确认今年4季度推出Win11 23H2&#xff0c;这是Win11第二个年度更新。 Win11 23H2具体有哪些功能升级&#xff0c;现在还不好说&#xff0c;但它会集成微软的Copilot&#xff0c;它很容易让人想到多年前的“曲别针”助手&#xff0c;但这次是AI技术加持的&#xff0c;Co…...

Opencv Win10+Qt+Cmake 开发环境搭建

文章目录 一.Opencv安装二.Qt搭建opencv开发环境 一.Opencv安装 官网下载Opencv安装包 双击下载的软件进行解压 3. 系统环境变量添加 二.Qt搭建opencv开发环境 创建一个新的Qt项目(Non-Qt Project) 打开创建好的项目中的CMakeLists.txt&#xff0c;添加如下代码 # openc…...

Matlab实现光伏仿真(附上30个完整仿真源码)

光伏发电电池模型是描述光伏电池在不同条件下产生电能的数学模型。该模型可以用于预测光伏电池的输出功率&#xff0c;并为优化光伏电池系统设计和控制提供基础。本文将介绍如何使用Matlab实现光伏发电电池模型。 文章目录 1、光伏发电电池模型2、使用Matlab实现光伏发电电池模…...

JSON.stringify()与JSON.parse()

JSON.parse() 方法用来解析 JSON 字符串 onst json {"result":true, "count":42}; const obj JSON.parse(json); console.log(typeof(json)) //string console.log(typeof(obj)) //objJSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字…...

neo4j教程-安装部署

neo4j教程-安装部署 Neo4j的关键概念和特点 •Neo4j是一个开源的NoSQL图形存储数据库&#xff0c;可为应用程序提供支持ACID的后端。Neo4j的开发始于2003年&#xff0c;自2007年转变为开源图形数据库模型。程序员使用的是路由器和关系的灵活网络结构&#xff0c;而不是静态表…...

网络面试合集

传输层的数据结构是什么&#xff1f; 就是在问他的协议格式&#xff1a;UDP&TCP 2.1.1三次握手 通信前&#xff0c;要先建立连接&#xff0c;确保双方都是在线&#xff0c;具有数据收发的能力。 2.1.2四次挥手 通信结束后&#xff0c;会有一个断开连接的过程&#xff0…...

java+springboot+mysql智慧办公OA管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的智慧办公OA管理系统&#xff0c;系统包含超级管理员&#xff0c;系统管理员、员工角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;部门管理&#xff1b;职位管理&#xff1b;员工管理…...

【教程】Tkinter实现Python软件自动更新与提醒

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 文件下载&#xff1a;https://download.csdn.net/download/sxf1061700625/88134425 示例演示&#xff1a; 参考代码&#xff1a; import os import _thread import shutil import subprocess import sys import …...

音频深度学习变得简单:自动语音识别 (ASR),它是如何工作的

一、说明 在过去的几年里&#xff0c;随着Google Home&#xff0c;Amazon Echo&#xff0c;Siri&#xff0c;Cortana等的普及&#xff0c;语音助手已经无处不在。这些是自动语音识别 &#xff08;ASR&#xff09; 最著名的示例。此类应用程序从某种语言的语音音频剪辑开始&…...

反射简述

什么是反射反射在java中起到什么样的作用获取class对象的三种方式反射的优缺点图 什么是反射 JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意一个方法和属性&…...

Kotlin泛型的协变与逆变

以下内容摘自郭霖《第一行代码》第三版 泛型的协变 一个泛型类或者泛型接口中的方法&#xff0c;它的参数列表是接收数据的地方&#xff0c;因此可以称它为in位置&#xff0c;而它的返回值是输出数据的地方&#xff0c;因此可以称它为out位置。 先定义三个类&#xff1a; op…...

【后端面经】微服务构架 (1-6) | 隔离:如何确保心悦会员体验无忧?唱响隔离的鸣奏曲!

文章目录 一、前置知识1、什么是隔离?2、为什么要隔离?3、怎么进行隔离?A) 机房隔离B) 实例隔离C) 分组隔离D) 连接池隔离 与 线程池隔离E) 信号量隔离F) 第三方依赖隔离二、面试环节1、面试准备2、基本思路3、亮点方案A) 慢任务隔离B) 制作库与线上库分离三、章节总结 …...

复习之kickstart无人职守安装脚本

一、kickstart简介 kickstart是红帽发行版中的一种安装方式&#xff0c;它通过以配置文件的方式来记录linux系统安装的各项参数和想要安装的软件。只要配置正确&#xff0c;整个安装过程中无需人工交互参与&#xff0c;达到无人值守安装的目的。 二、kickstar文件的生成 进入/…...

CSS动画——实现波浪摇摆效果...

一、效果展示 以下主要实现四个动画&#xff1a; 元素上下摇摆动画波浪上下摇摆动画气泡上升及消失动画连续气泡右飘动画 二、实现思路 这里主要讲一下波浪上下摇摆动画和连续气泡右飘动画的实现思路 这里拿一张波浪图来举例解释实现波浪动画的思路&#xff1a; 波浪的摇…...

【MyBatis学习】Spring Boot(SSM)单元测试,不用打包就可以测试我们的项目了,判断程序是否满足需求变得如此简单 ? ? ?

前言: 大家好,我是良辰丫,在上一篇文章中我们学习了MyBatis简单的查询操作,今天来介绍一下Spring Boot(SSM)的一种单元测试,有人可能会感到疑惑,框架里面还有这玩意?什么东东呀,框架里面是没有这的,但是我们简单的学习一下单元测试,可以帮助我们自己测试代码,学习单元测试可以…...

JavaScript 类

本文内容学习于&#xff1a;后盾人 (houdunren.com) 1.可以使用类声明和赋值表达式定义类&#xff0c;推荐使用类声明来定义类 //类声明 class User {} console.log(new User()); //赋值表达式定义类 let Article class {}; console.log(new Article()); //类方法间不需要逗号…...

SpringBoot的static静态资源访问、参数配置、代码自定义访问规则

目录 1. 静态资源1.1 默认静态资源1.2 Controller高优先级1.3 修改静态资源的URL根路径1.4 修改静态资源的目录1.5 访问webjars依赖包的静态资源1.6 静态资源的关闭1.7 静态资源在浏览器的缓存1.8 静态资源实战1.9 通过代码自定义静态资源访问规则 1. 静态资源 查看源码如下&a…...

IO进、线程——线程(线程的创建、线程的退出、线程的回收、线程的分离和多线程并发编程)

线程 并发执行的轻量级进程 进程是资源分配的最小单位&#xff0c;线程是任务调度的最小单位 线程是进程的一部分&#xff0c;是任务调度的最小单位。一个进程可以包含多个线程&#xff0c;这些线程可以并发执行&#xff0c;共享进程的资源&#xff0c;但每个线程都有自己的…...

neo4j教程-Cypher操作

Cypher基础操作 Cypher是图形存储数据库Neo4j的查询语言&#xff0c;Cypher是通过模式匹配Neo4j数据库中的节点和关系&#xff0c;从而对数据库Neo4j中的节点和关系进行一系列的相关操作。 下面&#xff0c;通过一张表来介绍一下常用的Neo4j操作命令及相关说明&#xff0c;具…...

秋招算法备战第31天 | 贪心算法理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

贪心算法理论基础 贪心算法并没有固定的套路&#xff0c;唯一的难点就是如何通过局部最优&#xff0c;推出整体最优。如何验证可不可以用贪心算法呢&#xff1f;最好用的策略就是举反例&#xff0c;如果想不到反例&#xff0c;那么就试一试贪心吧。刷题或者面试的时候&#xf…...

页面生成图片或PDF node-egg

没有特别的幸运&#xff0c;那么就特别的努力&#xff01;&#xff01;&#xff01; 中间件&#xff1a;页面生成图片 node-egg 涉及到技术node egg Puppeteer 解决文书智能生成多样化先看效果环境准备初始化项目 目录结构核心代码 完整代码https://gitee.com/hammer1010_ad…...