Boosting概念
提升学习(Boosting)是一种机器学习技术,可以用于回归和分类的问题,它也是多个弱学习器组合而成,但是跟bagging不同的是,bagging的学习器是相互独立的,但是boosting的每个学习器是基于前面的学习器生成的。
AdaBoost
它给样本加了一个权重,如果前面的学习器已经能把样本分对,那么权重会降低,如果不能分对就会把权重升高,更着重的去考虑分错的样本,然后把多个弱学习器组合形成一个强学习器。
AdaBoost算法推导
最终的增强学习器是:
G(x)=sign(f(x))=sign[∑m=1MαmGm(x)]
其中sign是一个-1/1的函数,如果sign(x),x>0则sign(x)预测为1(正样本),x<0则预测为-1(负样本), αm 是每个分类器的权重值,一共有M个分类器。
损失函数:
loss=1n∑i=1nI(G(xi)≠yi)
I 函数是如果分对则为0,如果分错则为1,损失函数可以直观的理解成错误率,分错的样本占总样本的比例。
损失函数变换:
loss=1n∑i=1ne−yif(x)
yi 如果整理是1,负例是-1,可以看到如果分类正确, −yif(x) 会是一个比较大的负数,则 e−yif(x) 比较接近于0,如果分类错误则是一个正数,与I函数的性质相似。
求每个分类器的权重 αm :
假设已经进行到k-1轮,这时候学习器是:
fk−1(x)=∑j=1k−1αjGj(x)
这时候第k轮的学习器应该是:
fk(x)=∑j=1k−1αjGj(x)+αkGk(x)=fk−1(x)+αkGk(x)
损失函数应该是:
loss=1n∑i=1ne−yi(fk−1(x)+αkGk(x))
可以拆分为:
loss=1n∑i=1ne−yifk−1(x)e−yiαkGk(x)
前面的部分是一个常数,前面的学习器组合而成,写成E。后面的部分重新写会成 I 函数,然后可以变成:
ϵt 是当前的错误率,对 αm 求偏导,令偏导数它等于0可以得到:
αm=12ln(1−ϵtϵt)
得到第m个学习器。
构建过程:
1、平均分配每个样本的权重
2、构建当前的分类器,计算误差,通过
αm=12ln(1−ϵtϵt)
,得到当前分类器的权重。
3、根据
αm
去跟新权重,更多的考虑分错的项。
wm+1,i=wm,iZme−αmyiGm(xi)
其中 Zm 是归一化因子。
4、重复执行过程直到错误率低于一定值或者跌代次数达到一定值。
样例:
制作虚拟数据:
import pandas as pd
import numpy as np
x = np.arange(0,10).reshape(1,-1)
y = np.array([1,1,1,-1,-1,-1,1,1,1,-1]).reshape(1,-1)
z = np.array([1/10]*10).reshape(1,-1)
data = np.concatenate((x,y,z),axis=0)
df = pd.DataFrame(data,index=['data','label','weight'])
df
# 假设用决策树的方法,用信息熵的衡量标准去构建决策树
# 计算信息熵的函数
def h(p_list):
return np.sum([-p*np.log2(p) for p in p_list])
# 找到信息增益最大的点,也就是条件熵最小的点:
# 在2.5处的条件熵:
Ht2_5 = h([3/7,4/7]) * 7 / 10 # 0.68965969522397608
# 在5.5处的条件熵:
Ht5_5 = h([0.5,0.5]) * 6 / 10 + h([1/4, 3/4]) * 4 / 10 # 0.92451124978365318
# 所以在2.5处划分。
# 计算误差率:(有三个分错,权重都是0.1) : 0.3
# 根据误差率,计算alpha的值
def g(e):
return 0.5 * np.log2((1-e)/e)
a1 = g(0.3) #0.61119621066822405
# 跟新权重
def update_weight(w, result, alpha):
z_m = 0
for i in range(w.shape[1]):
z_m += w[0][i] * np.exp(- alpha * result[0][i])
w_new = w * np.exp(- result * alpha) / z_m
return w_new
result = np.array([1,1,1,1,1,1,-1,-1,-1,1]).reshape(1,-1)
w = np.array(df.ix[[2]])
w_new = update_weight(w, result, a1)
print(w_new)
# [[ 0.05818722 0.05818722 0.05818722 0.05818722 0.05818722 0.05818722
# 0.19756314 0.19756314 0.19756314 0.05818722]]
# 可以看到,误分类的点权重加大了,正确分类的点,权重减小了。更加着重的去考虑错误分类的点。
最后的结果:
f(x)=0.6112G1(x)+1.1205G2(x)+1.631G3(x)