集成学习之Adaboost与GBDT

Boosting集成算法

boosting思想

通过串行地构造多个个体分类器,然后以一定的方式将他们组合成一个强学习器。
boosting思想

  • Boosting在集成学习领域是非常耀眼的一类方法,其中又以AdaBoost和GBDT最为突出
  • AdaBoost是Adaptive Boosting的简称,在人脸识别和处理不均匀数据相关领域得到广泛引用;
  • GBDT 更是被称为最强学习器,在各类数据竞赛中得到追捧。这两类方法都是集成模型,其构造方法是通过构造多个弱分类器来组成一个强分类器,且同属于Boosting框架。

区别

  • AdaBoost不属于梯度提升方法(Gradient Boosting),即它在构造集成模型的时候没有用到梯度下降的思想,而是用的 Forward Stagewise Additive Modeling (分步前向加性模型,FSAM)。
  • 基于Gradient Boosting算法的学习器被称为Gradient Boosting Machine(GBM),如果说AdaBoost是boosting方法的开山之作,那么GBM就是boosting方法的集大成者。

Adaboost算法

  • 概述:Adaboost是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。
  • 介绍:AdaBoost,是“Adaptive Boosting”(自适应增强)的缩写,是一种机器学习方法
  • 思想:前面的模型对训练集预测后,在每个样本上都会产生一个不同损失,AdaBoost会为每个样本更新权重,分类错误的样本要提高权重,分类正确的样本要降低权重,下一个学习器会更加“关注”权重大的样本;每一次得到一个模型后,根据模型在该轮数据上的表现给当前模型设置一个权重,表现好的权重大,最终带权叠加得到最终集成模型。

分类解释

  1. 输入训练集: T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x N , y N ) } , y ∈ { − 1 , + 1 } T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \ldots,\left(x_{N}, y_{N}\right)\right\}, \quad y \in\{-1,+1\} T={(x1,y1),(x2,y2),,(xN,yN)},y{1,+1}
  2. 训练弱学习器 M M M个。输出:最终的强学习器 G ( x ) G(x) G(x)
  • 初始化样本集权重为: D 1 = ( w 11 , w 12 , … , w 1 N ) w 1 i = 1 N , i = 1 , 2 , … , N D_{1}=\left(w_{11}, w_{12}, \ldots, w_{1 N}\right) \quad w_{1 i}=\frac{1}{N}, \quad i=1,2, \ldots, N D1=(w11,w12,,w1N)w1i=N1,i=1,2,,N
  • 对于 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M
    • 使用具有权值分布Dm的训练数据来训练模型,得到弱学习器 G m ( x ) G_m(x) Gm(x)
    • 计算 G m ( x ) G_m(x) Gm(x)的分类误差率.
  • e m = ∑ i = 1 N w m i I ( G m ( x ) ≠ y i ) e_{m}=\sum_{i=1}^{N} w_{m i} I\left(G_{m}(x) \neq y_{i}\right) em=i=1NwmiI(Gm(x)=yi)
    • 计算弱学习器的系数:
      α m = 1 2 l o g 1 − e m e m \alpha_m=\frac{1}{2}log\frac{1-e_m}{e_m} αm=21logem1em
    • 更新训练集中样本的权重
      z m = ∑ i = 1 w m , i exp ⁡ ( − a m y i G m ( x i ) ) W m + 1 , i = w m , i z m exp ⁡ ( − a m y i G m ( x i ) ) , i = 1 , 2 , 3 , … z_{\mathrm{m}}=\sum_{i=1} w_{m, i} \exp \left(-a_{m} y_{i} G_{m}\left(x_{i}\right)\right) \\ W_{m+1, i}=\frac{w_{m, i}}{z_{m}} \exp \left(-a_{m} y_{i} G_{m}\left(x_{i}\right)\right), \quad i=1,2,3, \ldots zm=i=1wm,iexp(amyiGm(xi))Wm+1,i=zmwm,iexp(amyiGm(xi)),i=1,2,3,
  • 最终学习器为
    f ( x ) = ∑ i = 1 m α M G m ( x ) g ( x ) = s i g n ( f ( x ) ) f(x)=\sum_{i=1}^{m}\alpha_MG_m(x)\\ g(x)=sign(f(x)) f(x)=i=1mαMGm(x)g(x)=sign(f(x))
    Adaboost算法步骤

分类案例

