Adaboosting算法原理代码实现 - Go语言中文社区

Adaboosting算法原理代码实现


导包

from sklearn.ensemble import AdaBoostClassifier
import numpy as np
from sklearn import tree

生成数据

X = np.arange(10).reshape(-1,1)
y = np.array([1,1,1,-1,-1,-1,1,1,1,-1])

声明算法,进行训练

ada = AdaBoostClassifier(algorithm='SAMME',n_estimators=3)
ada.fit(X,y)

第一棵树划分

_ = tree.plot_tree(ada[0])
ada[0].predict(X)

第一棵树划分手动计算

# 样本的初始权重,还没有开始进行训练,所以,所有样本权重一样?
w1 = np.full(shape = 10,fill_value=0.1)
# 样本中10个数据,划分,0到1之间(threshold阈值0.5)划分;1到2之间(1.5)划分……
# 如果阈值0.5,构建树,结果:
y1 = np.array([1,-1,-1,-1,-1,-1,-1,-1,-1,-1]) #预测结果
e1 = ((y != y1)*d1).sum()#误差
print('方式一',e1)
e1 = (y != y1).mean()
print('方式二',e1)
# 如果阈值1.5,构建树,结果:
y2 = np.array([1,1,-1,-1,-1,-1,-1,-1,-1,-1])
e2 = ((y != y2)*d1).sum()
print('方式一',e2)
e2 = (y != y2).mean()
print('方式二',e2)
# 第一颗树划分时,阈值选择了2.5
# 决策树的裂分,有一个标准!
# for 循环目的:找到分类条件:2.5或者8.5
thresholds = np.arange(0.5,10)
for i,t in enumerate(thresholds,start = 1):#enumerate,获取索引,默认从0开始, 
#     y_是弱分类器,预测值
    y_ = np.array([1]*i + [-1]*(10-i))
#     y_ = np.zeros(shape = 10)
#     y_[(X <=t).reshape(-1)] = 1
#     y_[(X > t).ravel()] = -1
    print(t,((y !=y_)*w1).sum())

根据输出的结果,结论,阈值是2.5或者8.5,误差最小的:0.3

选择2.5或者8.5作为裂分条件,代码中一般选择,前面的索引

更新样本的权重

# 在w1的基础上,进行更新 w1 = [0.1,0.1,0.1……]
y_ = np.array([1]*3 + [-1]*(10-3))
w2 = w1*np.exp(-y*y_*a1)
w2 = w2/w2.sum()
print(w2)

第二棵树划分

_= tree.plot_tree(ada[1])#样本权重,发生变化了

手动计算,第二棵树的划分

第二棵树,根据第一棵树的返回结果,进行,学习

第一棵树,更新了样本的权重!w2

thresholds = np.arange(0.5,10)
for i,t in enumerate(thresholds,start = 1):#enumerate,获取索引,默认从0开始, 
#     y_是弱分类器,预测值
    y_ = np.array([1]*i + [-1]*(10-i))
#     y_ = np.zeros(shape = 10)
#     y_[(X <=t).reshape(-1)] = 1
#     y_[(X > t).ravel()] = -1
    print(t,((y !=y_)*w2).sum())
# 阈值,如果是8.5,那么左边9个数,右边是1个数,计算误差率
y_ = np.array([1]*9 + [-1]*(10-9))#预测值
display(y,y_)
e2 = ((y != y_)*w2).sum()
print('第二棵树的误差率:',e2)
print('样本的权重是:',w2.round(4))
#计算第二棵树的权重
a2 =np.round( 1/2*np.log((1 - e2)/e2),4)
print('第二棵树,权重是:',a2)

更新第二棵树的样本的权值分布,根据第一棵树的结果w2进行更新

y_ = np.array([1]*9 + [-1]*(10-9))#预测值
w3 = w2*np.exp(-y*y_*a2)
w3 = w3/w3.sum()
print('第二棵树,更新样本权重,更新样本分布:',w3)

第三棵树划分

_ = tree.plot_tree(ada[2])
thresholds = np.arange(0.5,10)
for i,t in enumerate(thresholds,start = 1):#enumerate,获取索引,默认从0开始, 
#     y_是弱分类器,预测值
    y_ = np.array([1]*i + [-1]*(10-i))
#     y_ = np.zeros(shape = 10)
#     y_[(X <=t).reshape(-1)] = 1
#     y_[(X > t).ravel()] = -1
    print(t,((y !=y_)*w3).sum())#误差率 + 准确率 = 1
e3 = 0.1820
# 计算第三棵树的权重
y_ = np.array([-1]*6 + [1]*(10-6))
a3 = 1/2*np.log((1 - e3)/e3)
print('第三棵树的权重是:',a3)
# 更新第三棵树的,样本权值分布,权重
w4 = w3*np.exp(-y*y_*a3)
w4 = w4/w4.sum()
print('第三棵树,更新样本权重:',w4.round(3))

集成算法

F ( x ) = ∑ t = 1 N α t f t ( x ) F(x) = \sum\limits_{t = 1}^N\alpha_tf_t(x) F(x)=t=1Nαtft(x)

print(a1,a2,a3)
# 第一棵树ft(x)
y1 = np.array([1]*3 + [-1]*(10-3))
# 第二棵树的预测值
y2 = np.array([1]*9 + [-1]*(10-9))#预测值
# 第三棵树,预测值
y3 = np.array([-1]*6 + [1]*(10-6))
# 将多个弱分类器,整合,变成了强分类器F(X)
F =  a1*y1 + a2*y2 + a3*y3
F

手动预测和模型预测结果进行对比

#手动预测最终结果
result = [-1 if i<0 else 1 for i in F]
result
#这个模型预测的返回值
ada.predict(X)
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xswl0/article/details/105206706
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2023-01-02 15:51:46
  • 阅读 ( 169 )
  • 分类:算法

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