Live2D

谈谈模型融合之二 —— 随机森林

前言

上篇文章介绍了集成学习的相关概念以及基于 Boosting的 AdaBoost,这篇文章将介绍基于模型融合的另一种方式 Bagging 的算法,随机森林(Random Forest)。(上篇公式敲的太累了这篇就来个简单的缓解缓解)

随机森林

算法思想

我们先来看看这个算法的名字,可以拆分开为两部分,随机和森林。森林我们很容易可以想到,就是有很多棵树,即由多颗决策树组成。那么随机指的是什么呢?这里我们来看看 Bagging 的思想了。

首先先说说自助采样(Bootstrap Sanpling)

指任何一种有放回的均匀抽样,也就是说,每当选中一个样本,它等可能地被再次选中并被再次添加到训练集中。

而 Bagging 则是利用自助采样得到 T 组训练样本集,分别利用这些训练样本集训练 T 个分类器,最后进行集成的方法。从 Bias-Variance 分解的角度看, Bagging 主要关注降低方差。

那么,我们大概就能知道这个随机大概是什么意思了,就是随机抽取训练集。

那么,问题又来了,到底是随机抽取一定量的样本呢还是抽取部分特征呢?答案是都有,随机在这两方面都有所体现。

所以可以列出这么一个等式—— Random Forest = Bagging + Fully-Grown CART with Random Subspace。

其特点为:

  1. 可高度并行化
  2. 继承了 CART 的优点
  3. 克服了完全生长树的缺点

融合策略

知道了随机森林的算法思想后,知道了最后是需要将所有决策树的预测结果进行集成,那我们采用什么方法进行集成呢?

大概有以下几种方法:

  1. 平均法
  2. 加权平均法
  3. 投票法
    • 绝大多数投票(Majority Voting):超过半数则决策,否则拒绝
    • 少数服从多数(Plurality Voting):预测为得票最多的标记法
  4. 学习法
    • 用各学习器的输出生成新的训练数据,再去训练一个学习器

代码实现

emmmmmmmmmmm。。。。突然发现居然没有什么数学推导????惊了

下面的代码是基于投票法策略写的

def bagging(X, y, T, size, seed=0, max_depth=None):
    """
    Bagging算法,分类器为CART,用于二分类
    参数:
        X: 训练集
        y: 样本标签
        T: T组
        size: 每组训练集的大小
        seed: 随机种子
        max_depth: 基学习器CART决策树的最大深度
    返回:
        F: 生成的模型
    """
    classifiers = []
    m, n = X.shape
    
    np.random.seed(seed)
    for i in range(T):
        # 使用np.random.choice选择size个序号,注意replace参数的设置,以满足有放回的均匀抽样。
        index = np.random.choice(m,size)
        X_group = X[index]
        y_group = y[index]
        # 使用tree.DecisionTreeClassifier,设置max_depth=None, min_samples_split=2(生成完全树),random_state=0
        t = DecisionTreeClassifier(max_depth=max_depth, min_samples_split=2, random_state=0)
        # 开始训练
#         print(y_group.shape)
        t.fit(X_group, y_group)
        classifiers.append(t)
    
    def F(X):
        # 计算所有分类器的预测结果
        result = []
        for t in classifiers:
            result.append(t.predict(X))
        # 把预测结果组成 num_X * T 的矩阵
        pred = np.vstack(result).T
        # 计算"0"有多少投票
        vote_0 = T - np.sum(pred, axis=1)
        # 计算"1"有多少投票
        vote_1 = np.sum(pred, axis=1)
        # 选择投票数最多的一个标签
        pred = (vote_1 > vote_0).astype(int)
        
        return pred     
    return F

小节

上篇的 AdaBoost 一堆公式推导,这就来了篇简单的缓解缓解,写着写着发现就写完了而且还没有公式的时候瞬间惊了,下篇该系列文章就来讲讲数据挖掘竞赛中熟知的 GBDT

posted @ 2019-12-28 18:33  ITryagain  阅读(794)  评论(0编辑  收藏  举报