机器学习笔记(9)-集成方法[AdaBoost与随机森林]
分类器相关概述
将不同的分类器组合起来,而这种组合结果则被称为集成方法(ensemble method)或者元算法(meta-algorithm )。
集成方法:
1,投票选举(bagging: 自举汇聚法 bootstrap aggregating): 是基于数据随机重抽样分类器构造的方法。目前 bagging 方法最流行的版本是: 随机森林(random forest)【选男友:美女选择择偶对象的时候,会问几个闺蜜的建议,最后选择一个综合得分最高的一个作为男朋友】
2,再学习(boosting): 是基于所有分类器的加权求和的方法。目前 boosting 方法最流行的版本是: AdaBoost。【追女友:3个帅哥追同一个美女,第1个帅哥失败->(传授经验:姓名、家庭情况) 第2个帅哥失败->(传授经验:兴趣爱好、性格特点) 第3个帅哥成功】
bagging 和 boosting 区别是什么?
1,bagging 是一种与 boosting 很类似的技术, 所使用的多个分类器的类型(数据量和特征量)都是一致的。
2,bagging 是由不同的分类器(1.数据随机化 2.特征随机化)经过训练,综合得出的出现最多分类结果;boosting 是通过调整已有分类器错分的那些数据来获得新的分类器,得出目前最优的结果。
3,bagging 中的分类器权重是相等的;而 boosting 中的分类器加权求和,所以权重并不相等,每个权重代表的是其对应分类器在上一轮迭代中的成功度。
随机森林原理
随机森林指的是利用多棵树对样本进行训练并预测的一种分类器。假设随机森林中有3棵子决策树,2棵子树的分类结果是A类,1棵子树的分类结果是B类,那么随机森林的分类结果就是A类。
数据的随机化:
1,采取有放回的抽样方式 构造子数据集,保证不同子集之间的数量级一样(不同子集/同一子集 之间的元素可以重复)。
2,利用子数据集来构建子决策树,将这个数据放到每个子决策树中,每个子决策树输出一个结果。
3,然后统计子决策树的投票结果,得到最终的分类 就是 随机森林的输出结果。
待选特征的随机化:
1,子树从所有的待选特征中随机选取一定的特征。
2,在选取的特征中选取最优的特征。
交叉验证
def cross_validation_split(dataset, n_folds):
'''将数据集进行抽重抽样 n_folds 份,数据可以重复重复抽取,每一次list的元素是无重复的
:return: dataset_split list集合,存放的是:将数据集进行抽重抽样 n_folds 份,数据可以重复重复抽取,每一次list的元素是无重复的
'''
dataset_split = []
dataset_copy = list(dataset) # 复制一份 dataset,防止 dataset 的内容改变
fold_size = len(dataset) / n_folds
for i in range(n_folds):
fold = []
while len(fold) < fold_size:
index = randrange(len(dataset_copy))
# fold.append(dataset_copy.pop(index)) # 无放回的方式
fold.append(dataset_copy[index]) # 有放回的方式
dataset_split.append(fold)
return dataset_split
AdaBoost
算法流程图
实现过程
代码实现
def loadSimpData():
dataArr = array([[1., 2.1], [2., 1.1], [1.3, 1.], [1., 1.], [2., 1.]])
labelArr = [1.0, 1.0, -1.0, -1.0, 1.0]
return dataArr, labelArr
def stumpClassify(dataMat, dimen, threshVal, threshIneq): # G(x)公式
retArray = ones((shape(dataMat)[0], 1))
if threshIneq == 'lt':
retArray[dataMat[:, dimen] <= threshVal] = -1.0
else:
retArray[dataMat[:, dimen] > threshVal] = -1.0
return retArray
def buildStump(dataArr, labelArr, D):
"""buildStump(得到决策树的模型)
Args:
dataArr 特征标签集合;shape=(m,n)
labelArr 分类标签集合
D 最初的特征权重值
Returns:
bestStump 最优的分类器模型
minError 错误率
bestClasEst 训练后的结果集
"""
dataMat = mat(dataArr); labelMat = mat(labelArr).T;
m, n = shape(dataMat)
numSteps = 10.0; bestStump = {}; bestClasEst = mat(zeros((m, 1)))
minError = inf # 初始化的最小误差为无穷大
for i in range(n):
rangeMin = dataMat[:, i].min(); rangeMax = dataMat[:, i].max()
stepSize = (rangeMax-rangeMin)/numSteps # 计算每一份的元素个数
# 例如: 4=(10-1)/2 那么 1-4(-1次) 1(0次) 1+1*4(1次) 1+2*4(2次)
# 所以: 循环 -1/0/1/2
for j in range(-1, int(numSteps)+1):
for inequal in ['lt', 'gt']:
threshVal = (rangeMin + float(j) * stepSize) # 如果是-1,那么得到rangeMin-stepSize; 如果是numSteps,那么得到rangeMax
predictedVals = stumpClassify(dataMat, i, threshVal, inequal) # 对单层决策树进行简单分类,得到预测的分类值
errArr = mat(ones((m, 1)))
errArr[predictedVals == labelMat] = 0
weightedError = D.T*errArr # 权重乘以分错了的
if weightedError < minError:
minError = weightedError
bestClasEst = predictedVals.copy()
bestStump['dim'] = i
bestStump['thresh'] = threshVal
bestStump['ineq'] = inequal
return bestStump, minError, bestClasEst
# bestStump: {‘dim’:0,‘ineq‘:’lt‘,‘thresh':1.3}
# minError:错误率 matrix([[0.2]])
# bestClasEst:判断结果 array([[-1.],[1.],[-1.],[-1.],[1.]])
完整AdaBoost算法实现
对每次迭代:
利用buildStumpty函数找到最佳的单层决策树
将最佳单层决策树加入到单层决策树数组
计算alpha
计算新的权重向量D
更新累计类别估计值
如果错误率等于O.0,则退出循环
def adaBoostTrainDS(dataArr, labelArr, numIt=40):
"""adaBoostTrainDS(adaBoost训练过程放大)
Args:
dataArr 特征标签集合
labelArr 分类标签集合
numIt 实例数
Returns:
weakClassArr 弱分类器的集合
aggClassEst 预测的分类结果值
"""
weakClassArr = []; m = shape(dataArr)[0]
D = mat(ones((m, 1))/m) # 初始化 D,设置每个特征的权重值,平均分为m份
aggClassEst = mat(zeros((m, 1)))
for i in range(numIt):
bestStump, error, classEst = buildStump(dataArr, labelArr, D) # 得到决策树的模型
alpha = float(0.5*log((1.0-error)/max(error, 1e-16))) # alpha 目的主要是计算每一个分类器实例的权重(加和就是分类结果)
bestStump['alpha'] = alpha
weakClassArr.append(bestStump)
expon = multiply(-1*alpha*mat(labelArr).T, classEst)
D = multiply(D, exp(expon))
D = D/D.sum()
aggClassEst += alpha*classEst
aggErrors = multiply(sign(aggClassEst) != mat(labelArr).T, ones((m, 1)))
errorRate = aggErrors.sum()/m
if errorRate == 0.0:
break
return weakClassArr, aggClassEst
参考:
《机器学习实战》-Peter Harrington
《统计学习方法》-李航
《机器学习实战-教学版》-网易云课堂