现有训练样本, x x x为特征, y y y是标签
案例1

  1. 设置初始样本权重值: 1 N = 1 10 \frac{1}{N}=\frac{1}{10} N1=101
  2. 初始每个样本的权重: w 1 i = 0.1 , i = 1 , … , 10 w_{1i}=0.1,i=1,\dots,10 w1i=0.1,i=1,,10
    D 1 = ( 0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 , 0.1 ) D_1=(0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1) D1=(0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1)
  3. 初始第一个弱分类器,经过决策树分类原则,知道最佳阈值点为2,得到弱分类器:
    G 1 ( x ) = { 1 , x ≤ 2 − 1 , x > 2 G_{1}(x)=\left\{ \begin{array}{c} 1, x \leq 2 \\ -1, x > 2 \end{array} \right. G1(x)={1,x21,x>2
  4. 通过错误率计算,可以计算出错误率为 e m = 0.3 e_m=0.3 em=0.3
  5. 计算 G 1 ( x ) G_1(x) G1(x)在强分类器中的权重系数
    α 1 = 1 2 l o g 1 − e 1 e 1 = 0.4236 \alpha_1=\frac{1}{2}log\frac{1-e_1}{e_1}=0.4236 α1=21loge11e1=0.4236
  6. 更新样本的权重分布,用于下一轮迭代:
  7. 归一化因子(用于将样本权重加和值固定为1)
    z 1 = ∑ w 1 i exp ⁡ ( − a 1 y i G 1 ( x i ) ) W 2 , i = w 1 , i z 1 exp ⁡ ( − a 1 y i G 1 ( x i ) ) , i = 1 , 2 , 3 , … z_{\mathrm{1}}=\sum w_{1 i} \exp \left(-a_{1} y_{i} G_{1}\left(x_{i}\right)\right) \\ W_{2, i}=\frac{w_{1, i}}{z_{1}} \exp \left(-a_{1} y_{i} G_{1}\left(x_{i}\right)\right), \quad i=1,2,3, \ldots z1=w1iexp(a1yiG1(xi))W2,i=z1w1,iexp(a1yiG1(xi)),i=1,2,3,
  8. 更新后的权重进行调整
    D 2 = ( 0.0715 , 0.0715 , 0.0715 , 0.0715 , 0.0715 , 0.0715 , 0.1666 , 0.1666 , 0.1666 , 0.0715 ) D_2=(0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715) D2=(0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715)
  9. 得到第一轮迭代的强分类器
    s i g n ( F 1 ( x ) ) = s i g n ( 0.4236 G 1 ( x ) ) sign(F_1(x))=sign(0.4236G_1(x)) sign(F1(x))=sign(0.4236G1(x))
  10. 依次类推,经过多轮以后,得到如下强分类器:
    s i g n ( F 3 ( x ) ) = s i g n ( 0.4236 G 1 ( x ) + 0.6496 G 2 ( x ) + 0.7514 G 3 ( x ) ) sign(F_3(x))=sign(0.4236G_1(x)+0.6496G_2(x)+0.7514G_3(x)) sign(F3(x))=sign(0.4236G1(x)+0.6496G2(x)+0.7514G3(x))
  11. 分类误差率为0,结束迭代。 F ( x ) = s i g n ( F 3 ( x ) ) F(x)=sign(F_3(x)) F(x)=sign(F3(x))就是最终的强分类器。

回归解释

  1. 输入训练集: T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x N , y N ) } , y ∈ R T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \ldots,\left(x_{N}, y_{N}\right)\right\}, \quad y \in R T={(x1,y1),(x2,y2),,(xN,yN)},yR
  2. 训练弱学习器 M M M个。输出:最终的强学习器 G ( x ) G(x) G(x)
  • 初始化样本集权重为: D 1 = ( w 11 , w 12 , … , w 1 N ) w 1 i = 1 N , i = 1 , 2 , … , N D_{1}=\left(w_{11}, w_{12}, \ldots, w_{1 N}\right) \quad w_{1 i}=\frac{1}{N}, \quad i=1,2, \ldots, N D1=(w11,w12,,w1N)w1i=N1,i=1,2,,N
  • 对于 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M
    • 使用具有权值分布Dm的训练数据来训练模型,得到弱学习器 G m ( x ) G_m(x) Gm(x)
    • 计算 G m ( x ) G_m(x) Gm(x)的回归误差率.
  • e m = ∑ i = 1 N w m i ( y i − G m ) 2 G m 2 e_{m}=\sum_{i=1}^{N} w_{m i} \frac{(y_i-G_m)^2}{G_m^2} em=i=1NwmiGm2(yiGm)2
    • 计算弱学习器的系数:
      α m = 1 − e m e m \alpha_m=\frac{1-e_m}{e_m} αm=em1em
    • 更新训练集中样本的权重
      z m = ∑ i = 1 w m i α m 1 − e m W m + 1 , i = w m , i z m α m 1 − e m , i = 1 , 2 , 3 , … z_{\mathrm{m}}=\sum_{i=1} w_{mi} \alpha_m^{1-e_m} \\ W_{m+1, i}=\frac{w_{m, i}}{z_{m}} \alpha_m^{1-e_m}, \quad i=1,2,3, \ldots zm=i=1wmiαm1emWm+1,i=zmwm,iαm1em,i=1,2,3,
  • 最终学习器:先对弱学习器进行加权,取中位数,再集成模型
    G ( x ) = ∑ i = 1 M ( l n 1 α m ) g ( x ) , 其 中 g ( x ) 是 所 有 α m G m ( x ) 的 中 位 数 G(x)=\sum_{i=1}^{M}(ln\frac{1}{\alpha_m})g(x),其中g(x)是所有\alpha_mG_m(x)的中位数 G(x)=i=1M(lnαm1)g(x),g(x)αmGm(x)

