本博客主要实现adaboost算法依据以下数据集,如果关于adaboost算法有一些理论知识还不是很明白的,可以参考一下这篇博客
程序是我自己根据公式编写的,如果有错误的地方欢迎指正。目前感觉代码能力很一般,以后还会进一步对这个程序进行修改。
采用机器学习书中的算法步骤:
第一步:定义标签和数据集
def dataset():
data=[0,1,2,3,4,5,6,7,8,9]
labels=[1,1,1,-1,-1,-1,1,1,1,-1]
return data,labels
第二步:输入标签和数据集构造最优决策树。因为这里的样本是连续值,因此连续属性离散化技术在这里派上了用场。只需要求得该样本的候选划分点集合就可以了。候选划分点是每两者之间的平均值。
point=(np.array(data[:-1])+np.array(data[1:]))/2 #取data中相邻两者之间的平均值
结果:array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5])
一共有九个划分点
将每个划分点依次遍历,每个划分点分两种情况,第一将划分点左边的归为1,右边的归为-1;第二将划分点左边的归为-1,右边的归为1,最后取两者中loss最小的结果。bestpoint 返回总loss最小的值
for i in point: #遍历平均值
predict1=np.array(data<i) #判断左边为1
predict1=(predict1+0)+(predict1-1) #将结果转换为[1,-1]
result1=sum(abs(predict1-label)/2*D1) #误差
predict2 = np.array(data > i) #判断右边为1
predict2 = (predict2 + 0) + (predict2 - 1)
result2 = sum(abs(predict2 - label) / 2 * D1)
if result1<=result2: #保存符号和左右边哪个结果更好
dic[i]=result1
sign[i]='<'
else:
dic[i]=result2
sign[i]='>'
bestpoint = sorted(dic.items(),key=operator.itemgetter(1))
本程序的全部代码:
import pdb
import numpy as np
import operator
import math
def dataset():
data=[0,1,2,3,4,5,6,7,8,9]
labels=[1,1,1,-1,-1,-1,1,1,1,-1]
return data,labels
def mytree(data,label,D1): #生成最优决策树
point=(np.array(data[:-1])+np.array(data[1:]))/2 #取data中相邻两者之间的平均值
dic={}
sign={}
for i in point: #遍历平均值
predict1=np.array(data<i) #判断左边为1
predict1=(predict1+0)+(predict1-1) #将结果转换为[1,-1]
result1=sum(abs(predict1-label)/2*D1) #误差
predict2 = np.array(data > i) #判断右边为1
predict2 = (predict2 + 0) + (predict2 - 1)
result2 = sum(abs(predict2 - label) / 2 * D1)
if result1<=result2: #保存符号和左右边哪个结果更好
dic[i]=result1
sign[i]='<'
else:
dic[i]=result2
sign[i]='>'
bestpoint = sorted(dic.items(),key=operator.itemgetter(1))
return bestpoint[0],sign[bestpoint[0][0]]
def Zm1(label,Gm,a,D1): #返回当前样本的权重
sum=0
for i in range(len(label)):
sum+=D1[i]*math.e**(-a*label[i]*Gm[i])
newD1=[]
for i in range(len(label)):
w=D1[i]/sum*math.e**(-a*label[i]*Gm[i])
newD1.append(w)
return newD1
def adaboot1():
data,label=dataset() #获取数据集和标签文件
D1=[1/len(data)]*len(data) #求每一个样本的初始权重,0.1
bestpoint=[] #保存目前最佳的分割点
besta=[] #保存每一棵基决策树对应的权重
signall=[] #保存每一个最佳分割点对应的符号(大于或小于)
result=[] #保存每个基决策树对样本分类的结果
for i in range(20):
ht,sign=mytree(data,label,D1) #当前最好的树
signall.append(sign) #保存记号
bestpoint.append(ht[0]) #保存当前最佳分割点
if sign==str('>'):
Gm= np.array(data > ht[0])
Gm = (Gm+0) + (Gm-1)
else:
Gm= np.array(data < ht[0])
Gm = (Gm+ 0) + (Gm- 1) #样本带入树中得到当前样本结果
a=0.5*(math.log((1-ht[1])/ht[1])) #通过误差计算得到基决策树权值
besta.append(a)
result.append(Gm)
D1=Zm1(label,Gm,a,D1) #计算得到每个样本点的权值
sum1=[0]*len(data) #以下循环计算当前结果是否达到最优
for i in range(len(result)):
sum1+=result[i]*besta[i] #result=w1f(x1)+w2f(x2)+..
sum1 = np.array(sum1>=0)
sum1 = (sum1 + 0) + (sum1- 1)
if sum(sum1==label)==len(data): #如果结果相等,则输出以下语句
print("一种生成{}棵基函数".format(len(result)))
for i in range(len(result)):
dic = {}
print ("第{}棵决策树是".format(i+1))
if signall[i]==str('>'):
dic['num'+'>' + str(bestpoint[i])]=1
dic['num'+'<' + str(bestpoint[i])] = -1
if signall[i] == str('<'):
dic['num'+'<' + str(bestpoint[i])] = 1
dic['num'+'>' + str(bestpoint[i])] = -1
print(dic)
print ("权值是{}".format(besta[i]))
print()
break
adaboot1()
结果:
可以增加样本如:
结果如下:
转载:https://blog.csdn.net/qq_37960402/article/details/88539253
查看评论