六、(机器学习)-Adaboost提升树-二分类和多分类(最清晰最易懂)

Adaboost提升树

一、bagging与boosting

bagging即套袋法,通过对训练样本重新采样的方法得到不同的训练样本集,在这些新的训练样本集上分别训练学习器,最终合并每一个学习器的结果,作为最终的学习结果。随机森林就是采用的该方法,不同树之间是相互独立的,每个树的权重都是一样的,这样可以是树可以并行的运行。
在这里插入图片描述
boosting算法与baging算法不同的是,学习器之间是存在先后顺序的,同时,二米一个样本都是有权重的,初始时,每一个样本的权重是相等的。首先第一个学习器对训练样本进行学习,当学习完成后,增大错误样本的权重,你可能会问,为什么要增大错误样本的权重,在分类问题中,错误的样本是算法未正确预测的结果,所以我们要增大错误样本的权重,才能在之后的预测中将之前预测错误的结果预测准确,就好比在人群中,你为什么可以一眼就认出了姚明,那是因为姚明在人群中的权重较大,,增大错误样本的权重的同时,要减小正确样本的权重,在利用第二个学习器对其进行学习,依次进行下去,最终得到b个学习器,最后合并这b个学习器的结果,同时与bagging中不同的是,每一个学习器的权重也是不一样的。在bossting中最重要的就是Adaboost和GBDT。

在这里插入图片描述
二、adaboost算法主要步骤

  1. 从训练集D中无放回的抽样方式随机抽取一个训练子集d1,用于弱学习机c1的训练
  2. 从训练集D中以无放回的方式随机抽取一个训练子集d2,并将c1中误分分类样本中的50%加入训练集中,训练得到若学习机c2
  3. 从训练集D中以无放回的方式随机的抽取c1,c2分类结果不一致的训练样本生成训练样本集d3,用d3来训练第三个弱学习机c3
  4. 通过多数投票来组合弱学习机c1,c2,c3

boosting与bagging模型相比,boosting可以同时降低偏差和方差,bagging只能降低模型的方差,在实际的应用中,boosting算法是存在明显的高方差问题,也就是过拟合。