优缺点

  • 优点:
    • 可以使用各种回归分类模型来构建弱学习器,非常灵活
    • Sklearn中对AdaBoost的实现是从带权学习视角出发的,思想朴素,易于理解
    • 控制迭代次数可以一定程度防止发生过拟合
  • 缺点:
    • 对异常样本敏感,异常样本在迭代中可能会获得较高的权重,影响最终预测准确性。

GBDT算法

概述

  • Adaboost 是利用前一轮弱学习器的误差率来更新训练集的权重,这样一轮轮的迭代下去,简单的说是Boosting框架+任意基学习器算法+指数损失函数。
  • GBDT通过多轮迭代,每轮迭代产生一个弱分类器,每个分类器在上一轮分类器的残差基础上进行训练。对弱分类器的要求一般是足够简单,并且是低方差和高偏差的。因为训练的过程是通过降低偏差来不断提高最终分类器的精度
  • GBDT由三部分构成:DT(Regression Decistion Tree)、GB(Gradient Boosting)和Shrinkage(衰减)
  • 由多棵决策树组成,所有树的结果累加起来就是最终结果
  • 与随机森林区别:※随机森林使用抽取不同的样本构建不同的子树,也就是说第m棵树的构建和前m-1棵树的结果是没有关系;※迭代决策树在构建子树的时候,使用之前子树构建结果后形成的残差作为输入数据构建下一个子树;然后最终预测的时候按照子树构建的顺序进行预测,并将预测结果相加。
  • 回归树(Regression Decistion Tree, DT):GBDT的核心在于累加所有树的结果作为最终结果,所以GBDT中的树都是回归树,而不是分类树。
  • GBDT实质上是一个回归算法,不过可以稍微的进行转换后就可以解决分类问题。在分类问题中,假设有k个类别,那么每一轮实质上是构建了k棵树,对于某个样本x的会产生k个输出值,然后
    将这些输出值使用softmax来产生属于c类别的概率值,选择概率最大的最为最终的预测值。
    f ( z ) = e z ∑ i = 1 n e z f(z)=\frac{e^z}{\sum_{i=1}^{n}e^{z}} f(z)=i=1nezez
  • 衰减(Shrinkage):每次走一小步逐渐逼近结果的效果,要比每次迈一大步很快逼近结果的方式更容易避免过拟合。即模型不完全信任每一个残差树,认为每颗树只“学习”到一部分预测信息,所以在累加的时候只累加一小部分,通过多棵树的迭代就可以弥补不足

算法步骤

GBT算法步骤

API

Adaboost的API
GBDT的API

案例python实现

Adaboost

import pandas as pd
import numpy as np
import math
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import AdaBoostRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error

