小言_互联网的博客

机器学习之adaboost代码实现

614人阅读  评论(0)

本博客主要实现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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场