a、以相同的初始值来初始化样本的权重,并且样本权重和为1 ∑ i = 1 n w i = 1 \sum_{i=1}^nwi=1 i=1nwi=1
b、在m轮boosting操作中,对第j轮做如下操作
c、训练一个加权的弱学习机, C ( j ) = t r a i n ( X , y , w ) C(j) = train(X,y,w) C(j)=train(X,y,w)
d、预测样本类表 pred_y = predict(C(j), X)
e、计算权重错误率: ϵ = ω ∗ ( p r e d = = y ) \epsilon=\omega*(pred == y) ϵ=ω(pred==y)
f、计算相关系数 0.5 ∗ l o g ( 1 − ϵ ) / ϵ = a j 0.5*log(1-\epsilon)/\epsilon = a_j 0.5log(1ϵ)/ϵ=aj
g、更新权重 ϵ ∗ e ( − a j ∗ y ∗ y ′ ) = ϵ \epsilon*e^{(-a_j*y*y')} = \epsilon ϵe(ajyy)=ϵ
h、归一化权重,并保证权重之和为1 ϵ = ϵ / ∑ i = 1 n w i \epsilon = \epsilon/\sum_{i=1}^nw_i ϵ=ϵ/i=1nwi

三、举个实例

import numpy as np
y = np.array([0, 1]*5) # [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

我们假设我们的原始数据是y,然后我们需要找到一个切割点,使我们预测的错误率最低,我们将预测值左边取值为0,将预测值右边取值为1,如果在第一第二个数之间进行预测,则预测结果为[0, 1, 1, 1, 1, 1,1, 1, 1, 1 ],则错误率为60.1,如果在第二个数与第三个数之间进行分割,那么预测的结果为[0, 0, 1, 1, 1, 1, 1, 1, 1, 1],错误率则为 50.1,我们找到一个错误率最低的分割点,在第七个与第八个数之间进行分割,预测值为[0, 0, 0, 0, 0, 0, 0, 1, 0, 1],错误率为0.1*3.

所以我们通过上面的结论进行推导,
错误率为 ϵ = 0.3 \epsilon=0.3 ϵ=0.3
相关系数为: a j = 0.5 ∗ l o g ( 1 − ϵ ) / ϵ = 0.5 ∗ l o g ( 1 − 0.3 ) / 0.3 = 0.424 a_j = 0.5*log (1-\epsilon)/\epsilon = 0.5*log(1-0.3)/0.3 = 0.424 aj=0.5log(1ϵ)/ϵ=0.5log(10.3)/0.3=0.424
单个样本预测错误则更新后的权重为: ω = 0.1 ∗ e ( − 0.424 ∗ ( − 1 ) ∗ 1 ) = 0.153 \omega = 0.1*e^{(-0.424*(-1)*1)}=0.153 ω=0.1e(0.424(1)1)=0.153
单个样本预测正确则更新后的权重为: ω = 0.1 ∗ e ( − 0.424 ∗ 1 ∗ 1 ) = 0.066 \omega = 0.1*e^{(-0.424*1*1) }= 0.066 ω=0.1e(0.42411)=0.066
权重归一化: ∑ i = 1 10 ω i = 7 ∗ 0.065 + 3 ∗ 0.153 = 0.914 \sum_{i=1}^{10}\omega _i = 7*0.065 + 3*0.153=0.914 i=110ωi=70.065+30.153=0.914
预测正确的权重,归一化后的权重为: 0.066 / 0.914 = 0.072 0.066/0.914 = 0.072 0.066/0.914=0.072
预测错误的权重,归一化后的权重为: 0.153 / 0.914 = 0.167 0.153/0.914 = 0.167 0.153/0.914=0.167
通过一轮权重的更新可以发现,之前预测正确的权重由0.1变成了0.072,预测错误的权重由0.1变成了0.167,所以说,在权重更新的过程中,会增大预测错误的样本的权重,同时也会减少预测正确的权重。

四、利用Adaboost进行分析

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline


from sklearn.ensemble import AdaBoostClassifier
from sklearn import tree
X = np.arrange(10).reshape(-1, 1)
y = np.array([1, 1, 1, -1, -1, -1,1, 1, 1, -1 ])

ada = AdaBoostClassifier(n_estimators=3)
ada.fit(X, y)
ada.estimators_  # 可以看到adaboost是由三个决策树组成的

img

plt.figure(figsize=(9, 6))
_ = tree.plot_tree(ada[0])  # 对第一棵树进行划分

img

y_ = ada[0].predict(X)

# 计算误差率
e1 = 0.1 * (y! = y_).sum()
# 计算第一颗树权重
# 随机森林中每颗树的权重是一样的,在adaboost中每棵树的权重是不一样的
a1 = np.round(1/2*np.log((1-e1)/e1), 4)

# 更新权重
w2 = 0.1*n.e**(-a1*y*y_)
# 归一化
w2 = w2/w2.sum()

# 得到第一个分类函数
f1(x) = a1*G1(x) = 0.4236G1(x)
# 进行第二轮迭代
plt.figure(figsize=(9, 6))
_ = tree.plot_tree(ada[1])

img

# 计算误差率, 3, 4, 5预测错误
e2 = 0.0714*3

a2 = 1/2*np.log((1-e2)/e2, 4)
# 计算权重
y_ = ada[1].predict(X)
w3 = w2*np.e**(-a2*y*y_)
w3 = w3/w3.sum()
w3.round(4)
# 计算第三棵树
plt.figure(figsize=(9, 6))
_ = tree.plot_tree(ada[2])

img

y_ = ada[2].predict(X)
e3 = (w3*(y != y_)).sum()
a3 = 1/2*np.log((1-e3)/e3)

# 计算权重
# 弱分类器合并为强分类器
# 加和
# sign 符号函数,如果大于0变为1,小于0变为-1
G(x) = sign[f3(x) = sign[0.4236G1(x) + 0.6496G2(x) + 0.7514G3(x)]]
# 集成树
ada.predict(X) # [1, 1, 1, -1, -1, -1, 1, 1, 1, -1] 
'''
y_predict = a1*ada[0].predict(X) + a2*ada[1].predict(X) + a3*ada[2].predict(X)
np.sign(y_predict).astype(np.int)
[1, 1, 1, -1, -1, -1, 1, 1, 1, -1] # 结果与预测的完成一致
'''

s i g n ∑ i = 1 N a 1 ∗ G 1 ( x ) + a 2 ∗ G 2 ( x ) + … … + a n ∗ G n ( x ) sign\sum_{i=1}^N{a_1*G1(x) + a_2*G2(x) + ……+a_n*Gn(x)} signi=1Na1G1(x)+a2G2(x)++anGn(x)

网上一直流传一张非常容易理解的图。
img
五、以上是adaboost二分类的问题,那如果多分类该怎么预测呢?
img既然是多分类,首先要对样本进行理解,所谓的多分类就是样本集中不止两类样本,比如上面的样本有5类样本。每种颜色代表一类,同时也看到是非线性的,现在进行多分类时的处理办法一般都是将多分类转换为二分类问题,很简单,因为分类问题都会产生一个分类器,产生这个分类器靠的是训练样本,前面的二分类问题就是产生一个分类器,而多分类问题根据训练集产生的不是一个分类器,而是多个分类器。
那第一种方式就是将训练样本集中的某一类当成一类,其他的所有类当成另外一类,像上面的5类,我把最中间的一类当成是第一类,并重新赋予类标签为1,而把四周的四类都认为是第二类,并重新赋予类标签维-1,好了现在的问题是不是就是二分类问题了?是的。那二分类好办,用之前的任何一个算法处理即可。好了,这是把最中间的当成一类的情况下建立的一个分类器。同理,我们是不是也可以把四周任何一类自成一类,而把其他的统称为一类呀?当然可以,这样依次类推,我们共建立了几个分类器?像上面5类就建立了5个分类器吧,好了到了这我们该怎么划分测试集的样本属于哪一类了?注意测试集是假设不知道类标签的,那么来了一个测试样本,我把它依次输入到上述建立的5个分类器中,看看最终它属于哪一类的多,那它就属于哪一类了吧。比如假设一个测试样本本来是属于中间的(假设为第5类吧),那么先输入第五类自成一类的情况,这个时候发现它属于第五类,记录一下5,然后再输入左上角(假设为1类)自成一类的情况,那么发现这个样本时不属于1类的,而是属于2,3,4,5这几类合并在一起的一类中,那么它属于2,3,4,5中的谁呢?都有可能吧,那么我都记一下,此时记一下2,3,4,5。好了再到有上角,此时又可以记一下这个样本输入1,3,4,5.依次类推,最后把这5个分类器都走一遍,就记了好多1~5的标签吧,然后去统计他们的数量,比如这里统计1类,发现出现了3次,2,3,4都出现了3次,就5出现了5次,那么我们就有理由认为这个样本属于第五类,那么现在想想是不是就把多类问题解决了呢?而这个过程参考这位大神博客中的一张图表示就如下:

img 可以看到,其实黑实线本类是我们想要的理想分类面,而按照这种方式建立的分类面是带阴影部分的那个分类面,那阴影部分里面表示什么呢?我们想想,假设一个样本落在了阴影里面,比如我画的那个紫色的点,按照上面计算,发现它属于三角形一类的2次,属于正方形一类的2次,属于圆形一类的1次,那这个时候你怎么办?没招,只能在最大的两次中挑一个,运气好的认为属于三角形,挑对了,运气不好的挑了个正方形,分错了。所以阴影部分是属于模棱两可的情况,这个时候只能挑其中一个了。
这是第一种方式,那还有第二种分类方式,思想类似,也是转化为二分类问题,不过实现上不同。前面我们是挑一类自成一类,剩下的所有自成一类,而这里,也是从中挑一类自成一类,然剩下的并不是自成一类,而是在挑一类自成一类,也就是说从训练样本中挑其中的两类来产生一个分类器。像上述的5类,我先把1,2,类的训练样本挑出来,训练一个属于1,2,类的分类器,然后把1,3,挑出来训练一个分类器,再1,4再1,5再2,3,等等(注意2,1与1,2一样的,所以省去了),那这**样5类样本需要建立多少个分类器呢?n(n-1)/2吧,这里就是54/2=10个分类器,可以看到比上面的5个分类器多了5个。而且n越大,多的就越多。好了建立完分类器,剩下的问题同样采取投票机制,来一个样本,带到1,2建立的发现属于1,属于1类的累加器加一下,带到1,3建立的发现也属于1,在加一下,等等等等。最后看看5个类的累加器哪个最大就属于哪一类。那么一个问题来了,会不会出现像上面那种情况,有两个或者更多个累加器的值是一样的呢?答案是有的,但是这种情况下,出现一样的概率可比上述情况的概率小多了(比较是10个分类器来的结果,怎么也得比你5个的要好吧),同样一个示意图如下:

img可以看到重叠部分就是中间那么一小块,相比上面那种方式小了不少吧。
那么细比较这两种方式,其实各有优缺点。第一种方式由于建立的分类器少(n越大越明显吧,两者相差(n
(n-1)/2 - n)个分类器)。也就是在运算的时候速度更快,而第二种方式虽然速度慢,但是精度高呀,而且现在计算机的速度也够快了,可以弥补第二种方式的缺点,所以个人更倾向于第二种方式了。
*


望您:
“情深不寿,强极则辱,谦谦君子,温润如玉”。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值