算法基本原理如下:
第1行初始化样本权重,m表示样本总数。
第2到11行表示的是每一轮训练过程,t表示当前训练的轮数,T表示总的训练轮数
第4行计算训练误差
第5行计算当前基础模型的组合系数
第6到8行更新样本权重
其中,data就是输入的训练数据,Dt则是第t个基础模型对应的训练样本的权重。这里定义的基础模型非常简单,即找到一个阈值,以该阈值为分类边界进行分类。
import numpy as np
import matplotlib.pyplot as plt
# 基函数
def base_model(data,dt):
m=data.shape[0]
pred=[]
pos,mark,min_err=0,0,np.inf
for j in range(m):
pred_temp=[]
left_sum=np.sum(data[:j,1])
right_sum=np.sum(data[j:,1])
if left_sum<right_sum:
sub_mark=-1
pred_temp.extend([-1]*j)
pred_temp.extend([1]*(m-j))
else:
sub_mark=1
pred_temp.extend([1]*j)
pred_temp.extend([-1]*(m-j))
err=np.sum(1*(data[:,1]!=pred_temp)*dt)
if err<min_err:
min_err=err
pos=(data[:,0][j-1]+data[:,0][j])/2
mark=sub_mark
pred=pred_temp[:]
model=[pos,mark,min_err]
return model,pred
#权值修正,提升基础模型
def adaboost(data):
models=[]
m=data.shape[0]
D=np.zeros(m)+1.0/m
T=3
y=data[:,1]
for t in range(T):
dt=D[:]
model,y_=base_model(data,dt)
print(model)
err=model[-1]
alpha=0.5*np.log((1-err)/err)
zt=np.sum([dt[i]*np.exp(-alpha*y[i]*y_[i]) for i in range(m)])
D=np.array([dt[i]*np.exp(-alpha*y[i]*y_[i]) for i in range(m)])/zt
models.append([model,alpha])
return models
# 组合T个基础模型
def adaboost_predict(models,X):
pred_=[]
for x in X:
res=0
for base in models:
alpha_=base[1]
if x[0]>base[0][0]:
res-=base[0][1]*alpha_
else:
res+=base[0][1]*alpha_
pred_.append(np.sign(res))
return pred_
data=np.array([[0,1],[1,1],[2,1],[3,-1],[4,-1],[5,-1]
,[6,1],[7,1],[8,1],[9,-1]],dtype=np.float32)
plt.scatter(data[:,0],data[:,1],c=data[:,1],cmap=plt.cm.Paired)
plt.xlabel('x')
plt.ylabel('y')
plt.show()
models=adaboost(data)
X=data
y=data[:,1]
y_pred=adaboost_predict(models,X)
acc=np.sum(1*(y==y_pred))/float(len(X))
print(acc)