【机器学习】AdaBoost算法分析与实现

AdaBoost算法分析与实现

Email:chentravelling@163.com


年前年后已经把AdaBoost看了两三遍,昨天花了两个小时用python实现了一下。因为对python不太熟,跟网上的的代码一比较就发现自己的代码是多么粗糙了。不过没关系了,慢慢来。

一、AdaBoost的历史

Boosting方法是一种常用的统计学习方法,其基于这样的一个思想:对于一个复杂任务来说,将多个专家的判断进行适当的综合所得出的判断,要比其中任何一个专家单独的判断要好——三个臭皮匠顶个诸葛亮。

Boosting涉及到两个概念:弱学习和强学习。弱学习就是指一个学习算法对一组概念的识别率只比随机识别好一点,所谓强学习,就是指一个学习算法对一组概率的识别率很高。Kearns和Valiant提出了弱学习和强学习等价的问题 ,并证明了只要有足够的数据,弱学习算法就能通过集成的方式生成任意高精度的强学习方法

二、AdaBoost算法

2.1算法描述

【机器学习】AdaBoost算法分析与实现_第1张图片

【机器学习】AdaBoost算法分析与实现_第2张图片

2.2例子

对于我这个小菜鸟来说,看看这么一大段的流程还是有些晕,于是拿着李航的例子算了一笔:

【机器学习】AdaBoost算法分析与实现_第3张图片

【机器学习】AdaBoost算法分析与实现_第4张图片

【机器学习】AdaBoost算法分析与实现_第5张图片

【机器学习】AdaBoost算法分析与实现_第6张图片

三、代码实现

对于python不熟悉,代码极其粗糙,见谅咯。


# -*- coding:utf-8 -*-
# Author:code 陈
# Date:2016.02.21

from math import log,exp

# 数据集
def createDataSet():
    dataSet=[[0,1],[1,1],[2,1],[3,-1],[4,-1],[5,-1],[6,1],[7,1],[8,1],[9,-1]]
    weightSet=[0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1]
    return dataSet,weightSet

# 选择最佳阈值
# return 误差率  阈值
def chooseBsetThreshold(dataSet,weightSet):
    length = len(dataSet)
    minError = 1
    bestThreshold = 0
    for i in range(0,length):
        error = [0,0]
        for j in range(0,length):
            if j<i:
                if dataSet[j][1]!=1:##0:阈值左侧为1,右侧为-1;1:阈值左侧为-1,右侧为1
                    error[0] = error[0] + weightSet[j]
                if dataSet[j][1]!=-1:
                    error[1] = error[1] + weightSet[j]
            else:
                if dataSet[j][1]!=-1:
                    error[0] = error[0] + weightSet[j]
                if dataSet[j][1]!=1:
                    error[1] = error[1] + weightSet[j]
        if error[0]>error[1]:
            mer = error[1]
            index = 1;
        else:
            mer = error[0]
            index = 0
        if minError > mer:
            minError = mer
            bestThreshold = dataSet[i][0]
    return minError,bestThreshold,index
# 弱分类器
# param:数据、阈值、左侧为1?右侧为1?
def weakClassifier(data,bestThreshold,index):
    if index ==0:
        if data<bestThreshold:
            return 1
        else:
            return -1
    else:
        if data<bestThreshold:
            return -1
        else:
            return 1

# 更新权值
def updateWeightSet(minError,dataSet,weightSet,bestThreshold,index):
    alpha =float( 0.5*log((1-minError)/max(minError,1e-16)))
    print  alpha
    newWeightSet = []
    Z = 0
    for i in range(0,len(dataSet)):
        Z = Z + weightSet[i]*exp(-alpha*dataSet[i][1]*weakClassifier(dataSet[i][0],bestThreshold,index))
    for j in range(0,len(dataSet)):
        newWeightSet.append(weightSet[j]/Z*exp(-alpha*dataSet[j][1]*weakClassifier(dataSet[j][0],bestThreshold,index)))
    return newWeightSet,alpha
# 验证错误分类点个数
def countErr(weakClassifierArr,dataSet):
    n = 0
    for i in range(0,len(dataSet)):
        G = 0
        for j in range(0,len(weakClassifierArr)):
            G = G + weakClassifierArr[j]['alpha']*weakClassifier(dataSet[i][0],weakClassifierArr[j]['threshold'],weakClassifierArr[j]['index'])
        if  G * dataSet[i][1] <0:#异号就可以了,没有用sign函数
            n = n + 1
    return n

# AdaBoost
def AdaBoost(dataSet,weightSet,M):
    weakClassifierArr = []#存弱分类器
    G = 0
    for i in range(0,M):
        weakClassE = {}
        minError,bestThreshold,index = chooseBsetThreshold(dataSet,weightSet)
        print minError,\
            bestThreshold,\
            index
        weightSet,alpha = updateWeightSet(minError,dataSet,weightSet,bestThreshold,index)
        weakClassE['threshold']=bestThreshold
        weakClassE['index']= index
        weakClassE['alpha'] = alpha
        weakClassifierArr.append(weakClassE)
        print countErr(weakClassifierArr,dataSet)
        print weightSet
        if countErr(weakClassifierArr,dataSet) ==0:
            #print weakClassifierArr
            break
    return weakClassifierArr
if __name__=='__main__':
    dataSet,weightSet = createDataSet()
    weakClassifierArr = AdaBoost(dataSet,weightSet,6)

最后的数据和前面计算的结果一致:#代码中没有精确小数点位数

【机器学习】AdaBoost算法分析与实现_第7张图片

最终得到的分类器:

[{'threshold': 3, 'index': 0, 'alpha': 0.4236489301936017}, {'threshold': 9, 'index': 0, 'alpha': 0.6496414920651304}, {'threshold': 6, 'index': 1, 'alpha': 0.752038698388137}]

得到分类器后就应该是对测试数据进行预测了。


四、疑问

4.1权值和误差

【机器学习】AdaBoost算法分析与实现_第8张图片

【机器学习】AdaBoost算法分析与实现_第9张图片

4.2弱分类器

关于弱分类器G,一开始我也没懂,到底改怎么去选择,后来查了一下网上的资料,大部人提到了CART、SVM、回归等等都可以作为弱分类。

4.3多维的训练数据

例子中的训练数据是一维的,如果是多维的呢?查了一下资料,结果为:每次在多维中选择带权分类误差值最小的一维,然后在该维度下选择带权分类误差最小的阈值,绕了半天,这一点自己倒还没去实现过。

代码可能还有问题,原理上可能也还存在认知问题,后面再慢慢调整理解。





你可能感兴趣的:(python,机器学习,adaboost)