精华内容
下载资源
问答
  • 1.3基尼系数 2. ID3 vs C4.5 vs CART 3. 剪枝操作 3.1 预剪枝 3.2 后剪枝 4. 关于 ID3、C4.5、CART 的几个问题 1. 构造决策树的依据 决策树的构造,从本质上讲就是每次将样本分成几组,目标是让每一组中的...

    目录

    1. 构造决策树的依据

    1.1 信息增益度

    1.2 信息增益率

    1.3 基尼系数

    2. ID3 vs C4.5 vs CART

    3. 剪枝操作

    3.1 预剪枝

    3.2 后剪枝

    4. 关于 ID3、C4.5、CART 的几个问题


    1. 构造决策树的依据

    决策树的构造,从本质上讲就是每次将样本分成几组,目标是让每一组中的类别尽可能单一(每组的熵加权相加后的值尽可能的小)

    ID3中使用最大化信息增益度对样本进行分组,C4.5中使用最大化信息增益率对样本进行分组,CART中使用最小化分组后基尼系数进行分组;

    1.1 信息增益度

    信息增益度从字面上理解就是信息量变多的量,信息变多自然系统的混乱程度就会变小,因此信息增益度也就等价于节点分组前后信息熵差值

    通过某个特征a对样本进行划分后得到的信息增益度为:

    Gain(D,a)=Ent(D)-\sum_{v=1}^{V}\frac{|D^v|}{|D|}Ent(D^v)\\

    Ent(D)=\sum_{i=1}^{|y|}pi*log(pi)\\

    其中:

    • V表示a特征下所有取值的数目,Dv/D表示a特征取v值的概率
    • Ent(D)表示整个样本的信息熵,Ent(Dv)表示根据特征a分组后每组关于类别的信息熵
    • 后边这一项计算的是根据特征a的取值进行划分后每组信息增益的加权和,权重是每组样本数占总样本数的比例
    • 第二个公式中,|y|表示类别数,pi表示所有样本中i类样本的比例

    1.2 信息增益率

    信息增益率在信息增益度的基础上除了一个值,这个值表示a特征下不同取值的信息熵,公式如下:

    Gain_{ration}(D,a)=\frac{Gain(D,a)}{H_a(D)}

    H_a(D)=\sum_{i=1}^{n}\frac{|D_i|}{|D|}log\frac{|D_i|}{|D|}

    其中:

    • |Di|/D表示在样本数据D中,a特征取值第i种值的比例

    注意,H_a(D)表示样本D中a特征所有取值的信息熵,Ent(D)表示D样本中类别的信息熵,虽然都是信息熵,但是统计的对象不同,a特征下的取值越多,H_a(D)就会越大,因此信息增益率和H_a(D)成反比,当a特征下的取值越多,信息增益率就会越少

    在特征选择时,使用信息增益度会倾向于选择取值较多的特征,使用信息增益率会倾向于选择取值较小的特征,在C4.5中为了在两种算法中找到一个平衡,实际是先得到信息增益度大于某个阈值的特征集合,然后在这些特征中选择信息增益率最大的特征作为最终进行分裂的特征

    1.3 基尼系数

    通常意义上的基尼指数(基尼不纯度)= 样本被选中的概率 * 样本被分错的概率,公式如下:

    Gini(p)=\sum_{k=1}^{K}p_k(1-p_k)=1-\sum_{k=1}^{K}p_k^2\\

    其实,根据上述公式可以知:基尼系数表示从样本中有放回的抽取两个样本,类别不同的概率

    从样本中有放回的抽取两个样本,类别不同的概率根据第一次抽到的样本的不同类别可以看作是K(K=类别数)种情况概率的和

    以任意一个类别A为例,第一次抽中A类样本,第二次抽中非A类样本的概率(有放回)为 p_k(1-p_k),那么K种情况的概率和你可以表示为基尼系数的公式了

    决策树中的基尼系数可以表示为:

    Gini(D,a)=\frac{|D_1|}{|D|}Gini(D_1)+\frac{|D_2|}{|D|}Gini(D_2)

    Gini(D_1)=1-\sum_{k=1}^{K}(\frac{|D_{1k}|}{|D_1|})^2

    Gini(D_2)=1-\sum_{k=1}^{K}(\frac{|D_{2k}|}{|D_2|})^2

    其中,

    • \frac{|D_1|}{|D|}\frac{|D_2|}{|D|}表示根据a特征分组后,每一组样本占总样本的比例
    • \frac{|D_{1k}|}{|D_1|}\frac{|D_{2k}|}{|D_2|}表示通过a特征分组后,第1、2组中属于k类样本的比例
    • 因为在使用基尼系数的CART决策树中,树的类型只能是二叉树,因此这里每次只分两组

    基尼系数和信息增益、信息增益率不同,基尼系数越小越好,其实基尼系数和信息熵的评价效果类似;

    2. ID3 vs C4.5 vs CART

    ID3 vs C4.5 vs CART三种算法的比较如下图所示:

    算法支持任务树结构特征选择连续值处理缺失值处理剪枝特征多次被划分
    ID3分类多叉树信息增益度
    C4.5分类多叉树信息增益率
    CART分类回归二叉树基尼系数+MSE

    3. 缺失值处理

    请参考以下链接:

    决策树是如何处理不完整数据的?

    4. 剪枝操作

    剪枝的目的是构造一个高度最矮的决策树,防止模型的过拟合,C4.5和CART能够进行剪枝操作

    4.1 预剪枝

    预剪枝指在构建决策树的同时进行剪枝操作,预剪枝有以下几种方式:

    1. 提前设定决策树的最大深度和每个节点的最少样本数目,当决策树达到上述条件时提前停止构建
    2. 留出法:将数据集划分为训练集和测试集,当分裂节点时,使用k折交叉验证计算分裂前后在测试集上的准确率(泛化性能),若准确率提高则分裂,否则此节点不在分裂

    预剪枝相比于后剪枝,虽然计算量小,但容易出现欠拟合

    4.2 后剪枝

    后剪枝指在决策树构建完成后进行剪枝操作,后剪枝有一下几种方式:

    1. 通过比较前后损失函数是否降低,若降低则进行剪枝操作,否则不进行剪枝
    2. 留出法:将数据集划分为训练集和测试集,当分裂节点时,使用k折交叉验证计算分裂前后在测试集上的准确率(泛化性能),若准确率提高则分裂,否则此节点不在分裂

    决策树损失函数如下:

    C(t)=\sum_{t \in leaf} N_t*H(t)+\alpha |T|\\

    损失函数是两项的线性组合,其中:

    • 第一项是所有叶子节点信息熵(对象是类别)的加权和,权重是每个叶子节点的样本数量,这一项用来降低每个叶子节点的熵值
    • 第二项是决策树中叶子节点的数量,用来降低网络的复杂程度

    5. 关于 ID3、C4.5、CART 的几个问题

    1. C4.5、CART 处理连续值属性

    ID3原则上不能对连续值进行处理,因为连续值的特征往往还有很多取值,如果使用ID对连续值进行分裂,那么会产生众多分支,这显然不是高效的;如果使用C4.5和CART的划分方式,每次将连续值划分为两部分,这显然违背了ID3每个特征只能划分一次的规则,当然通过简单的改进ID3也是能够处理连续特征的

    对于连续值的属性,我们一般进行如下处理:

    1. 将连续特征的取值按升序排列
    2. 根据取值确定N个分割点(取相邻两个取值的均值作为分割点),计算每个分割点修正后的信息增益,(修正的方法是在信息增益的基础上-log2(N-1)/|D|,N是连续特征的取值个数,D是训练数据数目)
    3. 选取修正信息增益最大的分割点计算信息增益率,并将其作为此特征的信息增益率

    注:修正的信息增益是连续特征和离散特征处理时最大的区别;使用修正的信息增益,原因在于:当离散属性和连续属性并存时,C4.5算法倾向于选择连续特征做最佳树分裂点,修正后的信息增益能够在一定程度上避免此问题


    2. C4.5、CART 解决回归问题

    回归和分类问题本质上就是预测标签的区别,分类的标签是离散值,回归的标签是连续值

    对于连续值我们无法将同标签的样本划分到一起,因为每个样本的标签值都是不同的;但是连续值不同取值之间可以比较大小,因此对于回归问题,我们更希望在分裂时将标签数值接近的样本划分到一起(分类是最小化每组标签值的种类,回归是最小化每组标签取值的范围);在回归问题中,我们使用均方根误差代替信息增益来作为节点分裂的依据,这是决策树在解决分类问题和回归问题时最主要的区别

    在决策树中,计算连续值特征的信息增益和解决回归问题是两类不同的问题,虽然都是对连续值的处理但是对象不同:连续值的特征是指样本的某一个特征的值是连续的;回归问题是指样本的标签是连续值


    3. 对于ID3模型,每次分组是时根节点的信息熵是定值,为什么不直接用分组后的信息熵作损失函数?

    具体的有原因还没有弄明白,还请大神解惑,个人推测了两种原因

    1. 如果对于每一个根节点进行分组时,分组前的信息熵(信息增益中的第一项)确实是不变的,但是要在多个根节点中选择一个进行分裂,每个根节点的信息熵就不同了,此时就需要计算信息增益

    2. 为了在C4.5中计算信息增益率,因此先计算信息增益度,方便后边的计算


    4. 为什么CART中不需要计算基尼系数的前后差值

    ID3、C4.5 的多分支树结构,在使用信息增益选择分裂特征时会想倾向选择那些取值较多的特征(这种特征往往不是最优特征)因此在C4.5中使用信息增益率来避免算法对多取值特征的倾向,而计算信息增益率就需要用到信息增益的差值;

    但是在CART决策树中使用的是二叉树,因此选择了取值较多的特征也不会使网络的性能变差,因此就不需要信息增益率来限制特征选择,因此不需要计算基尼系数前后的差值

    展开全文
  • 结点分为内部结点和叶结点,其中每个内部结点表示一个特征或属性,叶结点表示类别。从顶部根结点开始,所有样本聚在一起。经过根结点的划分,样本被分到不同的子结点中。再根据子结点的特征进一步划分,直至所有样本...

    一、决策树概述

    注:生产实践中,不使用决策树,太简单,而是使用决策树的升级版:集成学习算法
    集成学习算法有:

    • Random Forest(随机森林)
    • Extremely Randomized Forest(极限随机森林)
    • Adaboost提升树
    • GBDT(梯度提升树)
    • XGBoost(极端梯度提升树)

    1、决策树概念

    决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法。
    在这里插入图片描述

    • 决策树算法采用的是自顶向下递归方法,其基本思想是以信息熵为度量构造一棵值下降最快的树,到叶子节点处熵值为零,此时每个叶节点中的实例都属于同一类。
    • 决策树是一种自上而下,对样本数据进行树形分类的过程,由结点有向边组成。结点分为内部结点叶结点,其中每个内部结点表示一个特征或属性叶结点表示类别。从顶部根结点开始,所有样本聚在一起。经过根结点的划分,样本被分到不同的子结点中。再根据子结点的特征进一步划分,直至所有样本都被归到某一个类别(即叶结点)中
    • 决策树:自顶向下,做一个信息熵下降最快的树,使得事件越来越确定。
    • 决策树算法的特点:决策树学习算法的最大优点是,它可以自学习。在学习的过程中,不需要使用者了解过多背景知识,只需要对训练实例进行较好的标注,就能够进行学习。从一类无序、无规则的事物 (概念 )中推理出决策树表示的分类规则。
    • 决策树分为两大类,回归树和分类树。
      • 回归树用于预测实数值,如明天的温度、用户的年龄、网页的相关程度;
      • 分类树用于分类标签值,如晴天/阴天/雾/雨、用户性别、网页是否是垃圾页面。
      • 回归树的结果加减是有意义的,如10岁+5岁-3岁=12岁,比如GBDT梯度提升树的核心就在于累加所有树的结果作为最终结果
      • 分类树的结果加减则无意义,如男+男+女=到底是男是女?

    决策树:

    • 是一种树形结构,本质是一颗由多个判断节点组成的树;
    • 其中每个内部节点表示一个属性上的判断;
    • 每个分支代表一个判断结果的输出;
    • 最后每个叶节点代表一种分类结果;
    • 决策树学习是以实例为基础的归纳;
    • 决策树学习采用的是自顶向下递归方法;

    怎么理解这句话?通过一个对话例子
    在这里插入图片描述
    上面案例是女生通过定性的主观意识,把年龄放到最上面,那么如果需要对这一过程进行量化,该如何处理呢?
    此时需要用到信息论中的知识:信息熵,信息增益

    2、CART树(Category And Regression Tree)

    CART是一棵二叉树,每一次分裂会产生两个子节点。CART树分为分类树和回归树。

    • 分类树:针对目标值为离散型的情况,比如预测一个动物是否是哺乳动物。
      • 如果是分类树,将选择能够最小化分裂后节点GINI值的分裂属性;
    • 回归树:针对目标值为连续值的情况,比如预测一个动物的年龄。
      • 如果是回归树,选择能够最小化两个节点样本均方误差的分裂属性。CART跟其他决策树算法一样,需要进行剪枝,才能防止算法过拟合从而保证算法的泛化性能。

    二、分类树

    sklearn.tree.DecisionTreeClassifier()

    1、信息熵

    物理学上,熵 Entropy 是“混乱”程度的量度。系统越有序,熵值越低;系统越混乱或者分散,熵值越高。
    信息学上,1948年香农提出了信息熵(Entropy)的概念。

    在信息论中,熵(英语:entropy)是接收的每条消息中包含的信息的平均量,又被称为信息熵、信源熵、平均自信息量。这里,“消息”代表来自分布或数据流中的事件、样本或特征。(熵最好理解为不确定性的量度而不是确定性的量度,因为越随机的信源的熵越大)

    信息理论:

    1. 信息和消除不确定性是相联系的;
    2. 信息熵越大,信息越不确定,信息熵越小,信息越明确;
    3. 从信息的完整性上进行的描述:当系统的有序状态一致时,数据越集中的地方熵值越小,数据越分散的地方熵值越大;
    4. 从信息的有序性上进行的描述:当数据量一致时,系统越有序,熵值越低;系统越混乱或者分散,熵值越高;

    信息熵(information entropy)是度量样本集合纯度最常用的一种指标。

    假定当前样本集合 D D D 中第 k k k 类样本所占的比例为 p k p_k pk (k = 1, 2,. . . , |y|) ,

    p k = C k C D p_k=\cfrac{C_k}{C_D} pk=CDCk

    • C k C_k Ck 是按目标值分类后第 k k k 类样本的数量;

    • C D C_D CD为样本集合D的总数量;

    则样本集合 D D D信息熵 定义为:

    E n t ( D ) = − ∑ k = 1 n C k C D l o g 2 C k C D = − ∑ k = 1 n p k l o g 2 p k = − ( p 1 l o g 2 p 1 + p 2 l o g 2 p 2 + . . . + p n l o g 2 p n ) \color{violet}{Ent(D) = -\sum_{k=1}^{n}\cfrac{C_k}{C_D}log_2\cfrac{C_k}{C_D}=-\sum_{k=1}^{n}p_klog_2{p_k}=-(p_1log_2p_1+p_2log_2p_2+...+p_nlog_2p_n)} Ent(D)=k=1nCDCklog2CDCk=k=1npklog2pk=(p1log2p1+p2log2p2+...+pnlog2pn)

    其中: E n t ( D ) Ent(D) Ent(D)的值越小,则样本集合 D D D 的纯度越高。单位为“比特”

    案例01:
    假设我们没有看世界杯的比赛,但是想知道哪支球队会是冠军,
    我们只能猜测某支球队是或不是冠军,然后观众用对或不对来回答,
    我们想要猜测次数尽可能少,你会用什么方法?
    答案:
    二分法:
    假如有 16 支球队,分别编号,先问是否在 1-8 之间,如果是就继续问是否在 1-4 之间,
    以此类推,直到最后判断出冠军球队是哪支。
    如果球队数量是 16,我们需要问 4 次来得到最后的答案。那么世界冠军这条消息的信息熵就是 4比特。
    
    那么信息熵等于4,是如何进行计算的呢?
    

    E n t ( D ) = − ( p 1 ∗ l o g 2 p 1 + p 2 ∗ l o g 2 p 2 + . . . + p 1 6 ∗ l o g 2 p 16 ) Ent(D) =-(p_1 * log_2p_1 + p_2 * log_2p_2 + ... + p_16 * log_2p_{16}) Ent(D)=(p1log2p1+p2log2p2+...+p16log2p16)
    其中 p 1 p_1 p1, …, p 16 p_{16} p16 分别是这 16 支球队夺冠的概率。
    当每支球队夺冠概率相等都是 1 16 \cfrac{1}{16} 161 的时: E n t ( D ) = − ( 16 ∗ 1 16 ∗ l o g 2 1 16 ) = 4 Ent(D) = -(16 * \cfrac{1}{16} * log_2\cfrac{1}{16}) = 4 Ent(D)=(16161log2161)=4
    每个事件概率相同时,熵最大,这件事越不确定。

    案例02:
    篮球比赛里,有4个球队 {A,B,C,D} ,获胜概率分别为{1/2, 1/4, 1/8, 1/8}
    求Ent(D)
    

    在这里插入图片描述

    2、分类树分类依据

    2.1 信息增益

    信息增益:以某特征划分数据集前后的熵的差值。熵可以表示样本集合的不确定性,熵越大,样本的不确定性就越大。因此可以使用划分前后集合熵的差值来衡量使用当前特征对于样本集合D划分效果的好坏。
    信息增益:表示得知特征X的信息而使得类Y的信息熵减少的程度的量度。
    一个属性的信息增益(或信息增益率、Gini系数的降低值)越大,表明该属性对样本的熵减少的能力越强,这个属性使得数据由不确定性变成确定性的能力越强。
    计算机循环计算各个属性的各个样本点为裂分点时的信息增益,然后将信息增益最大的属性样本点作为本节点裂分点。

    特征 a a a 对训练数据集 D D D 的信息增益 G a i n ( D , a ) Gain(D,a) Gain(D,a) 定义为:集合 D D D 的信息熵 H ( D ) H(D) H(D) 与特征 a a a 给定条件下 D D D信息条件熵 H ( D ∣ a ) H(D|a) H(Da) 之差,即:信息增益 = entroy(前) - entroy(后)。

    G a i n ( D , a ) = E n t ( D ) − E n t ( D ∣ a ) Gain(D,a)=Ent(D)-Ent(D|a) Gain(D,a)=Ent(D)Ent(Da)

    • E n t ( D ) = − ∑ k = 1 n C k C D l o g 2 C k C D Ent(D) = -\sum_{k=1}^{n}\cfrac{C_k}{C_D}log_2\cfrac{C_k}{C_D} Ent(D)=k=1nCDCklog2CDCk
      • n n n 表示按目标值分类后的类的总数量
      • C D C_D CD为集合 D D D 的样本总数量,
      • C k C_k Ck为按目标值分类后第 k k k 类中样本的数量;
    • E n t ( D ∣ a ) = ∑ k = 1 n C D a k C D E n t ( D a k ) = ∑ k = 1 n C D a k C D [ − ∑ i = 1 m C D a k i C D a k l o g 2 C D a k i C D a k ] = − ∑ k = 1 n C D a k C D [ ∑ i = 1 m C D a k i C D a k l o g 2 C D a k i C D a k ] \color{violet}{Ent(D|a) = \sum_{k=1}^n\cfrac{C_{D_a^k}}{C_D}Ent(D_a^k) = \sum_{k=1}^n\cfrac{C_{D_a^k}}{C_D}[-\sum_{i=1}^{m}\cfrac{C^i_{D_a^k}}{C_{D_a^k}}log_2\cfrac{C^i_{D_a^k}}{C_{D_a^k}}] = -\sum_{k=1}^n\cfrac{C_{D_a^k}}{C_D}[\sum_{i=1}^{m}\cfrac{C^i_{D_a^k}}{C_{D_a^k}}log_2\cfrac{C^i_{D_a^k}}{C_{D_a^k}}]} Ent(Da)=k=1nCDCDakEnt(Dak)=k=1nCDCDak[i=1mCDakCDakilog2CDakCDaki]=k=1nCDCDak[i=1mCDakCDakilog2CDakCDaki]
      • n n n 表示按条件 a a a 的分类后的一级类数量 C D a k C_{D_a^k} CDak 表示集合 D D D 在条件 a a a 的分类条件下,一级类 k k k 中包含的样本数量
      • m m m 表示在条件 a a a 的分类条件下,一级类 k k k 中包含的的二级类数量 C D a k i C^i_{D_a^k} CDaki 表示在条件a分类条件下,一级类 k k k 所包含的二级类 i i i 中所包含的样品数量
      • 信息条件熵,即:在条件 a a a 的分类下,分出 a 1 , a 2 , . . . , a k , . . . , a n a_1, a_2, ..., a_k, ..., a_n a1,a2,...,ak,...,an 组,先分别求出这 n n n 组各自的信息熵,然后加权平均得到总的信息熵

    对于特征 a a a b b b c c c 而言,如果 G a i n ( D , a ) > G a i n ( D , b ) > G a i n ( D , c ) Gain(D,a)>Gain(D,b)>Gain(D,c) Gain(D,a)>Gain(D,b)>Gain(D,c),说明这几个特征对于数据集 D D D 的重要性而言 a > b > c a>b>c a>b>c 。在做特征选择或者数据分析的时候,我们应该把特征 a a a 当做第一个分类标准,然后再考虑特征 b b b,最后考虑特征 c c c

    2.2 信息增益率

    以信息增益作为划分训练数据集的特征,存在偏向于优先选择取值较多的特征的问题。可以使用信息增益比对这一问题进行校正。

    G a i n r ( D , a ) = G a i n ( D , a ) E n t ( a ) = E n t ( D ) − E n t ( D ∣ a ) E n t ( a ) Gain_r(D,a)=\dfrac{Gain(D,a)}{Ent(a)}=\dfrac{Ent(D)-Ent(D|a)}{Ent(a)} Gainr(D,a)=Ent(a)Gain(D,a)=Ent(a)Ent(D)Ent(Da)

    优化后解决了ID3分支过程中总喜欢偏向选择值较多的 属性

    2.3 基尼系数(Gini index)

    G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 Gini(p)=\sum_{k=1}^Kp_k(1-p_k)=1-\sum_{k=1}^Kp^2_k=1-\sum_{k=1}^K(\dfrac{|C_k|}{|D|})^2 Gini(p)=k=1Kpk(1pk)=1k=1Kpk2=1k=1K(DCk)2

    使用Gini系数的效果总体上比前两者好一点

    3、分类树算法

    名称分支方式对比①对比②对比③对比④对比⑤对比⑥
    ID3信息增益只能处理离散型变量只进行分类对样本特征缺失值敏感每个节点可以产生多叉分支每个特征在层级之间不会复用通过剪枝来权衡树的准确性与泛化能力
    C4.5信息增益率可以处理离散型变量
    也可以处理连续型变量
    只进行分类可以对缺失值进行不同方式的处理每个节点可以产生多叉分支每个特征在层级之间j可以复用通过剪枝来权衡树的准确性与泛化能力
    CARTGini系数可以处理离散型变量
    也可以处理连续型变量
    可以进行分类回归可以对缺失值进行不同方式的处理每个节点只能产生2个分支
    最后会形成二叉树
    每个特征在层级之间j可以复用直接利用全部数据发现所有可能的树结构进行对比

    比信息增益划分的更加仔细。

    4、分类树的损失函数

    假定样本的总类别为 K K K 个。对于决策树的某叶结点 A A A,假定该叶节点 A A A 中含有样本总数为 n n n,其中第 k k k 类的样本数目为 n k , k = 1 , 2 , … , K n_k,k=1,2,…,K nk,k=1,2,,K,则 n = n 1 + n 2 + . . . + n K n=n_1+n_2+...+n_K n=n1+n2+...+nK

    • 若叶结点 A A A中, j j j 类样本数 n j = n n_j=n nj=n 而其余 K − 1 K-1 K1 类的样本数都为 0 , n 1 = n 2 = … = n j − 1 = n j + 1 = … = n K = 0 0,n_1=n_2=…=n_{j-1}=n_{j+1}=…=n_K=0 0n1=n2==nj1=nj+1==nK=0 ,称该叶结点为纯叶节点
    • 若叶结点 A A A中,各类样本的数量都相等, n 1 = n 2 = … = n j = … = n K = n K n_1=n_2=…=n_j=…=n_K=\dfrac{n}{K} n1=n2==nj==nK=Kn,则称该叶结点为均叶节点
    • 纯叶节点的信息熵 H p = 0 H_p=0 Hp=0,最小;
    • 均叶节点的信息熵 H u = l n K H_u=lnK Hu=lnK,最大;
    • 对所有叶节点的信息熵求和,该值越小说明对样本的分类越精确;
    • 各叶结点包含的样本数目不同,可使用加权求信息熵和,由于该值越小越好,所以称之为损失函数

    C ( T ) = ∑ t ∈ l e a f N t ⋅ H t ( T ) \color{violet}{C(T)=\sum_{t∈leaf}N_t·H_t(T)} C(T)=tleafNtHt(T)

    为了避免出现过拟合的现象,我们要对决策树进行剪枝。
    决策树的剪枝类似一种参数正则化的过程,其选择正则化的参数是树的叶子节点的个数。

    设决策树 T 的叶子节点个数为 |T|,t 是树 T 的叶子节点,该叶节点有 N t N_t Nt 个样本点,其中 k 类的样本点有 N t k N_{tk} Ntk 个, H t ( T ) H_t(T) Ht(T) 为叶节点 t 上的经验熵,α⩾0 为正则化系数,则包含剪枝的决策树的损失函数可以定义为:

    在这里插入图片描述
    其中

    • 经验熵为:

    在这里插入图片描述

    • 右边第一项表示误差大小,第二项表示模型的复杂度,也就是用叶节点表示,防止过拟化。

    • 损失函数中的第一项表示模型对训练数据的预测误差,也就是模型的拟合程度,第二项表示模型的复杂程度,通过参数 α 控制二者的影响力。一旦 α 确定,那么我们只要选择损失函数最小的模型即可。

    5、分类树算法优缺点

    • 优点:

      • 简单的理解和解释,树木可视化;
      • 需要很少的数据准备,其他技术通常需要数据归一化;
      • 决策树算法可以用于小数据集;
      • 决策树算法的时间复杂度较小,为用于训练决策树的数据点的对数;
      • 对缺失值不敏感。
      • 效率高,决策树只需要一次构建,反复使用,每一次预测的最大计算次数不超过决策树的深度。
    • 缺点:

      • 对连续性的字段比较难预测。
      • 决策树学习者可以创建不能很好地推广数据的过于复杂的树,容易发生过拟合;
      • 当类别太多时,错误可能就会增加的比较快。
      • 忽略了属性之间的相关性,在处理特征关联性比较强的数据时表现得不是太好;
      • 对于各类别样本数量不一致的数据,在决策树当中,信息增益的结果偏向于那些具有更多数值的特征;
    • 改进:

      • 随机森林(集成学习的一种);
      • 减枝cart算法(决策树Api中已经实现),降低过拟合现象;通过DecisionTreeClassifier()方法里的min_samples_leaf参数来调节;如果设定min_samples_leaf=3,那么samples<3的叶子节点会被删除,防止分类太细化,决策树层数过深,产生过拟合。
        在这里插入图片描述
        注:企业重要决策,由于决策树很好的分析能力,在决策过程应用较多, 可以选择特征

    6、scikit-learn分类树算法Api

    class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)

    • criterion

      • 特征选择标准
      • “gini"或者"entropy”,前者代表基尼系数,后者代表信息增益。默认"gini",即CART算法。
    • min_samples_split

      • 内部节点再划分所需最小样本数
      • 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。我之前的一个项目例子,有大概10万样本,建立决策树时,我选择了min_samples_split=10。可以作为参考。
    • min_samples_leaf

      • 叶子节点最少样本数
      • 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。之前的10万样本项目使用min_samples_leaf的值为5,仅供参考。
    • max_depth

      • 决策树最大深度
      • 决策树的最大深度,默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间
    • random_state

      • 随机数种子

    7、决策树算法案例

    使用决策树算法时,特征数据值不需要进行去量纲化归一化标准化处理。

    7.1 鸢尾花分类

    import numpy as np
    import pandas as pd
    from sklearn import datasets
    from sklearn.model_selection import train_test_split
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.metrics import accuracy_score
    import matplotlib.pyplot as plt
    from sklearn import tree
    
    if __name__ == '__main__':
        # 一、提取数据
        iris = datasets.load_iris()
        # 1.1 提取特征数据值、目标值
        X = iris.data
        y = iris.target
        feature_names = iris.feature_names
    
        # 二、特征工程
        # 2.1 分割训练集、测试集
        X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8)
        # 2.2 查看数据
        X_train_012 = pd.DataFrame(X_train, columns=feature_names)
        print('X_train_012 =\n', X_train_012.head(5))
        # 2.2.0 查看所有列数据的标准差,标准差越大,说明该列数据波动性越大,越容易分类
        std_all_012 = X_train_012.std(axis=0)
        print('type(std_all_012) = ', type(std_all_012), '----std_all_012 = \n', std_all_012)
        # 2.2.1 petal length (cm) 列的数据
        X_train_petal_length = X_train_012.iloc[:, 2]
        X_train_petal_length = np.sort(X_train_petal_length)
        print('type(X_train_petal_length) = ', type(X_train_petal_length), '----X_train_petal_length = X_train_012.iloc[:, 2] =\n', X_train_petal_length)
        index_2 = np.argsort(X_train_012.iloc[:, 2])
        y_train_012 = y_train[index_2]
        print('样本所属分类:y_train_012 = \n', y_train_012)
    
        # 2.2.2 根据petal length (cm)将类型0的花全部分类出去后,剩下类型1、类型2的花
        X_train_12 = X_train_012[y_train != 0]
        print('X_train_12.shape = ', X_train_12.shape, '----X_train_12 =\n', X_train_12.head(5))
        # 2.2.3 查看所有列数据的标准差,标准差越大,说明该列数据波动性越大,越容易分类
        std_all_12 = X_train_12.std(axis=0)
        print('type(std_all_12) = ', type(std_all_12), '----std_all_12 = \n', std_all_12)
        # 2.2.4 petal width (cm) 列的数据
        X_train_petal_width = X_train_12.iloc[:, 3]
        X_train_petal_width = np.sort(X_train_petal_width)
        print('type(X_train_petal_width) = ', type(X_train_petal_width), '----X_train_petal_width = X_train_12.iloc[:, 2] =\n', X_train_petal_width)
        index_3 = np.argsort(X_train_12.iloc[:, 3])
        y_train_12 = y_train[y_train != 0][index_3]
        print('样本所属分类:y_train_12 = \n', y_train_12)
    
    
        # 三、算法工程
        # 3.1 实例化分类决策树算法
        dt = DecisionTreeClassifier(criterion='entropy', max_depth=10, min_samples_leaf=1)
        dt.fit(X_train, y_train)
    
        # 四、模型评估
        # 4.1 测试集预测
        y_predict = dt.predict(X_test)
        print('测试集真实值:y_test = ', y_test)
        print('测试集预测值:y_predict = ', y_predict)
        # 4.2 模型准确度
        predict_score = dt.score(X_test, y_test)
        print('模型准确度:predict_score = ', predict_score)
        accuracy_score = accuracy_score(y_test, y_predict)
        print('模型准确度:accuracy_score = ', accuracy_score)
    
        # 五、画决策树
        plt.figure(figsize=(15, 12))
        _ = tree.plot_tree(dt, filled=True, feature_names=feature_names, max_depth=10)
        plt.savefig('./tree.jpg')
    

    在这里插入图片描述

    打印结果:

    X_train_012 =
        sepal length (cm)        ...         petal width (cm)
    0                6.3        ...                      2.5
    1                5.5        ...                      1.1
    2                6.2        ...                      1.5
    3                6.5        ...                      2.0
    4                7.2        ...                      1.8
    [5 rows x 4 columns]
    type(std_all_012) =  <class 'pandas.core.series.Series'> ----std_all_012 = 
     sepal length (cm)    0.834152
    sepal width (cm)     0.433473
    petal length (cm)    1.799313
    petal width (cm)     0.777232
    dtype: float64
    type(X_train_petal_length) =  <class 'numpy.ndarray'> ----X_train_petal_length = X_train_012.iloc[:, 2] =
     [1.  1.1 1.2 1.2 1.3 1.3 1.3 1.3 1.3 1.3 1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.4
     1.4 1.4 1.4 1.4 1.5 1.5 1.5 1.5 1.5 1.5 1.6 1.6 1.6 1.6 1.6 1.6 1.6 1.7
     1.7 1.7 1.9 1.9 3.  3.3 3.3 3.5 3.6 3.7 3.8 3.9 3.9 3.9 4.  4.  4.  4.
     4.1 4.2 4.2 4.2 4.3 4.4 4.5 4.5 4.5 4.5 4.5 4.5 4.5 4.5 4.6 4.6 4.6 4.7
     4.8 4.8 4.8 4.9 4.9 4.9 4.9 4.9 5.  5.  5.  5.  5.1 5.1 5.1 5.1 5.1 5.1
     5.1 5.2 5.2 5.3 5.4 5.5 5.5 5.5 5.6 5.6 5.6 5.6 5.6 5.6 5.7 5.7 5.8 5.8
     5.8 5.9 6.  6.  6.1 6.1 6.3 6.4 6.6 6.7 6.7 6.9]
    样本所属分类:y_train_012 = 
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2
     1 2 2 1 1 2 2 1 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
     2 2 2 2 2 2 2 2 2]
    X_train_12.shape =  (80, 4) ----X_train_12 =
        sepal length (cm)        ...         petal width (cm)
    0                6.3        ...                      2.5
    1                5.5        ...                      1.1
    2                6.2        ...                      1.5
    3                6.5        ...                      2.0
    4                7.2        ...                      1.8
    [5 rows x 4 columns]
    type(std_all_12) =  <class 'pandas.core.series.Series'> ----std_all_12 = 
     sepal length (cm)    0.675211
    sepal width (cm)     0.342145
    petal length (cm)    0.856249
    petal width (cm)     0.424831
    dtype: float64
    type(X_train_petal_width) =  <class 'numpy.ndarray'> ----X_train_petal_width = X_train_12.iloc[:, 2] =
     [1.  1.  1.  1.  1.  1.1 1.1 1.1 1.2 1.2 1.3 1.3 1.3 1.3 1.3 1.3 1.3 1.3
     1.3 1.3 1.4 1.4 1.4 1.4 1.4 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5
     1.6 1.6 1.6 1.7 1.7 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.9 1.9
     1.9 2.  2.  2.  2.  2.  2.  2.1 2.1 2.1 2.1 2.2 2.2 2.2 2.3 2.3 2.3 2.3
     2.3 2.3 2.4 2.4 2.4 2.5 2.5 2.5]
    样本所属分类:y_train_12 = 
     [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 2 2 1 1 1 1 1 1 1 2
     1 1 1 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
     2 2 2 2 2 2]
    测试集真实值:y_test =  [0 2 1 0 1 2 2 1 1 0 1 0 1 2 2 0 1 2 0 1 1 0 2 0 1 0 1 1 1 0]
    测试集预测值:y_predict =  [0 2 1 0 1 2 2 1 1 0 1 0 1 2 2 0 1 2 0 1 1 0 2 0 1 0 1 1 1 0]
    模型准确度:predict_score =  1.0
    模型准确度:accuracy_score =  1.0
    

    7.2 泰坦尼克号幸存者预测

    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.feature_extraction import DictVectorizer
    from sklearn.tree import DecisionTreeClassifier, export_graphviz
    
    
    def decision():
        """决策树对泰坦尼克号进行预测生死"""
        # 获取数据
        titanic = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
        print('type(titanic) = ', type(titanic), '----titanic = \n', titanic.head(5))
    
        # 一、数据处理
        # 1.1 找出特征数据值和目标值
        xDataFrame = titanic[['pclass', 'age', 'sex']]
        ySeries = titanic['survived']
        print('type(xDataFrame) = ', type(xDataFrame), '----特征数据值,xDataFrame = \n', xDataFrame.head(5))
        print('type(ySeries) = ', type(ySeries), '----目标值,ySeries = \n', ySeries.head(5))
        # 缺失值处理
        xDataFrame['age'].fillna(xDataFrame['age'].mean(), inplace=True)
    
        # 二、特征工程
        # 2.1 分割数据集到训练集合测试集
        xTrainDataFrame, xTestDataFrame, yTrainSeries, yTestSeries = train_test_split(xDataFrame, ySeries, test_size=0.25)
        print('type(xTrainDataFrame) = ', type(xTrainDataFrame), '----xTrainDataFrame = \n', xTrainDataFrame.head(5))
        print('type(xTestDataFrame) = ', type(xTestDataFrame), '----xTestDataFrame = \n', xTestDataFrame.head(5))
        print('type(yTrainSeries) = ', type(yTrainSeries), '----yTrainSeries = \n', yTrainSeries.head(5))
        print('type(yTestSeries) = ', type(yTestSeries), '----yTestSeries = \n', yTestSeries.head(5))
        # 2.2 特征抽取(字典数据类型,当特征值是类别时,进行ont-hot编码)
        dv = DictVectorizer(sparse=False)  # 实例化字典类型数据的特征抽取器(默认值为sparse=True,为True时返回sparse矩阵,当为False时,返回矩阵)
        xTrainDictList = xTrainDataFrame.to_dict(orient="records")  # 将DataFrame格式的xTrain转为Dict字典类型
        xTestDictList = xTestDataFrame.to_dict(orient="records")  # 将DataFrame格式的xTest转为Dict字典类型
        print('type(xTrainDictList) = ', type(xTrainDictList), '----xTrainDictList[0] = \n', xTrainDictList[0])
        xTrainNdArray = dv.fit_transform(xTrainDictList)  # 训练集特征抽取,返回一个ndarray格式的ont-hot编码后的xTrain
        xTestNdArray = dv.transform(xTestDictList);  # 测试集特征抽取
        featureNamesList = dv.get_feature_names()
        print('type(featureNamesList) = ', type(featureNamesList), '----featureNamesList = \n', featureNamesList)
        print('type(xTrainNdArray) = ', type(xTrainNdArray), '----xTrainNdArray = \n', xTrainNdArray)
        print('type(xTestNdArray) = ', type(xTestNdArray), '----xTestNdArray = \n', xTestNdArray)
    
        # 三、算法工程
        # 3.1 实例化一个决策树估计器对象
        dec_estimator = DecisionTreeClassifier(criterion='gini', max_depth=5)  # 一般使用默认的gini系数,max_depth为决策树层数
        # 3.2 调用fit方法,进行训练
        dec_estimator.fit(xTrainNdArray, yTrainSeries)
    
        # 四、模型评估
        # 4.1 数据预测,得出预测结果
        predictTestSeries = dec_estimator.predict(xTestNdArray)
        print('type(predictTestSeries) = ', type(predictTestSeries), '----predictTestSeries = \n', predictTestSeries)
        # 4.2 计算准确率
        predictScore = dec_estimator.score(xTestNdArray, yTestSeries)  # 输入”测试集“的特征数据值、目标值
        print('type(predictScore) = ', type(predictScore), '----predictScore = ', predictScore)
        # 4.3 导出决策树的结构文件(dot格式)
        export_graphviz(dec_estimator, out_file="./tree.dot", feature_names=['年龄', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
        # windows安装graphviz软件,运行命令(dot -Tpng tree.dot -o tree.png)将dot文件转换为pdf、png,如果出现“Format: "png" not recognized. Use one of:”错误提示,则在管理员模式下打开cmd窗口,输入"dot -c",然后再运行命令。
        # http://webgraphviz.com/在线显示图片
        return None
    
    if __name__ == "__main__":
        decision()
    

    dec_estimator = DecisionTreeClassifier(criterion=‘entropy’, max_depth=2)参数下的tree.dot文件转为tree.png图片:

    在这里插入图片描述

    dec_estimator = DecisionTreeClassifier(criterion=‘entropy’, max_depth=5)参数下的tree.dot文件转为tree.png图片:

    在这里插入图片描述
    dec_estimator = DecisionTreeClassifier(criterion=‘gini’, max_depth=10)参数下的tree.dot文件转为tree.png图片:

    在这里插入图片描述

    打印结果:

    type(titanic) =  <class 'pandas.core.frame.DataFrame'> ----titanic = 
        row.names pclass  survived   ...        ticket   boat     sex
    0          1    1st         1   ...    24160 L221      2  female
    1          2    1st         0   ...           NaN    NaN  female
    2          3    1st         0   ...           NaN  (135)    male
    3          4    1st         0   ...           NaN    NaN  female
    4          5    1st         1   ...           NaN     11    male
    [5 rows x 11 columns]
    
    type(xDataFrame) =  <class 'pandas.core.frame.DataFrame'> ----特征数据值,xDataFrame = 
       pclass      age     sex
    0    1st  29.0000  female
    1    1st   2.0000  female
    2    1st  30.0000    male
    3    1st  25.0000  female
    4    1st   0.9167    male
    
    type(ySeries) =  <class 'pandas.core.series.Series'> ----目标值,ySeries = 
     0    1
    1    0
    2    0
    3    0
    4    1
    Name: survived, dtype: int64
    
    type(xTrainDataFrame) =  <class 'pandas.core.frame.DataFrame'> ----xTrainDataFrame = 
          pclass        age   sex
    1128    3rd  31.194181  male
    207     1st  31.194181  male
    638     3rd  24.000000  male
    1202    3rd  31.194181  male
    127     1st  25.000000  male
    
    type(xTestDataFrame) =  <class 'pandas.core.frame.DataFrame'> ----xTestDataFrame = 
          pclass        age     sex
    258     1st  18.000000  female
    1274    3rd  31.194181    male
    695     3rd  18.000000  female
    10      1st  47.000000    male
    220     1st  18.000000  female
    
    type(yTrainSeries) =  <class 'pandas.core.series.Series'> ----yTrainSeries = 
     1128    0
    207     1
    638     0
    1202    0
    127     1
    Name: survived, dtype: int64
    type(yTestSeries) =  <class 'pandas.core.series.Series'> ----yTestSeries = 
     258     1
    1274    0
    695     0
    10      0
    220     1
    Name: survived, dtype: int64
    
    type(xTrainDictList) =  <class 'list'> ----xTrainDictList[0] = 
     {'pclass': '3rd', 'age': 31.19418104265403, 'sex': 'male'}
     
    type(featureNamesList) =  <class 'list'> ----featureNamesList = 
     ['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male']
     
    type(xTrainNdArray) =  <class 'numpy.ndarray'> ----xTrainNdArray = 
     [[31.19418104  0.          0.          1.          0.          1.        ]
     [31.19418104  1.          0.          0.          0.          1.        ]
     [24.          0.          0.          1.          0.          1.        ]
     ...
     [24.          0.          0.          1.          1.          0.        ]
     [11.          0.          0.          1.          1.          0.        ]
     [31.19418104  0.          0.          1.          1.          0.        ]]
     
    type(xTestNdArray) =  <class 'numpy.ndarray'> ----xTestNdArray = 
     [[18.          1.          0.          0.          1.          0.        ]
     [31.19418104  0.          0.          1.          0.          1.        ]
     [18.          0.          0.          1.          1.          0.        ]
     ...
     [22.          0.          0.          1.          1.          0.        ]
     [31.19418104  0.          0.          1.          0.          1.        ]
     [31.19418104  0.          0.          1.          0.          1.        ]]
     
    type(predictTestSeries) =  <class 'numpy.ndarray'> ----predictTestSeries = 
     [1 0 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
     0 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0
     0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 1
     0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0
     0 1 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0
     0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1
     0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0 1 0 1 0 1 0 1 0
     0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
     0 0 1 0 0 1 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
     
    type(predictScore) =  <class 'numpy.float64'> ----predictScore =  0.8297872340425532
    

    三、回归树

    sklearn.tree.DecisionTreeRegressor()

    • 回归决策树算法不是构建方程,原理类似分类决策树

    四、分类树 v.s. 回归树

    1、分类树总体流程

    • 我们以对人的性别预测为例来说明,假定训练集中有四个人A、B、C、D,性别分别是男,女(目标值),feature(特征)有“在网时长”、“购物金额”。
    • 我们知道C4.5分类树在每次分枝时,是穷举每一个feature的每一个阈值,找最好的分割点,即该分割点使得按照feature<=阈值,和feature>阈值为条件分成的两个分枝时的信息熵增益最大,即:特征 a a a 对训练数据集 D D D 的信息增益 G a i n ( D , a ) = E n t ( D ) − E n t ( D ∣ a ) Gain(D,a)=Ent(D)-Ent(D|a) Gain(D,a)=Ent(D)Ent(Da)。按照该标准分枝得到两个新节点。
    • 用同样方法继续分枝直到所有人都被分入性别唯一的叶子节点,或达到预设的终止条件,若最终叶子节点中的性别不唯一,则以多数人的性别作为该叶子节点的性别。

    2、回归树总体流程

    • 我们以对人的年龄预测为例来说明,假定训练集中有四个人A、B、C、D,年龄分别是14,16,24,26(目标值),feature(特征)有“在网时长”、“购物金额”。
    • 不过在每个节点(不一定是叶子节点)都会得一个预测值,该预测值等于属于这个节点的所有人年龄的平均值。分枝时穷举每一个feature的每个阈值,找最好的分割点,但衡量最好的标准不再是最大熵,而是最小化均方误差,即该分割点使得按照feature<=阈值,和feature>阈值为条件分成的两个分枝的均方误差 1 n ∑ i = 1 n ( x i − μ ) 2 \cfrac{1}{n}\sum^n_{i=1}(x_i-μ)^2 n1i=1n(xiμ)2 之和最小。
    • 用同样方法继续分枝直到每个叶子节点上人的年龄都唯一或者达到预设的终止条件(如叶子个数上限),若最终叶子节点上人的年龄不唯一,则以该节点上所有人的平均年龄做为该叶子节点的预测年龄。

    五、随机森林(样本随机,特征随机)

    集成学习方法:通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测。

    随机森林:是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定,即所有决策树投票决定目标值的类别。
    数据越复杂,随机森林的优势越明显,因为随机森林估计器中有很多超参数可以进行调优。

    1、为什么使用随机森林

    1. 随机森林既可以用于分类问题,也可以用于回归问题;
    2. 过拟合是个关键的问题,可能会让模型的结果变得糟糕,但是对于随机森林来说,如果随机森林的树足够多,那么分类器就不会过拟合模型;
    3. 随机森林分类器可以处理缺失值;
    4. 随机森林分类器可以用分类值建模;

    2、随机森林建造过程

    随机森林中每棵树的建造过程:

    • N N N 来表示训练样本的总数量, M M M 表示特征总数目。
    • 随机选出 m m m 个特征用于该棵决策树, m < < M m<<M m<<M m m m 远小于 M M M), m m m 过大容易过拟合。
    • 从总体的 N N N 个训练样本中以有放回抽样的方式随机取样 N N N,形成一个训练集(即bootstrap取样),并用未抽到的样本作测试集,评估其误差。
    • 在随机森林算法中,不用考虑各个特征之间的耦合关系(不需要用PCA处理),因为每棵树的 m m m 个特征是随机选出的,随机森林里的所有决策树一起可以消除特征的耦合影响;

    3、随机森林和单棵树的关系

    • 随机森林里的所有树可以都使用决策树分类器;
    • 随机森林里的树也可以使用SVM、Logistic回归等其他分类器,习惯上,这些分类器组成的“总分类器”仍然叫做随机森林。

    4、为什么要随机抽样训练集?

    如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的。

    5、为什么要有放回地抽样?

    如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。

    6、随机森林分类器Api

    class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, andom_state=None)

    • n_estimators:integer,optional(default = 10) 森林里的树木数量,实践中经验取值为:120,200,300,500,800,1200
    • criteria:string,可选(default =“gini”)分割特征的测量方法,一般使用默认的gini系数,比信息增益(entropy)划分准确一些;
    • max_depth:integer或None,可选(默认=无)树的最大深度
    • bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样
    • max_features:(default = auto),每个决策树的最大特征数量,
      • max_features=‘auto’:max_features=sqrt(n_features)
      • max_features=‘sqrt’:max_features=sqrt(n_features)
      • max_features=‘log2’:max_features=log2(n_features)
      • None:max_features = n_features

    随机森林模型是稳健的:随机森林分类器比较容易调参,参数在一个很宽的范围内都能达到差不多的效果。相对比的,SVM就没那么稳健,SVM算法的参数取值里只有少数几个值能使得模型效果不错,参数稍微改动一下,模型效果就千差万别,相对不容易把握。

    7、随机森林案例

    import pandas as pd
    from sklearn.model_selection import train_test_split, GridSearchCV
    from sklearn.feature_extraction import DictVectorizer
    from sklearn.tree import DecisionTreeClassifier, export_graphviz
    from sklearn.ensemble import RandomForestClassifier
    
    
    def decision():
        """决策树对泰坦尼克号进行预测生死"""
        # 获取数据
        titanic = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
        print('type(titanic) = ', type(titanic), '----titanic = \n', titanic.head(5))
    
        # 一、数据处理
        # 1.1 找出特征数据值和目标值
        xDataFrame = titanic[['pclass', 'age', 'sex']]
        ySeries = titanic['survived']
        print('type(xDataFrame) = ', type(xDataFrame), '----特征数据值,xDataFrame = \n', xDataFrame.head(5))
        print('type(ySeries) = ', type(ySeries), '----目标值,ySeries = \n', ySeries.head(5))
        # 缺失值处理
        xDataFrame['age'].fillna(xDataFrame['age'].mean(), inplace=True)
    
        # 二、特征工程
        # 2.1 分割数据集到训练集合测试集
        xTrainDataFrame, xTestDataFrame, yTrainSeries, yTestSeries = train_test_split(xDataFrame, ySeries, test_size=0.25)
        print('type(xTrainDataFrame) = ', type(xTrainDataFrame), '----xTrainDataFrame = \n', xTrainDataFrame.head(5))
        print('type(xTestDataFrame) = ', type(xTestDataFrame), '----xTestDataFrame = \n', xTestDataFrame.head(5))
        print('type(yTrainSeries) = ', type(yTrainSeries), '----yTrainSeries = \n', yTrainSeries.head(5))
        print('type(yTestSeries) = ', type(yTestSeries), '----yTestSeries = \n', yTestSeries.head(5))
        # 2.2 特征抽取(字典数据类型,当特征值是类别时,进行ont-hot编码)
        dv = DictVectorizer(sparse=False)  # 实例化字典类型数据的特征抽取器(默认值为sparse=True,为True时返回sparse矩阵,当为False时,返回矩阵)
        xTrainDictList = xTrainDataFrame.to_dict(orient="records")  # 将DataFrame格式的xTrain转为Dict字典类型
        xTestDictList = xTestDataFrame.to_dict(orient="records")  # 将DataFrame格式的xTest转为Dict字典类型
        print('type(xTrainDictList) = ', type(xTrainDictList), '----xTrainDictList[0] = \n', xTrainDictList[0])
        xTrainNdArray = dv.fit_transform(xTrainDictList)  # 训练集特征抽取,返回一个ndarray格式的ont-hot编码后的xTrain
        xTestNdArray = dv.transform(xTestDictList);  # 测试集特征抽取
        featureNamesList = dv.get_feature_names()
        print('type(featureNamesList) = ', type(featureNamesList), '----featureNamesList = \n', featureNamesList)
        print('type(xTrainNdArray) = ', type(xTrainNdArray), '----xTrainNdArray = \n', xTrainNdArray)
        print('type(xTestNdArray) = ', type(xTestNdArray), '----xTestNdArray = \n', xTestNdArray)
    
        # 三、算法工程(决策树)
        # # 3.1 实例化一个决策树估计器对象
        # dec_estimator = DecisionTreeClassifier(criterion='entropy', max_depth=2)  # 默认使用gini系数,或采用“entropy”信息增益,max_depth为决策树层数
        # # 3.2 调用fit方法,进行训练
        # dec_estimator.fit(xTrainNdArray, yTrainSeries)
        #
        # # 四、模型评估
        # # 4.1 数据预测,得出预测结果
        # predictTestSeries = dec_estimator.predict(xTestNdArray)
        # # 4.2 计算准确率
        # predictScore = dec_estimator.score(xTestNdArray, yTestSeries)  # 输入”测试集“的特征数据值、目标值
        # # 4.3 导出决策树的结构文件(dot格式)
        # export_graphviz(dec_estimator, out_file="./tree.dot", feature_names=['年龄', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
        # # windows安装graphviz软件,运行命令(dot -Tpng tree.dot -o tree.png)将dot文件转换为pdf、png,如果出现“Format: "png" not recognized. Use one of:”错误提示,则在管理员模式下打开cmd窗口,输入"dot -c",然后再运行命令。
    
        # 三、算法工程(随机森林)
        # 3.1 实例化一个随机森林估计器对象(随机森林无法导出决策树的结构文件)
        rf = RandomForestClassifier()
        # 3.2 网格搜索进行超参数调优,构造一些参数的值进行搜索
        param = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}
        # 网格搜索与交叉验证
        gc = GridSearchCV(rf, param_grid=param, cv=2)
        gc.fit(xTrainNdArray, yTrainSeries)
    
        # 四、模型评估
        predictTestSeries = gc.predict(xTestNdArray)
        scoreTest = gc.score(xTestNdArray, yTestSeries)
        print("在测试集上的预测结果,predictTestSeries =\n", predictTestSeries)
        print("在测试集上准确率,scoreTest = ", scoreTest)
        print("查看选择的参数模型:", gc.best_params_)
        return None
    
    
    if __name__ == "__main__":
        decision()
    

    打印结果:

    type(titanic) =  <class 'pandas.core.frame.DataFrame'> ----titanic = 
        row.names pclass  survived   ...        ticket   boat     sex
    0          1    1st         1   ...    24160 L221      2  female
    1          2    1st         0   ...           NaN    NaN  female
    2          3    1st         0   ...           NaN  (135)    male
    3          4    1st         0   ...           NaN    NaN  female
    4          5    1st         1   ...           NaN     11    male
    [5 rows x 11 columns]
    
    type(xDataFrame) =  <class 'pandas.core.frame.DataFrame'> ----特征数据值,xDataFrame = 
       pclass      age     sex
    0    1st  29.0000  female
    1    1st   2.0000  female
    2    1st  30.0000    male
    3    1st  25.0000  female
    4    1st   0.9167    male
    
    type(ySeries) =  <class 'pandas.core.series.Series'> ----目标值,ySeries = 
     0    1
    1    0
    2    0
    3    0
    4    1
    Name: survived, dtype: int64
    
    type(xTrainDataFrame) =  <class 'pandas.core.frame.DataFrame'> ----xTrainDataFrame = 
          pclass        age   sex
    213     1st  31.194181  male
    1243    3rd  31.194181  male
    108     1st  44.000000  male
    254     1st  61.000000  male
    1198    3rd  31.194181  male
    
    type(xTestDataFrame) =  <class 'pandas.core.frame.DataFrame'> ----xTestDataFrame = 
          pclass        age     sex
    836     3rd  37.000000    male
    1290    3rd  31.194181    male
    1233    3rd  31.194181  female
    892     3rd  31.194181    male
    62      1st  31.194181    male
    
    type(yTrainSeries) =  <class 'pandas.core.series.Series'> ----yTrainSeries = 
     213     0
    1243    0
    108     1
    254     0
    1198    0
    Name: survived, dtype: int64
    
    type(yTestSeries) =  <class 'pandas.core.series.Series'> ----yTestSeries = 
     836     0
    1290    0
    1233    0
    892     0
    62      0
    Name: survived, dtype: int64
    
    type(xTrainDictList) =  <class 'list'> ----xTrainDictList[0] = 
     {'pclass': '1st', 'age': 31.19418104265403, 'sex': 'male'}
     
    type(featureNamesList) =  <class 'list'> ----featureNamesList = 
     ['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male']
     
    type(xTrainNdArray) =  <class 'numpy.ndarray'> ----xTrainNdArray = 
     [[31.19418104  1.          0.          0.          0.          1.        ]
     [31.19418104  0.          0.          1.          0.          1.        ]
     [44.          1.          0.          0.          0.          1.        ]
     ...
     [31.19418104  0.          0.          1.          0.          1.        ]
     [31.19418104  0.          0.          1.          1.          0.        ]
     [64.          1.          0.          0.          1.          0.        ]]
     
    type(xTestNdArray) =  <class 'numpy.ndarray'> ----xTestNdArray = 
     [[37.          0.          0.          1.          0.          1.        ]
     [31.19418104  0.          0.          1.          0.          1.        ]
     [31.19418104  0.          0.          1.          1.          0.        ]
     ...
     [31.19418104  0.          0.          1.          0.          1.        ]
     [26.          0.          0.          1.          0.          1.        ]
     [ 8.          0.          1.          0.          1.          0.        ]]
     
    在测试集上的预测结果,predictTestSeries =
     [0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1
     1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
     0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1
     0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
     0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
     1 0 0 1 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
     0 0 1 1 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1
     0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0
     1 0 1 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 1 0 1 0 0 1]
     
    在测试集上准确率,scoreTest =  0.8237082066869301
    
    查看选择的参数模型: {'max_depth': 5, 'n_estimators': 300}
    

    8、使用随机森林计算特征重要度

    随机森林是常用的衡量特征重要性方法:计算正例经过的结点,使用经过节点的数目、经过节点的gini系数和等指标。或者,随机替换一列数据,重新建立决策树,计算模型的正确率变化,从而考虑这一列特征的重要性。

    • selection frequency
    • gini importance
    • permutation importance

    9、随机森林的优缺点

    9.1 随机森林的优点

    • 在当前所有算法中,具有极好的准确率
    • 能够有效地运行在大数据集上(“大”体现在样本数、特征数);
    • 能够处理具有高维特征的输入样本,而且不需要降维
    • 能够评估各个特征在分类问题上的重要性;
    • 对于缺省值问题也能够获得很好得结果;
    • 随机森林是使用最多的一种机器学习算法
    • 由于采用了集成算法,本身精度比大多数单个算法要好,所以准确性高
    • 在测试集上表现良好,由于两个随机性的引入,使得随机森林不容易陷入过拟合(样本随机,特征随机)
    • 在工业上,由于两个随机性的引入,使得随机森林具有一定的抗噪声能力,对比其他算法具有一定优势
    • 由于树的组合,使得随机森林可以处理非线性数据,本身属于非线性分类(拟合)模型
    • 它能够处理很高维度(feature很多)的数据,并且不用做特征选择,对数据集的适应能力强:既能处理离散型数据,也能处理连续型数据,数据集无需规范化
    • 训练速度快,可以运用在大规模数据集上
    • 可以处理缺省值(单独作为一类),不用额外处理
    • 由于有袋外数据(OOB),可以在模型生成过程中取得真实误差的无偏估计,且不损失训练数据量
    • 在训练过程中,能够检测到feature间的互相影响,且可以得出feature的重要性,具有一定参考意义
    • 由于每棵树可以独立、同时生成,容易做成并行化方法
    • 由于实现简单、精度高、抗过拟合能力强,当面对非线性数据时,适于作为基准模型

    8.2 随机森林的缺点

    • 超参数调优,找不到合适的参数组合来调优。
    • 当随机森林中的决策树个数很多时,训练时需要的空间和时间会比较大
    • 随机森林中还有许多不好解释的地方,有点算是黑盒模型
    • 在某些噪音比较大的样本集上,RF的模型容易陷入过拟合

    六、极限森林(Extremely Randomized Forest)

    决策树,进行裂分时候,根据信息增益最大进行裂分,刻板, 情深不寿,慧极必伤。

    极限森林: 1、样本随机 2、分裂条件随机(每次裂分不是按照最好的裂分条件裂分,即不是按照信息增益最大值裂分)

    • 像在随机森林中一样,使用候选特征的随机子集,但不是寻找最有区别的阈值,
    • 而是为每个候选特征随机绘制阈值,
    • 并选择这些随机生成的阈值中的最佳阈值作为划分规则。
    from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier
    from sklearn import datasets
    from sklearn.model_selection import train_test_split
    from sklearn.tree import DecisionTreeClassifier
    
    if __name__ == "__main__":
        """极限森林对泰坦尼克号进行预测生死"""
        # 获取数据
        wine = datasets.load_wine()
    
        # 一、数据处理
        # 1.1 找出特征数据值和目标值
        X = wine['data']
        y = wine['target']
        print('type(X) = ', type(X), '----特征数据值,X = \n', X)
        print('type(y) = ', type(y), '----目标值,y = \n', y)
    
        # 二、特征工程
        # 2.1 分割数据集到训练集合测试集
        x_train_Ndarray, x_test_Ndarray, y_train_Ndarray, y_test_Ndarray = train_test_split(X, y, test_size=0.2)
        print('type(x_train_Ndarray) = ', type(x_train_Ndarray), '----x_train_Ndarray = \n', x_train_Ndarray)
        print('type(x_test_Ndarray) = ', type(x_test_Ndarray), '----x_test_Ndarray = \n', x_test_Ndarray)
        print('type(y_train_Ndarray) = ', type(y_train_Ndarray), '----y_train_Ndarray = \n', y_train_Ndarray)
        print('type(y_test_Ndarray) = ', type(y_test_Ndarray), '----y_test_Ndarray = \n', y_test_Ndarray)
    
        # 三、算法工程(极限森林)
        # 3.1 实例化一个极限森林估计器对象
        et = ExtraTreesClassifier(n_estimators=100)
        # 3.2 调用fit方法,进行训练
        et.fit(x_train_Ndarray, y_train_Ndarray)
        # 3.3 计算准确率
        score = et.score(x_test_Ndarray, y_test_Ndarray)  # 输入”测试集“的特征数据值、目标值
        print("单个极限森林的准确度:score = ", score)
    
        # 四、对比模型01:算法工程(随机森林)
        # 4.1 实例化一个随机森林估计器对象
        rf = RandomForestClassifier(n_estimators=100)
        # 4.2 调用fit方法,进行训练
        rf.fit(x_train_Ndarray, y_train_Ndarray)
        # 4.3 计算准确率
        score01 = rf.score(x_test_Ndarray, y_test_Ndarray)  # 输入”测试集“的特征数据值、目标值
        print("单个随机森林的准确度:score01 = ", score01)
    
        # 五、对比模型0:2:随机多次创建决策树,计算准确率平均值
        score02 = 0
        for i in range(100):
            X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
            dt_clf = DecisionTreeClassifier()
            dt_clf.fit(X_train, y_train)
            score02 += dt_clf.score(X_test, y_test)
        score02 = score02 / 100
        print('决策树多次运行准确率:score02 = ', score02)
    
        # 六、对比模型03:随机多次创建随机森林,计算准确率平均值
        score03 = 0
        for i in range(100):
            X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
            clf = RandomForestClassifier(n_estimators=100)
            clf.fit(X_train, y_train)
            score03 += clf.score(X_test, y_test)
        score03 = score03 / 100
        print('随机森林多次运行准确率:score03 = ', score03)
    
        # 七、对比模型03:随机多次创建随机森林,计算准确率平均值
        score04 = 0
        for i in range(100):
            X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
            clf = RandomForestClassifier(n_estimators=100)
            clf.fit(X_train, y_train)
            score04 += clf.score(X_test, y_test)
        score04 = score04 / 100
        print('极限森林多次运行准确率:score04 = ', score04)
    

    打印结果:

    type(X) =  <class 'numpy.ndarray'> ----特征数据值,X = 
     [[1.423e+01 1.710e+00 2.430e+00 ... 1.040e+00 3.920e+00 1.065e+03]
     [1.320e+01 1.780e+00 2.140e+00 ... 1.050e+00 3.400e+00 1.050e+03]
     [1.316e+01 2.360e+00 2.670e+00 ... 1.030e+00 3.170e+00 1.185e+03]
     ...
     [1.327e+01 4.280e+00 2.260e+00 ... 5.900e-01 1.560e+00 8.350e+02]
     [1.317e+01 2.590e+00 2.370e+00 ... 6.000e-01 1.620e+00 8.400e+02]
     [1.413e+01 4.100e+00 2.740e+00 ... 6.100e-01 1.600e+00 5.600e+02]]
    type(y) =  <class 'numpy.ndarray'> ----目标值,y = 
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
     1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
     1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
     2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
    type(x_train_Ndarray) =  <class 'numpy.ndarray'> ----x_train_Ndarray = 
     [[1.208e+01 1.330e+00 2.300e+00 ... 1.070e+00 3.210e+00 6.250e+02]
     [1.420e+01 1.760e+00 2.450e+00 ... 1.050e+00 2.850e+00 1.450e+03]
     [1.237e+01 1.070e+00 2.100e+00 ... 1.040e+00 2.770e+00 6.600e+02]
     ...
     [1.358e+01 2.580e+00 2.690e+00 ... 7.400e-01 1.800e+00 7.500e+02]
     [1.237e+01 9.400e-01 1.360e+00 ... 1.050e+00 1.820e+00 5.200e+02]
     [1.388e+01 1.890e+00 2.590e+00 ... 8.800e-01 3.560e+00 1.095e+03]]
    type(x_test_Ndarray) =  <class 'numpy.ndarray'> ----x_test_Ndarray = 
     [[1.410e+01 2.020e+00 2.400e+00 1.880e+01 1.030e+02 2.750e+00 2.920e+00
      3.200e-01 2.380e+00 6.200e+00 1.070e+00 2.750e+00 1.060e+03]
     [1.208e+01 1.830e+00 2.320e+00 1.850e+01 8.100e+01 1.600e+00 1.500e+00
      5.200e-01 1.640e+00 2.400e+00 1.080e+00 2.270e+00 4.800e+02]
     [1.316e+01 3.570e+00 2.150e+00 2.100e+01 1.020e+02 1.500e+00 5.500e-01
      4.300e-01 1.300e+00 4.000e+00 6.000e-01 1.680e+00 8.300e+02]
     [1.184e+01 2.890e+00 2.230e+00 1.800e+01 1.120e+02 1.720e+00 1.320e+00
      4.300e-01 9.500e-01 2.650e+00 9.600e-01 2.520e+00 5.000e+02]
     [1.237e+01 1.170e+00 1.920e+00 1.960e+01 7.800e+01 2.110e+00 2.000e+00
      2.700e-01 1.040e+00 4.680e+00 1.120e+00 3.480e+00 5.100e+02]
     [1.221e+01 1.190e+00 1.750e+00 1.680e+01 1.510e+02 1.850e+00 1.280e+00
      1.400e-01 2.500e+00 2.850e+00 1.280e+00 3.070e+00 7.180e+02]
     [1.264e+01 1.360e+00 2.020e+00 1.680e+01 1.000e+02 2.020e+00 1.410e+00
      5.300e-01 6.200e-01 5.750e+00 9.800e-01 1.590e+00 4.500e+02]
     [1.437e+01 1.950e+00 2.500e+00 1.680e+01 1.130e+02 3.850e+00 3.490e+00
      2.400e-01 2.180e+00 7.800e+00 8.600e-01 3.450e+00 1.480e+03]
     [1.285e+01 1.600e+00 2.520e+00 1.780e+01 9.500e+01 2.480e+00 2.370e+00
      2.600e-01 1.460e+00 3.930e+00 1.090e+00 3.630e+00 1.015e+03]
     [1.182e+01 1.470e+00 1.990e+00 2.080e+01 8.600e+01 1.980e+00 1.600e+00
      3.000e-01 1.530e+00 1.950e+00 9.500e-01 3.330e+00 4.950e+02]
     [1.402e+01 1.680e+00 2.210e+00 1.600e+01 9.600e+01 2.650e+00 2.330e+00
      2.600e-01 1.980e+00 4.700e+00 1.040e+00 3.590e+00 1.035e+03]
     [1.317e+01 5.190e+00 2.320e+00 2.200e+01 9.300e+01 1.740e+00 6.300e-01
      6.100e-01 1.550e+00 7.900e+00 6.000e-01 1.480e+00 7.250e+02]
     [1.349e+01 3.590e+00 2.190e+00 1.950e+01 8.800e+01 1.620e+00 4.800e-01
      5.800e-01 8.800e-01 5.700e+00 8.100e-01 1.820e+00 5.800e+02]
     [1.229e+01 1.410e+00 1.980e+00 1.600e+01 8.500e+01 2.550e+00 2.500e+00
      2.900e-01 1.770e+00 2.900e+00 1.230e+00 2.740e+00 4.280e+02]
     [1.258e+01 1.290e+00 2.100e+00 2.000e+01 1.030e+02 1.480e+00 5.800e-01
      5.300e-01 1.400e+00 7.600e+00 5.800e-01 1.550e+00 6.400e+02]
     [1.345e+01 3.700e+00 2.600e+00 2.300e+01 1.110e+02 1.700e+00 9.200e-01
      4.300e-01 1.460e+00 1.068e+01 8.500e-01 1.560e+00 6.950e+02]
     [1.363e+01 1.810e+00 2.700e+00 1.720e+01 1.120e+02 2.850e+00 2.910e+00
      3.000e-01 1.460e+00 7.300e+00 1.280e+00 2.880e+00 1.310e+03]
     [1.242e+01 1.610e+00 2.190e+00 2.250e+01 1.080e+02 2.000e+00 2.090e+00
      3.400e-01 1.610e+00 2.060e+00 1.060e+00 2.960e+00 3.450e+02]
     [1.251e+01 1.730e+00 1.980e+00 2.050e+01 8.500e+01 2.200e+00 1.920e+00
      3.200e-01 1.480e+00 2.940e+00 1.040e+00 3.570e+00 6.720e+02]
     [1.369e+01 3.260e+00 2.540e+00 2.000e+01 1.070e+02 1.830e+00 5.600e-01
      5.000e-01 8.000e-01 5.880e+00 9.600e-01 1.820e+00 6.800e+02]
     [1.373e+01 4.360e+00 2.260e+00 2.250e+01 8.800e+01 1.280e+00 4.700e-01
      5.200e-01 1.150e+00 6.620e+00 7.800e-01 1.750e+00 5.200e+02]
     [1.208e+01 1.130e+00 2.510e+00 2.400e+01 7.800e+01 2.000e+00 1.580e+00
      4.000e-01 1.400e+00 2.200e+00 1.310e+00 2.720e+00 6.300e+02]
     [1.390e+01 1.680e+00 2.120e+00 1.600e+01 1.010e+02 3.100e+00 3.390e+00
      2.100e-01 2.140e+00 6.100e+00 9.100e-01 3.330e+00 9.850e+02]
     [1.368e+01 1.830e+00 2.360e+00 1.720e+01 1.040e+02 2.420e+00 2.690e+00
      4.200e-01 1.970e+00 3.840e+00 1.230e+00 2.870e+00 9.900e+02]
     [1.299e+01 1.670e+00 2.600e+00 3.000e+01 1.390e+02 3.300e+00 2.890e+00
      2.100e-01 1.960e+00 3.350e+00 1.310e+00 3.500e+00 9.850e+02]
     [1.387e+01 1.900e+00 2.800e+00 1.940e+01 1.070e+02 2.950e+00 2.970e+00
      3.700e-01 1.760e+00 4.500e+00 1.250e+00 3.400e+00 9.150e+02]
     [1.383e+01 1.650e+00 2.600e+00 1.720e+01 9.400e+01 2.450e+00 2.990e+00
      2.200e-01 2.290e+00 5.600e+00 1.240e+00 3.370e+00 1.265e+03]
     [1.207e+01 2.160e+00 2.170e+00 2.100e+01 8.500e+01 2.600e+00 2.650e+00
      3.700e-01 1.350e+00 2.760e+00 8.600e-01 3.280e+00 3.780e+02]
     [1.419e+01 1.590e+00 2.480e+00 1.650e+01 1.080e+02 3.300e+00 3.930e+00
      3.200e-01 1.860e+00 8.700e+00 1.230e+00 2.820e+00 1.680e+03]
     [1.222e+01 1.290e+00 1.940e+00 1.900e+01 9.200e+01 2.360e+00 2.040e+00
      3.900e-01 2.080e+00 2.700e+00 8.600e-01 3.020e+00 3.120e+02]
     [1.179e+01 2.130e+00 2.780e+00 2.850e+01 9.200e+01 2.130e+00 2.240e+00
      5.800e-01 1.760e+00 3.000e+00 9.700e-01 2.440e+00 4.660e+02]
     [1.229e+01 3.170e+00 2.210e+00 1.800e+01 8.800e+01 2.850e+00 2.990e+00
      4.500e-01 2.810e+00 2.300e+00 1.420e+00 2.830e+00 4.060e+02]
     [1.277e+01 3.430e+00 1.980e+00 1.600e+01 8.000e+01 1.630e+00 1.250e+00
      4.300e-01 8.300e-01 3.400e+00 7.000e-01 2.120e+00 3.720e+02]
     [1.247e+01 1.520e+00 2.200e+00 1.900e+01 1.620e+02 2.500e+00 2.270e+00
      3.200e-01 3.280e+00 2.600e+00 1.160e+00 2.630e+00 9.370e+02]
     [1.320e+01 1.780e+00 2.140e+00 1.120e+01 1.000e+02 2.650e+00 2.760e+00
      2.600e-01 1.280e+00 4.380e+00 1.050e+00 3.400e+00 1.050e+03]
     [1.334e+01 9.400e-01 2.360e+00 1.700e+01 1.100e+02 2.530e+00 1.300e+00
      5.500e-01 4.200e-01 3.170e+00 1.020e+00 1.930e+00 7.500e+02]]
    type(y_train_Ndarray) =  <class 'numpy.ndarray'> ----y_train_Ndarray = 
     [1 0 1 1 1 0 0 1 2 0 2 1 1 1 0 1 0 2 2 1 0 0 2 0 1 2 0 2 2 2 2 1 1 0 1 2 0
     2 1 0 0 0 1 1 0 0 2 1 1 2 1 2 1 2 1 1 0 1 0 0 1 2 1 2 0 0 1 0 1 0 1 2 2 2
     2 1 2 1 0 1 0 1 1 2 1 0 2 0 2 1 2 1 0 1 0 2 0 0 0 1 2 0 0 2 0 1 1 0 0 2 1
     2 2 0 0 0 2 1 0 2 0 0 1 1 1 0 1 1 2 1 2 0 2 1 1 0 2 2 1 2 1 0]
    type(y_test_Ndarray) =  <class 'numpy.ndarray'> ----y_test_Ndarray = 
     [0 1 2 1 1 1 1 0 0 1 0 2 2 1 2 2 0 1 1 2 2 1 0 0 1 0 0 1 0 1 1 1 1 1 0 1]
    单个极限森林的准确度:score =  0.9722222222222222
    单个随机森林的准确度:score01 =  0.9166666666666666
    决策树多次运行准确率:score02 =  0.909722222222222
    随机森林多次运行准确率:score03 =  0.9780555555555561
    极限森林多次运行准确率:score04 =  0.9800000000000003
    
    展开全文
  • 1.bootstrap 在原始数据的范围内作有放回的再抽样M个, 样本容量仍为n,原始数据中每个观察单位每次被到的概率相等, 为1/n , 所得样本称为Bootstrap样本。于是可得到参数θ的一个估计值θ^(b),这样重复若干次,记...

     1.bootstrap   在原始数据的范围内作有放回的再抽样M个, 样本容量仍为n,原始数据中每个观察单位每次被抽到的概率相等, 为1/n , 所得样本称为Bootstrap样本。于是可得到参数θ的一个估计值θ^(b),这样重复若干次,记为B 。为了可以避免一些误差点对少量树的决策影响。 

     

     2.决策树 : 

       信息熵: Ent(D) = - ΣPk*logPk, Ent(D)的值越小,则D的纯度越高
               信息增益: ID3中使用, 存在过拟合的情况,

                           避免过拟合的方法,1. 通过significant test,用判断成功的概率来判断要不要进行剩下的分类

                                                            2. 进行剪枝,去掉该枝还是可以完成正确的分类,就说明该枝没有用

               举例说明: 17个西瓜, 8个好瓜, 9个坏西瓜

                                P1 = 8/17, P2 = 9/17 

                                当前的信息熵 = -(8/17*log(8/17)+9/17*log(9/17))

                                根据色泽特征(绿色,红色,白色)分成了3类

                                             绿色里面有6个瓜,3个好瓜,3个坏瓜, 红色里面有4个好瓜,2个坏瓜, 白色里面有一个好瓜,4个坏瓜

                                             Ent(D1) = -(3/6*log(3/6) + 3/6*log(3/6))  根据绿色条件分出了6个西瓜,其中3个好瓜,3个坏瓜

                                             Ent(D2) = -(4/6*log(4/6) + 2/6*log(2/6))  根据红色条件分出了6个西瓜,其中4个好瓜,2个坏瓜

                                             Ent(D3) = -(1/5*log(1/5) + 4/5*log(4/5))   根据白色条件分出了5个西瓜,其中1个坏瓜,4个好瓜
                                 信息增益率 = 上一次的信息熵 - 当前信息熵 

                                                   =  -(8/17*log(8/17)+9/17*log(9/17)) - (6/17 * Ent(D1)  + 6/17 * Ent(D2) + 5/17*Ent(D3))  > 0 说明存在信息增益

                    信息增益率: C4,5

                              通过进行前后的信息熵的相除 

                     CART算法: 基尼系数, 从两个样本中随机抽取两个样例,其类别标记不一致的概率

                                                Gini(D) = 1 - ΣPk^2 

                       如果是连续值的话,那么进行的就是回归树的分类

                        多分类  ΣΣPk*logPk

                  决策树:优势:

                                      - 非黑盒

                                      - 轻松去除无关attribute(Gain=0)

                                      - test 起来很快
                                劣势:

                                      - 只能线性分割数据
                                      - 贪婪算法(可能找不到最好的树)

     

    3. Bagging 表示集群树进行投票,根据票数的结果来统计最终结果

     

    4. Random Forest (随机森林) 在选取有限样本的同时,选取的特征也是有限的,有点像dropout,最后的结果进行投票

     

    5.  Boosting :

           1. 先在原始数据集中长出一个Tree,

           2 把前一个tree没有完美分类的数据,进行数据权重的重构,让没有分好的数据所占的权重更大

           3. 用新的re-weighted tree再训练一个tree

           4.最终的分类结果由投票决定

           根据前一个树的分类结果,来强化当前的树

    6. Adaboost

           步骤1 : 首先初始化数据的权重分布,每个训练样本最开始被赋予相同的权值

            D1 = (w11, w12, ...., W1n) W1i = 1/n i= 1, 2, ....N

           步骤2: 使用权值分布Dm的训练集学习,得到基本分类器(选取让误差率最低的阈值来设计基本分类器)

            步骤3: 计算Gm(x) 在训练数据集上的分类误差率,Wm = 当前分类器的分类误差, 根据错误率对训练数据进行加权

                          em = ΣWmIGm(xi) != yi

             步骤4: 带入上述进行权重加权的em,然后表示当前分类器的受重视程度

                          am = 1/2log(1-em/em) 当em<1/2 时 am>=0 且am随着em的减小而增大
                          意味着分类误差率越小的基本分类器在最终分类器的作用越大

               步骤5:组合各个弱分类器

    7.GBDT 

            Adaboost 的Regreesion版本
            Adaboost的em , 这里可以使用欧式距离或者交叉熵做为错误率判断的方式

            把残差做为下一轮的学习目标

           c .最终的结果有加权和值得到,不再是简单的多数投票

           G(x) = ΣamGm(x)

     

    8. XGboost 本身也是一种GBDT,但是把速度与效率做到了极值

    a. 使用L1, L2 Regularization 防止Overfitting, 加入正则化偏质相,使得每次梯度方向都存在一定的偏差,减少局部拟合的情况

    L1 

      w = argminΣ(t(xj) - Σwihi(xj)^2) + λΣwi 

    L2 

       w =argminΣ(t(xj) - Σwihi(xj)^2) + λΣwi^2 

    b. 对代价函数一阶与二阶求导,更快的Converge

    c. 树长全后再进行剪枝,防止贪心算法



                

     

     

     

     

     

     
       

     

         

     

                                                   

     

                                   

     

                         

     

                     

     

    转载于:https://www.cnblogs.com/my-love-is-python/p/9768912.html

    展开全文
  • R语言︱决策树族——随机森林算法

    万次阅读 多人点赞 2016-05-03 23:07:42
    基尼系数的选择的标准就是每个子节点达到最高的纯度,即落在子节点中的所有观察都属于同一个分类,此时基尼系数最小,纯度最高,不确定度最小。 决策树中最常用的四种算法: 基尼系数(Gini Index) 基尼系数指出:...



    每每以为攀得众山小,可、每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~

    ———————————————————————————


    笔者寄语:有一篇《有监督学习选择深度学习还是随机森林或支持向量机?》(作者BioSebastianRaschka)中提到,在日常机器学习工作或学习中,当我们遇到有监督学习相关问题时,不妨考虑下先用简单的假设空间(简单模型集合),例如线性模型逻辑回归。若效果不好,也即并没达到你的预期或评判效果基准时,再进行下换其他更复杂模型来实验。


    ——————————————————————————————————————————————


    一、随机森林理论介绍


    1.1 优缺点


    优点。

    (1)不必担心过度拟合;

    (2)适用于数据集中存在大量未知特征;

    (3)能够估计哪个特征在分类中更重要;

    (4)具有很好的抗噪声能力;

    (5)算法容易理解;

    (6)可以并行处理。

    缺点。

    (1)对小量数据集和低维数据集的分类不一定可以得到很好的效果。

    (2)执行速度虽然比Boosting等快,但是比单个的决策树慢很多。

    (3)可能会出现一些差异度非常小的树,淹没了一些正确的决策。


    1.2 生成步骤介绍


    1、从原始训练数据集中,应用bootstrap方法有放回地随机抽取k个新的自助样本集,并由此构建k棵分类回归树,每次未被抽到的样本组成了K个袋外数据(out-of-bag,BBB)。

    2、设有n 个特征,则在每一棵树的每个节点处随机抽取mtry 个特征,通过计算每个特征蕴含的信息量,特征中选择一个最具有分类能力的特征进行节点分裂。

    3、每棵树最大限度地生长, 不做任何剪裁

    4、将生成的多棵树组成随机森林, 用随机森林对新的数据进行分类, 分类结果按树分类器投票多少而定。


    1.3 随机森林与SVM的比较


    (1)不需要调节过多的参数,因为随机森林只需要调节树的数量,而且树的数量一般是越多越好,而其他机器学习算法,比如SVM,有非常多超参数需要调整,如选择最合适的核函数,正则惩罚等。

    (2)分类较为简单、直接。随机深林和支持向量机都是非参数模型(复杂度随着训练模型样本的增加而增大)。相较于一般线性模型,就计算消耗来看,训练非参数模型因此更为耗时耗力。分类树越多,需要更耗时来构建随机森林模型。同样,我们训练出来的支持向量机有很多支持向量,最坏情况为,我们训练集有多少实例,就有多少支持向量。虽然,我们可以使用多类支持向量机,但传统多类分类问题的执行一般是one-vs-all(所谓one-vs-all 就是将binary分类的方法应用到多类分类中。比如我想分成K类,那么就将其中一类作为positive),因此我们还是需要为每个类训练一个支持向量机。相反,决策树与随机深林则可以毫无压力解决多类问题。

    (3)比较容易入手实践。随机森林在训练模型上要更为简单。你很容易可以得到一个又好且具鲁棒性的模型。随机森林模型的复杂度与训练样本和树成正比。支持向量机则需要我们在调参方面做些工作,除此之外,计算成本会随着类增加呈线性增长。

    (4)小数据上,SVM优异,而随机森林对数据需求较大。就经验来说,我更愿意认为支持向量机在存在较少极值的小数据集上具有优势。随机森林则需要更多数据但一般可以得到非常好的且具有鲁棒性的模型。



    1.5 随机森林与深度学习的比较


    深度学习需要比随机森林更大的模型来拟合模型,往往,深度学习算法需要耗时更大,相比于诸如随机森林和支持向量机那样的现成分类器,安装配置好一个神经网络模型来使用深度学习算法的过程则更为乏味。

    但不可否认,深度学习在更为复杂问题上,如图片分类,自然语言处理,语音识别方面更具优势。

    另外一个优势为你不需要太关注特征工程相关工作。实际上,至于如何选择分类器取决于你的数据量和问题的一般复杂性(和你要求的效果)。这也是你作为机器学习从业者逐步会获得的经验。

    可参考论文《An Empirical Comparison of Supervised Learning Algorithms》。



    1.6 随机森林与决策树之间的区别


    模型克服了单棵决策树易过拟合的缺点,模型效果在准确性和稳定性方面都有显著提升。


    决策树+bagging=随机森林




    1.7 随机森林不会发生过拟合的原因


    在建立每一棵决策树的过程中,有两点需要注意-采样与完全分裂。首先是两个随机采样的过程,random forest对输入的数据要进行行、列的采样。对于行采样,采用有放回的方式,也就是在采样得到的样本集合中,可能有重复的样本。

    假设输入样本为N个,那么采样的样本也为N个。这样使得在训练的时候,每一棵树的输入样本都不是全部的样本,使得相对不容易出现over-fitting


    然后进行列采样,从Mfeature中,选择m(m << M)。之后就是对采样之后的数据使用完全分裂的方式建立出决策树,这样决策树的某一个叶子节点要么是无法继续分裂的,要么里面的所有样本的都是指向的同一个分类。一般很多的决策树算法都一个重要的步骤-剪枝,但是这里不这样干,由于之前的两个随机采样的过程保证了随机性,所以就算不剪枝,也不会出现over-fitting 按这种算法得到的随机森林中的每一棵都是很弱的,但是大家组合起来就很厉害了。


    可以这样比喻随机森林算法:每一棵决策树就是一个精通于某一个窄领域的专家(因为我们从Mfeature中选择m让每一棵决策树进行学习),这样在随机森林中就有了很多个精通不同领域的专家,对一个新的问题(新的输入数据),可以用不同的角度去看待它,最终由各个专家,投票得到结果。



    1.8 随机森林与梯度提升树(GBDT)区别


    随机森林:决策树+bagging=随机森林

    梯度提升树:决策树Boosting=GBDT


    两者区别在于bagging boosting之间的区别,可见:

     

     

    bagging

    boosting

    取样方式

    bagging采用均匀取样

    boosting根据错误率来采样

    精度、准确性

    相比之,较低

    训练集选择

    随机的,各轮训练集之前互相独立

    各轮训练集的选择与前面各轮的学习结果相关

    预测函数权重

    各个预测函数没有权重

    boost有权重

    函数生成顺序

    并行生成

    顺序生成

    应用

    象神经网络这样极为消耗时间的算法,bagging可通过并行节省大量的时间开销

    bagingboosting都可以有效地提高分类的准确性

    bagingboosting都可以有效地提高分类的准确性

    一些模型中会造成模型的退化(过拟合)

    boosting思想的一种改进型adaboost方法在邮件过滤,文本分类中有很好的性能

     

    随机森林

    梯度提升树

     

    1.9 决策树的特征选择


    本部分参考:随机森林简易教程

    特征选择目前比较流行的方法是信息增益、增益率、基尼系数和卡方检验。这里主要介绍基于基尼系数(GINI)的特征选择,因为随机森林采用的CART决策树就是基于基尼系数选择特征的。

    基尼系数的选择的标准就是每个子节点达到最高的纯度,即落在子节点中的所有观察都属于同一个分类,此时基尼系数最小,纯度最高,不确定度最小。

    决策树中最常用的四种算法:

    基尼系数(Gini Index)

    基尼系数指出:我们从总体中随机挑选两个样本,如果总体是纯的,那么这两个样本是同类别的概率为1。

    1. 用于处理分类型目标变量“Success”或者“Failure”。
    2. 它只作用于二进制分裂。
    3. 基尼系数越大,纯度越高。
    4. CART(分类和回归树)使用Gini方法创建二进制分裂。

    卡方(Chi-Square)

    它可以用来衡量子节点和父节点之间是否存在显著性差异。我们用目标变量的观测频率和期望频率之间的标准离差的平方和来计算卡方值。

    1. 它用于处理分类型目标变量“Success”或“Failure”。
    2. 它可以计算两个或多个分裂。
    3. 卡方越高,子节点与父节点之间的差异越显著。
    4. Chi-square = ((Actual – Expected)^2 / Expected)^1/2
    5. 它生成的树称为:CHAID (Chi-square Automatic Interaction Detector)

    如何计算一个分裂的卡方:

    1. 通过计算Success和Failure的偏差来计算单个节点的卡方。
    2. 通过计算每个节点的Success和Failure的所有卡方总和计算一个分裂的卡方。

    信息增益(Information Gain)

    观察下面的图像,想一下哪个节点描述起来更加容易。答案一定是C,因为C图中的所有的值都是相似的,需要较少的信息去解释。相比较,B和A需要更多的信息去描述。用纯度描述,就是:Pure(C) > Pure(B) > Pure(A)。

    图片描述

    纯度越高的节点,就会需要更少的信息去描述它;相反,不纯度越高,就会需要更多的信息。信息论用熵来定义系统的混乱程度。如果样本中的个体是完全相同类别的,那么系统的熵为0;如果样本是等划分的(50%-50%),那么系统的熵为1。

    方差削减(Reduction in Variance)

    至此,我们已经讨论了很多关于分类型目标变量的算法。方差削减是用于连续型目标变量的算法(回归问题)。它使用方差公式去挑选最优分裂。方差最小的分裂将会作为分割总体的准则。

    图片描述

    如何计算方差?

    1. 计算每一个节点的方差。
    2. 计算每一个节点方差的加权平均,作为一个分裂的方差。


    ——————————————————————————————————————————————


    二、随机森林重要性度量指标——重要性评分、Gini指数


    (1)重要性评分


    定义为袋外数据自变量值发生轻微扰动后的分类正确率与扰动前分类正确率的平均减少量。

    (1):对于每棵决策树,利用袋外数据进行预测,将袋外数据的预测误差将记录下来。其每棵树的误差是:vote1,vote2····,voteb;

    (2):随机变换每个预测变量,从而形成新的袋外数据,再利用袋外数据进行验证,其每个变量的误差是:vote11,vote12,···,vote1b。

    (3):对于某预测变量来说,计算其重要性是变换后的预测误差与原来相比的差的均值。

    r语言中代码:

    rf <- randomForest(Species ~ ., data=a, ntree=100, proximity=TRUE,importance=TRUE)


    (2)gini指数


    gini指数表示节点的纯度,gini指数越大纯度越低。gini值平均降低量表示所有树的变量分割节点平均减小的不纯度。对于变量重要度衡量,步骤如同前面介绍,将变量数据打乱,gini指数变化的均值作为变量的重要程度度量。


    gini(T)=1−∑j=1np2j


    (3)重要性绘图函数——varImpPlot(rf)函数




    ——————————————————————————————————————————————



    三、随机森林模型R语言实践


    3.1 随机森林模型几点注意


    模型中关于分类任务以及回归预测任务的区别:

    随机森林模型,分类和回归预测的操作不同之处在于判断因变量的类型,如果因变量是因子则执行分类任务,如果因变量是连续性变量,则执行回归预测任务。


    模型中关于数据结构的要求:

    `randomForest`函数要求为数据框或者矩阵,需要原来的数据框调整为以每个词作为列名称(变量)的数据框。在文本挖掘的过程中,需要把词频(横向,long型数据)转化为变量(wide型纵向数据),可以用reshape2、data.table包来中dcast来实现。具体实战见博客:R语言︱监督算法式的情感分析笔记的4.1节。



    随机森林的两个参数:

    候选特征数K
    K越大,单棵树的效果会提升,但树之间相关性也会增强
    决策树数量M
    M越大,模型效果会有提升,但计算量会变大



    R中与决策树有关的Package:

    单棵决策树:rpart/tree/C50
    随机森林:randomforest/ranger
    梯度提升树:gbm/xgboost
    树的可视化:rpart.plot


    3.2 模型拟合


    本文以R语言中自带的数据集iris为例,以setosa为因变量,其他作为自变量进行模型拟合,由于setosa本身就是因子型,所以不用转换形式。


    > data <- iris
    > library(randomForest)
    > system.time(Randommodel <- randomForest(Species ~ ., data=data,importance = TRUE, proximity = FALSE, ntree = 100))
    用户 系统 流逝 
       0    0    0 
    > print(Randommodel)
    
    Call:
     randomForest(formula = Species ~ ., data = data, importance = TRUE,      proximity = FALSE, ntree = 100) 
                   Type of random forest: classification
                         Number of trees: 100
    No. of variables tried at each split: 2
    
            OOB estimate of  error rate: 3.33%
    Confusion matrix:
               setosa versicolor virginica class.error
    setosa         50          0         0        0.00
    versicolor      0         47         3        0.06
    virginica       0          2        48        0.04

    代码解读:randomForset,执行建模,x参数设定自变量数据集,y参数设定因变量数据列,importance设定是否输出因变量在模型中的重要性,如果移除某个变量,模型方差增加的比例是它判断变量重要性的标准之一,proximity参数用于设定是否计算模型的临近矩阵,ntree用于设定随机森林的树数(后面单独讨论),最后一句输出模型在训练集上的效果。

    prInt输出模型在训练集上的效果,可以看出错误率为3.33%,维持在比较低的水平。


    3.3 随机森林模型重要性检测


    > importance(Randommodel,type=1)  #重要性评分
                 MeanDecreaseAccuracy
    Sepal.Length             4.720094
    Sepal.Width              1.405924
    Petal.Length            16.222059
    Petal.Width             13.895115
    > importance(Randommodel,type=2)  #Gini指数
                 MeanDecreaseGini
    Sepal.Length         9.484106
    Sepal.Width          1.930289
    Petal.Length        45.873386
    Petal.Width         41.894352
    > varImpPlot(Randommodel)         #可视化

    利用iris数据,可以看到这四个变量的重要性排序是一样的。



    3.4 模型的预测功能


    predict中有多种参数,比如Nodes,Proximity,predict.all。


    predict(object, newdata, type="response",
            norm.votes=TRUE, predict.all=FALSE, proximity=FALSE, nodes=FALSE,
            cutoff, ...)
    #Nodes判断是否是终点。Proximity判断是否需要进行近邻测量。predict.all判断是否保留所有的预测器。


    举例,以前面的随机森林模型进行建模。

    predict.all会输出一个150*150的字符矩阵,代表每一颗树的150个预测值(前面预设了ntree=100);

    Nodes输出100颗树的节点情况。


    prediction <- predict(Randommodel, data[,1:5],type="class")  #还有response回归类型
    
    table(observed =data$Species,predicted=prediction) 


    table输出混淆矩阵,注意table并不是需要把预测值以及实际值放在一个表格之中,只要顺序对上,用observed以及predicted直接调用也可以。


    3.5 补充——随机森林包(party包)


    与randomForest包不同之处在于,party可以处理缺失值,而这个包可以。

    library(party)
       #与randomForest包不同之处在于,party可以处理缺失值,而这个包可以
    set.seed(42)
    crf<-cforest(y~.,control = cforest_unbiased(mtry = 2, ntree = 50), data=step2_1)
    varimpt<-data.frame(varimp(crf))


    party包中的随机森林建模函数为cforest函数,

    mtry代表在每一棵树的每个节点处随机抽取mtry 个特征,通过计算每个特征蕴含的信息量,特征中选择一个最具有分类能力的特征进行节点分裂。

    varimp代表重要性函数。跟对着看:笔记+R︱风控模型中变量粗筛(随机森林party包)+细筛(woe包)




    每每以为攀得众山小,可、每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~

    ———————————————————————————


    展开全文
  • 如:预测明天的气温是多少度 CART是一棵二叉树 当CART是分类树时,与C4.5算法类似,只是采用 基尼系数 作为节点分裂的依据 CART在构造分类树的时候会选择基尼系数最小的属性作为属性的划分。 基尼系数:反应了样本的...
  • 决策树与随机森林(从入门到精通)

    万次阅读 多人点赞 2020-07-06 22:54:44
    现解释如下:   我们知道信息熵的定义式为:   那么基尼系数实际上就是用 1 − p i 1-p_{i} 1−pi​来代替了 − l o g ( p i ) -log(p_{i}) −log(pi​),画出二者图像:   因为概率是属于0到1之间,所以我们...
  • 分类树:基尼系数 最小的准则,在sklearn中可以选择划分的原则。 3.5 决策树的流程 收集数据:公开数据源或爬虫等方式。 准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化。 分析数据:可以使用任何...
  • 3.CART:以基尼系数为准则选择最优划分属性,可用于分类和回归 CART是一棵二叉树,采用二元切分法,每次把数据分成两份,分别进入左子树、右子树。并且每个非叶子节点都有两个孩子,所以CART的叶子节点比非叶子节点...
  • print('基尼系数得分: %.4f'%score) RF = RandomForestClassifier(criterion = 'entropy',random_state = 66) score = cross_val_score(RF,x,y,cv=10).mean() print('熵得分: %.4f'%score) 输出: 基尼系数得分: 0....
  • 机器学习基础知识点

    千次阅读 2021-10-24 14:38:12
    y i ) p\left(a_{j} \mid y_{i}\right) p(aj​∣yi​) 表示该类别下该特征出现的概率, p ( y i ) p\left(y_{i}\right) p(yi​) 表示全部类别中这个这个类别出现的概率。 就这么简单。特征为离散值时直接统计即可...
  • 其中 p(x)p(x)p(x) 代表随机事件 发生的概率,然后将概率取倒数 1p(x)\frac{1}{{p(x)}}p(x)1​,表示信息量和概率成反比关系,再取对数将信息量的值从区间 [1,+∞][1, + \infty ][1,+∞] 映射到 [0,+∞][0, + \...
  • 你不得不了解的机器学习知识

    千次阅读 多人点赞 2020-02-14 19:51:07
    CART 算法使用了基尼系数取代了信息熵模型。 5.K邻近 – k-nearest neighbors | KNN 通过搜索K个最相似的实例(邻居)的整个训练集并总结那些K个实例的输出变量,对新数据点进行预测。对于回归问题,这可能...
  • 基尼系数 在这一点上,我们应该尝试了解基尼系数。简而言之,Gini Impurity是随机选择的样本被节点中的样本分布标记错误的概率。例如,在顶部(根)节点中,有44.4%错误的可能性根据节点中样本标签的分布对随机...
  • 初识决策树

    2018-02-28 21:03:10
    而且决策树在生活中也所处可见,下面用一个图例表示某一天的活动。上面的图例就是一个比较简单的决策树模型。决策树模型是基于一系列的问题来进行决策的,在处理实际问题的时候会比上面树要大的多。一颗决策树通常...
  •  7.SQL语言允许使用通配符进行字符串匹配的操作,其中‘%’可以表示D  A.零个字符  B.1个字符  C.多个字符  D.以上都可以  8.关于正态分布,下列说法错误的是:C  A.正态分布具有集中性和对称性  B.正态分布的...
  • 机器学习----面试题汇总

    千次阅读 2018-05-22 19:25:03
    当桥长n米,最多装m颗的时候结果用公式怎么表示? 一个绳子烧完需要1个小时,假设所有绳子的材质都不一样,也不均匀,怎么取出1小时加 15分钟。 把1~9这9个填入九格宫里,使每一横、竖、斜相等。 有100个黑球...
  • (即bootstrap取样),并用未到的用例(样本)作预测,评估其误差。 4、对于每一个节点,随机选择 m 个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,计算其最佳的分裂方式。 5、每棵树...
  • 机器学习算法梳理(四):随机森林

    千次阅读 2019-01-22 14:36:49
    7) 节点划分最小不纯度min_impurity_split: 这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。一般不推荐改动默认值1e-7。 上面决策树...
  • (5)算法参数选定后,要用“训练集+验证集”重新训练最终模型 5、超参数优化 (1)超参数:层、每层神经元个、激活函数、学习率(以及动态调整算法)、正则化系数、mini-batch 大小 (2)优化方法:网格搜索、...
  • 3.2 梯度下降法改进 指数加权平均 在讲解一些常见的梯度下降改进算法之前,我们先来看一下指数加权平均(Exponentially weighted averages):指数加权平均是对趋势的一种刻画,计算公式如下: 在上式中,vt是t...
  • 基尼指数在这里为什么Gini(D)系数越小,样本纯度越高?五.什么是剪枝?六.为什么需要剪枝叶?七. 如何去剪枝八. 后剪枝是根据什么来剪枝的?九,测试结果十. 代码 一.什么是决策树? 决策树是一种基本的分类与回归...
  • 1.信息论基础(熵 联合熵 条件熵 信息增益 基尼不纯度) 2.决策树的不同分类算法(ID3算法、C4.5、CART分类树)的原理及应用场景 3.回归树原理 4.决策树防止过拟合手段 5.模型评估 6.sklearn参数详解,Python绘制...
  • 可生成一个Proximities=(pij)矩阵,用于度量样本之间的相似性: pij=aij/N, aij表示样本i和j出现在随机森林中同一个叶子结点的次数,N随机森林中树的颗 e. 在创建随机森林的时候,对generlization error使用...
  • 机器学习-决策树算法

    千次阅读 2018-08-10 10:45:46
    基尼系数相比信息熵,计算代价更小,相当于一阶泰勒展开的近似。首先不用算上一步的信息熵,其次不用计算log了。   原始基尼系数: 将基尼系数的P乘以进公式,就可以展开如下计算公式: 2.3.3 ...
  • (信息熵越小 表示结果越确定) 信息熵的公式如下: , i=1,2,...,n 表示所有可能的事件发生的概率。表示可能事件发生后包含的信息量(越小概率事件发生所包含的信息量越大。例如:中国乒乓球队获胜比美国乒乓球队...
  • 决策树与随机森林

    2017-12-20 22:04:15
    决策树有三种,分为ID3,C4.5和CART算法,分别基于信息增益,信息增益比和基尼系数来作为划分选择特征的依据。 1.2.1 ID3算法 ID3算法的核心是在决策树各个节点上使用信息增益准则选择特征,递归地构建决策...
  • 数据挖掘常用模型

    千次阅读 2019-07-02 23:02:11
    基尼指数Gini(D)表示集合D的不确定性,基尼指数越大,样本集合的不确定性也就越大,这一点与熵相似。 2. 决策树ID3算法的思路  上面提到 ID3算法就是用信息增益大小来判断当前节点应该用什么特征来构建决策...
  • 算法梳理之决策树

    2018-12-23 19:25:27
    1 信息论基础 决策树我们都知道它的样子,就像树一样一级一级的细分,正如西瓜树上的图示 ...熵(entropy)是表示随机变量不确定性的度量,熵越大,随机变量的不确定性越大。 熵定义为 条件熵:条件熵H(Y|X...
  • 3.构建决策树的时候分裂节点的选择依据最小基尼系数 4.在训练时,对于预选变量个和随机森林中树的个数这两个参数的调优很重要。 随机森林的优点: 1.两个随机性的引入,使得随机森林抗噪声能力强,方差小泛化...

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 324
精华内容 129
关键字:

数抽表示的基尼系数。

友情链接: 成熟版.zip