利用AdaBoost元算法提高分类性能
2017-08-17 16:43
661 查看
1. 元算法介绍
做重要决定时,大家可能会考虑多个权威的意见而不是一个人的意见,机器学习中也是如此,这就是元算法的背后思想。元算法是对其他算法组合的一种方式。优点:泛化错误低,易编码,可以用在大部分分类器上,无参数调整问题
缺点:对离群点敏感
2. AdaBoost思想 以及 涉及公式
2.1 简单理解
AdaBoost是adaptive boosting(自适应boosting)的缩写,是利用弱分类器和多个实例来构建为一个强分类器,弱强指的是分类效果,AdaBoost算法是与分类器交互并且重点关注分类失败的点来获得新的分类器….(实际就是分类失败的点权重问题)与SVM有着相似的label , 也就是+1/-1化(sign函数把小于0的赋值-1反之+1)
可以把AdaBoost弱分类器类比SVM核函数
- 首先本文选择的弱分类器为单层决策树(DS),实际可以选择任何弱分类器
- 初始化每个分类器权重alpha
- 初始化每个样本的权重D
- 计算弱分类器的分类错误率,根据错误率更新权重D,权重alpha
- 根据新的权重D进行分类
- 每个分类器乘以权重alpha求和(加权求和)
简易流程图
(黑色柱状代表权重D大小)
2.1 公式
错误率定义 : ϵ=分类错误样本数量总样本数量alpha权重更新公式 : α=12ln(1−ϵϵ) 公式1
D权重更新公式 :
样本正确分类 : D(t+1)i=Dti⋅e−αSum(D) 公式2
样本错误分类 : D(t+1)i=Dti⋅eαSum(D)
可以看到 : 错误率减小,alpha变大,样本错误分类的权重D变大…..
下文代码解释 :
代码 multiply(-1 * alpha * mat(label).T, preLabel)
这么理解 -1 * alpha * (mat(label).T * preLabel)
如果labeli是1, preLabeli是-1 正确即为+1 错误为-1
3. 主要算法伪代码
# 建立单层决策树 初始最小误差值inf for 每一个特征 for 每一个待处理的阀值 for 每一个符号(大/小于) 设立阀值 调用函数,产生预测值 预测/实际分类的误差求和 误差打擂台 记录最小的误差 返回 最优DS,最优误差,最优分类 # AdaBoost算法 初始化样本权重D矩阵 建立弱分类器列表 for 0 - numIt 迭代: 调用建立单层决策树函数 计算alpha,保存alpha 弱分类器列表加入上决策树 更新样本权重D 累计错误率 返回弱分类器列表
4. 代码 以及 几个小栗子
# coding:utf-8 from numpy import * def loadSimpleData(): data = matrix([[1.0, 2.1], [2.0, 1.1], [2.0, 1.0], [1.0, 1.0], [1.3, 1.0]]) label = [1.0, 1.0, 1.0, -1.0, -1.0] return data, label def loadData(fileName): dataMat = [] labelMat = [] with open(fileName) as txtFile: for line in txtFile.readlines(): temp = line.split() dataMat.append(map(float, temp)[0:-1]) labelMat.append(map(float, temp)[-1]) return dataMat, labelMat def sigTreeClassify(data, index, splitValue, splitSign): labelPre = ones((shape(data)[0], 1)) if splitSign == 'small': labelPre[data[:, index] <= splitValue] = -1.0 # 符号无所谓 用1与-1区分类别 与SVM相似 else: labelPre[data[:, index] > splitValue] = -1.0 # 有区别就行 return labelPre def buildTree(data, label, D): # D 样本权重 data = mat(data) label = mat(label).T m, n = shape(data) numSteps = 10.0 bestTree = {} # 最优的弱分类器 bestLabel = mat(zeros((m, 1))) # 最优预测label minError = inf # 打擂台专属 for index in range(n): rangeMin = data[:, index].min() rangeMax = data[:, index].max() stepSize = (rangeMax - rangeMin) / numSteps for j in range(-1, int(numSteps) + 1): for sign in ["small", "large"]: value = rangeMin + float(j) * stepSize # j:-1~numstep+1 value稍微超出范围 labelPre = sigTreeClassify(data, index, value, sign) errArr = ones((m, 1)) errArr[labelPre[:] == label[:]] = 0 # 预测正确为0 反之为1 weightError = D.T * errArr # 可以看得出来01的作用, 方便加权求和 if minError > weightError: # 更新最小误差 以及 最优树 minError = weightError bestLabel = labelPre bestTree['value'] = value # 字典存取单层决策树的信息 bestTree['index'] = index bestTree['sign'] = sign ''' if U have some questions ''' # print "inloop: index:%d, value:%f, sign:%s" % (index, value, sign) # 循环中的变量 # print "label :", label.T # 正确值 # print "labelPre :", labelPre.T # 预测值 # print "errArr :", errArr.T # 预测是否正确 # print "D :", D.T # D # print "weightError :", weightError # alpha加权误差 # print "minError :", minError, '\n----------------------------------------------' # print "bestTree :", bestTree # print "minError :", minError # print "bestLabel :", bestLabel.T, "\n++++++++++++++++++++++++++++" ''' have a look ''' return bestTree, minError, bestLabel def AdaBoostTrainDS(data, label, numIt=40): # numIt实际就是生成单层决策树的个数 weakClassArr = [] # 弱分类器列表 m = shape(data)[0] D = mat(ones((m, 1)) / m) # 样本权重和为1 每个样本有一个权重 aggClassEst = mat(zeros((m, 1))) for i in range(numIt): bestTree, error, preLabel = buildTree(data, label, D) # 生成一个单层决策树 alpha = float(0.5 * log((1.0 - error) / max(error, 1e-16))) # max()防止分母0,公式1:更新alpha bestTree['alpha'] = alpha weakClassArr.append(bestTree) # 弱分类器加入带有alpha的最优树 expon = multiply(-1 * alpha * mat(label).T, preLabel) # 公式2:样本权重更新 见公式2详解 D = multiply(D, exp(expon)) / D.sum() aggClassEst += alpha * preLabel # 运行时的类别估计值 sign函数处理之前 aggErrors = multiply(sign(aggClassEst) != mat(label).T, ones((m, 1))) # 预测label的误差和 errorRate = aggErrors.sum() / m # 预测正确为0 不正确为1 再乘以one矩阵得到矩阵 ''' if U have some questions ''' # print "loop number is :", i # print "label :", label # print "preLabel :", preLabel.T # print "expon :", expon.T # print "alpha :", alpha # print "D :", D.T # print "aggClassEst :", aggClassEst.T # print "sign(aggClassEst) :",sign(aggClassEst) # print "aggClassEst != label :",sign(aggClassEst) != mat(label).T # print "aggErrors :", aggErrors.T # print "errorRate :", errorRate, "\n----------------------------------------------" ''' have a look above ''' if errorRate == 0.0: break # print "numIt is :", numIt,"\ntrainError rate is :",errorRate return weakClassArr def AdaBoostClassify(data, classifierArr): # classifierArr 就是所有单层决策树的列表 data = mat(data) m = shape(data)[0] aggClassEst = mat(zeros((m, 1))) # print "len",len(classifierArr) for i in range(len(classifierArr)): labelPre = sigTreeClassify(data, classifierArr[i]['index'], classifierArr[i]['value'], classifierArr[i]['sign']) aggClassEst += classifierArr[i]['alpha'] * labelPre ''' have a look ''' # print "loopNum is :",i # print "labelPre :", labelPre.T # print "aggClassEst :",aggClassEst.T # print "sign(aggClassEst) :",sign(aggClassEst).T ''' ok ''' return sign(aggClassEst) # -1 ~ 1 if __name__ == '__main__': data, label = loadSimpleData() # 加载简单数据集 ''' 建单层决策树验证 ''' D = mat(ones((shape(data)[0], 1)) / shape(data)[0]) bestTree, minError, bestLabel = buildTree(data, label, D) print "bestTree :", bestTree, '\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++' ''' 简单数据训练+预测 ''' classifierArr = AdaBoostTrainDS(data, label, 10) # 训练模型 data = matrix([ [1.0, 2.1], [2.0, 1.1], [2.0, 1.0], [1.0, 1.0], [1.3, 1.0], [0.8, 1.4], [1.0, 0.5] ]) label = [1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0] labelPre = AdaBoostClassify(data, classifierArr) # 进行预测 print "label :", mat(label) print "prelabel :", labelPre.T, '\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++' ''' 复杂数据训练+预测 ''' trainData, trainLabel = loadData("horseTrain.txt") testData, testLabel = loadData("horseTest.txt") m = shape(testData)[0] for numIt in [1, 10, 50, 100, 500, 1000, 10000]: classifierArr = AdaBoostTrainDS(trainData, trainLabel, numIt) # 训练模型 labelPre = AdaBoostClassify(testData, classifierArr) # 进行预测 errArr = mat(ones((m, 1))) errorSum = errArr[labelPre != mat(testLabel).T].sum() print "testError rate is :", 1.0 * errorSum / 67, '\n----------------------------------------'
5. 结果分析 以及 辅助理解图像
# 输出结果 # 如详细理解过程可以在代码中撤销注释获得打印输出 ''' bestTree : {'index': 0, 'value': 1.3, 'sign': 'small'} +++++++++++++++++++++++++++++++++++++++++++++++++++++++ label : [[ 1. 1. 1. -1. -1. 1. -1.]] prelabel : [[ 1. 1. 1. -1. -1. -1. -1.]] +++++++++++++++++++++++++++++++++++++++++++++++++++++++ numIt is : 1 trainError rate is : 0.284280936455 testError rate is : 0.268656716418 ---------------------------------------- numIt is : 10 trainError rate is : 0.234113712375 testError rate is : 0.238805970149 ---------------------------------------- numIt is : 50 trainError rate is : 0.207357859532 testError rate is : 0.208955223881 ---------------------------------------- numIt is : 100 trainError rate is : 0.1872909699 testError rate is : 0.238805970149 ---------------------------------------- numIt is : 500 trainError rate is : 0.157190635452 testError rate is : 0.253731343284 ---------------------------------------- numIt is : 1000 trainError rate is : 0.133779264214 testError rate is : 0.268656716418 ---------------------------------------- numIt is : 10000 trainError rate is : 0.110367892977 testError rate is : 0.328358208955 ---------------------------------------- ''' # 分析 ''' 第一个栗子中 打印了最优DS的分类特征,分类阀值,分类符号小于号 第二个栗子中 很显然最后一个预测失误了 第三个栗子中 numIt从1~10000过程中,对于训练数据拟合越来越好,而相对于测试数据在出现最优错误率之后又下降了,很显然的过拟合....(相关文献证明AdaBoost错误率回达到一个稳定值,不会随着分类器的个数增加而变优) '''
简单数据集的坐标图像
6. 附 数据集
数据集 请点击这里元算法介绍
AdaBoost思想 以及 涉及公式
1 简单理解
1 公式
主要算法伪代码
代码 以及 几个小栗子
结果分析 以及 辅助理解图像
附 数据集
相关文章推荐
- 利用AdaBoost元算法提高分类性能
- 利用AdaBoost元算法提高分类性能
- 利用Adaboost元算法提高分类性能
- 第七章 利用AdaBoost元算法提高分类性能
- 机器学习实战——利用AdaBoost元算法提高分类性能
- 读书笔记:机器学习实战【第7章:利用Adaboost元算法提高分类性能】
- 《机器学习实战》学习笔记:利用Adaboost元算法提高分类性能
- 机器学习实战(7) ——利用AdaBoost元算法提高分类性能(python实现)
- 利用adaboost元算法提高分类性能
- 《机器学习实战》笔记之七——利用AdaBoost元算法提高分类性能
- 机器学习实战第七章 - 利用AdaBoost元算法提高分类性能
- 《机器学习实战》笔记之七——利用AdaBoost元算法提高分类性能
- 机器学习实战笔记-利用AdaBoost元算法提高分类性能
- 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能
- 机器学习实战代码详解(七)利用AdaBoost元算法提高分类性能
- 利用AdaBoost元算法提高分类性能
- 《机器学习实战》笔记之七——利用AdaBoost元算法提高分类性能
- 机器学习实战(七)利用AdaBoost元算法提高分类性能
- 《机器学习实战》笔记之七——利用AdaBoost元算法提高分类性能
- 机器学习之利用AdaBoost元算法提高分类性能