机器学习笔记(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
《统计学习方法》-李航
《机器学习实战-教学版》-网易云课堂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值