欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

机器学习笔记(9)-集成方法[AdaBoost与随机森林]

程序员文章站 2022-07-14 13:46:16
...

分类器相关概述

将不同的分类器组合起来,而这种组合结果则被称为集成方法(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,在选取的特征中选取最优的特征。
机器学习笔记(9)-集成方法[AdaBoost与随机森林]
交叉验证

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

算法流程图
机器学习笔记(9)-集成方法[AdaBoost与随机森林]
实现过程
机器学习笔记(9)-集成方法[AdaBoost与随机森林]
机器学习笔记(9)-集成方法[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

机器学习笔记(9)-集成方法[AdaBoost与随机森林]
机器学习笔记(9)-集成方法[AdaBoost与随机森林]
机器学习笔记(9)-集成方法[AdaBoost与随机森林]
机器学习笔记(9)-集成方法[AdaBoost与随机森林]
机器学习笔记(9)-集成方法[AdaBoost与随机森林]

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

相关标签: 机器学习