机器学习--集成学习AdaBoost

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=1ni=1nI(G(xi)yi)

I 函数是如果分对则为0,如果分错则为1,损失函数可以直观的理解成错误率,分错的样本占总样本的比例。

损失函数变换:

loss=1nni=1I(G(xi)yi) 不利于作数学运算,转化成具有相同性质易于作数学运算的形式:

loss=1ni=1neyif(x)

yi 如果整理是1,负例是-1,可以看到如果分类正确, yif(x) 会是一个比较大的负数,则 eyif(x) 比较接近于0,如果分类错误则是一个正数,与I函数的性质相似。

求每个分类器的权重 αm

假设已经进行到k-1轮,这时候学习器是:

fk1(x)=j=1k1αjGj(x)

这时候第k轮的学习器应该是:
fk(x)=j=1k1αjGj(x)+αkGk(x)=fk1(x)+αkGk(x)

损失函数应该是:
loss=1ni=1neyi(fk1(x)+αkGk(x))

可以拆分为:
loss=1ni=1neyifk1(x)eyiαkGk(x)

前面的部分是一个常数,前面的学习器组合而成,写成E。后面的部分重新写会成 I 函数,然后可以变成:
loss=eαm(1ϵt)+eαmϵt

ϵ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)

这里写图片描述

猜你喜欢

转载自blog.csdn.net/xiayto/article/details/79529798
今日推荐