class adaboost_study(object):
	def __init__(self):
		self.df = pd.DataFrame([[0,1],[1,1],[2,1],[3,-1],[4,-1],
		                   [5,-1],[6,1],[7,1],[8,1],[9,-1]])
		#初始化权值分布,每个样本的权重都是均值,求和为1
		self.w =np.ones(df.shape[0])/df.shape[0]
		#分割x,y
		self.X = df.iloc[:,[0]]
		self.Y = df.iloc[:,[-1]]
	
	def self_adaboost(self):
		X = self.X
		Y = self.Y
		model = DecisionTreeClassifier(max_depth=1).fit(X,Y,sample_weight=w)
		model1 = model
		#计算模型的误差率
		e = sum(w*(model.predict(X) != Y.values.T[0]))#初始化权值分布,平均值,求和为1
		#计算学习器系数
		a = 1/2*math.log((1-e)/e)
		a1 = a
		#权重值的调整
		z = sum(w*np.exp(-1*a*Y.values.T[0]*model.predict(X))) #规范因子
		w = w/z*np.exp(-1*a*Y.values.T[0]*model.predict(X))#更新权值分布
		print('第一个模型错误率:{}'.format(e))
		print('第一个模型学习器权重:{}'.format(a))
		
		model = DecisionTreeClassifier(max_depth=1).fit(X,Y,sample_weight=w)##训练第2个模型
		model2 = model
		e = sum(w*(model.predict(X) != Y.values.T[0]))
		a = 1/2*math.log((1-e)/e)
		a2 = a
		z = sum(w*np.exp(-1*a*Y.values.T[0]*model.predict(X)))
		#更新权重,进行下一次操作的处理
		w = w/z*np.exp(-1*a*Y.values.T[0]*model.predict(X))
		
		model = DecisionTreeClassifier(max_depth=1).fit(X,Y,sample_weight=w)##训练第3个模型
		model3 = model
		e = sum(w*(model.predict(X) != Y.values.T[0]))
		a = 1/2*math.log((1-e)/e)
		a3 = a
		
		y_ = np.sign(a1*model1.predict(X)+a2*model2.predict(X)+a3*model3.predict(X))##模型组合
		#错误率
		e = sum((y_ != Y.values.T[0]))/df.shape[0]
		print(e)
	
	def sklearn_classifier(self):
		model = AdaBoostClassifier(n_estimators=3).fit(self.X,self.Y)#创建了三颗决策树进行处理
y_ = model.predict(X)
print(model.score(X, Y))
	
	def sklearn_re(self):
		model = DecisionTreeRegressor(max_depth=3)#弱学习器
		#可以尝试调参,提升模型的准确度
		model = AdaBoostRegressor(n_estimators=5,base_estimator=model,learning_rate=0.01).fit(self.X,self.Y)
		y_ = model.predict(self.X)
		print(model.score(self.X, self.Y))

GBDT

import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import GradientBoostingRegressor
import warnings
warnings.filterwarnings('ignore')

class GBDT_study(object):
	def __init__():
		self.df = pd.DataFrame([[1,5.56],[2,5.7],[3,5.91],[4,6.4],[5,6.8],[6,7.05],[7,8.9],[8,8.7],[9,9],[10,9.05]],columns=["x","y"])
		self.X = df.iloc[:,[0]]  #构造X
		self.Y = df.iloc[:,[-1]]  #构造Y
		self.y_ = Y
	
	def self_GBDT(self):
		X = self.X
		Y=self.Y
		y_ = self.y_
		M = [] #存储决策树模型的数组
		n_trees = 4  #设置树的颗数
		for i in range(n_trees):
		    model = DecisionTreeRegressor(max_depth=2).fit(X,Y)  #新建决策树模型
		    M.append(model)  #将决策树模型加入数组
		    Y_het = model.predict(X) #输出模型预测值
		    Y_het = pd.DataFrame(Y_het,columns=["y"]) #将模型预测值转为DataFrame
		    print(Y_het)
		    Y = Y - Y_het #改变原始的Y,让下一个学习器继续学习
		    print(i, Y)
		res = np.zeros(df.shape[0]) #初始化全零向量
		for i in M: #遍历模型数组
    		res += i.predict(X) #将每个模型预测值叠加到res变量
		print(res) #输出最终对每个样本标签的预测值
		print('均方误差:', mean_squared_error(y_, res))

	def GBDT_cla(self):
		model = GradientBoostingClassifier(n_estimators=3).fit(self.X,self.Y)
		y_ = model.predict(self.X)
		print(model.score(self.X, self.Y))
	
	def GBDT_Re(self):
		model = GradientBoostingRegressor(n_estimators=50)
model.fit(self.X, self.Y)
		y_ = model.predict(self.X)
		print(y_)
		print(mean_squared_error(Y, y_))
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梚枫_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值