利用ID3算法来判断某天是否适合打网球。
(1)类别属性信息熵的计算由于未分区前,训练数据集中共有14个实例,
其中有9个实例属于yes类(适合打网球的),5个实例属于no类(不适合打网球),
因此分区前类别属性的熵为:
(2)非类别属性信息熵的计算,若先选择Outlook属性。
(3)Outlook属性的信息增益为:
(4)同理计算出其他3个非类别属性的信息增益,取最大的那个属性作为分裂节点,此例中最大的是Outlook,进而得到如下图所示:
(5)上图中,针对sunny中的子训练数据集分支,有两个类别,该分支中有3个实例属于no类,有2个实例属于yes类,求类别属性新的信息熵
(6)再分别求3个非类别属性的信息熵,同时求出各属性的信息增益,选出信息增益最大的属性Humidity,得:
(7)同理可得:
(8)cool对应的数据子集都是no,所以直接写no,无需分裂。mild对应的数据子集,Humidity和windy的信息增益是相同的,因为在该分组中,yes元组的比例比no元组的大,所以直接写yes,最终得到的决策树图如图所示:
但是,使用信息增益的话其实是有一个缺点,那就是它偏向于具有大量值的属性。什么意思呢?就是说在训练集中,某个属性所取的不同值的个数越多,那么越有可能拿它来作为分裂属性。例如一个训练集中有10个元组,对于某一个属相A,它分别取1-10这十个数,如果对A进行分裂将会分成10个类,那么对于每一个类Info(D_j)=0,从而式(2)为0,该属性划分所得到的信息增益(3)最大,但是很显然,这种划分没有意义。
正是基于此,ID3后面的C4.5采用了信息增益率这样一个概念。信息增益率使用“分裂信息”值将信息增益规范化。分类信息类似于Info(D),定义如下:
(4)
这个值表示通过将训练数据集D划分成对应于属性A测试的v个输出的v个划分产生的信息。信息增益率定义:
(5)
选择具有最大增益率的属性作为分裂属性。
(3)Gini指标
Gini指标在CART中使用。Gini指标度量数据划分或训练元组集D的不纯度,定义为:
(6)
这里通过下面的数据集(均为离散值,对于连续值,下面有详细介绍)看下信息增益率节点选择:
上面的训练集有4个属性,即属性集合A={OUTLOOK, TEMPERATURE, HUMIDITY, WINDY};而类标签有2个,即类标签集合C={Yes, No},分别表示适合户外运动和不适合户外运动,其实是一个二分类问题。
数据集D包含14个训练样本,其中属于类别“Yes”的有9个,属于类别“No”的有5个,则计算其信息熵:即公式(1)的值
1 |
Info(D) = -9/14 * log2(9/14) - 5/14 * log2(5/14) = 0.940 |
下面对属性集中每个属性分别计算信息熵,如下所示:
1 |
Info(OUTLOOK) = 5/14 * [- 2/5 * log2(2/5) – 3/5 * log2(3/5)] + 4/14 * [ - 4/4 * log2(4/4) - 0/4 * log2(0/4)] + 5/14 * [ - 3/5 * log2(3/5) – 2/5 * log2(2/5)] = 0.694 |
2 |
Info(TEMPERATURE) = 4/14 * [- 2/4 * log2(2/4) – 2/4 * log2(2/4)] + 6/14 * [ - 4/6 * log2(4/6) - 2/6 * log2(2/6)] + 4/14 * [ - 3/4 * log2(3/4) – 1/4 * log2(1/4)] = 0.911 |
3 |
Info(HUMIDITY) = 7/14 * [- 3/7 * log2(3/7) – 4/7 * log2(4/7)] + 7/14 * [ - 6/7 * log2(6/7) - 1/7 * log2(1/7)] = 0.789 |
4 |
Info(WINDY) = 6/14 * [- 3/6 * log2(3/6) – 3/6 * log2(3/6)] + 8/14 * [ - 6/8 * log2(6/8) - 2/8 * log2(2/8)] = 0.892 |
根据上面的数据,我们可以计算选择第一个根结点所依赖的信息增益值,计算如下所示:
1 |
Gain(OUTLOOK) = Info(D) - Info(OUTLOOK) = 0.940 - 0.694 = 0.246 |
2 |
Gain(TEMPERATURE) = Info(D) - Info(TEMPERATURE) = 0.940 - 0.911 = 0.029 |
3 |
Gain(HUMIDITY) = Info(D) - Info(HUMIDITY) = 0.940 - 0.789 = 0.151 |
4 |
Gain(WINDY) = Info(D) - Info(WINDY) = 0.940 - 0.892 = 0.048 |
接下来,我们计算分裂信息度量SplitInfo,此处记为H(V):
- OUTLOOK属性
属性OUTLOOK有3个取值,其中Sunny有5个样本、Rainy有5个样本、Overcast有4个样本,则
1 |
H(OUTLOOK) = - 5/14 * log2(5/14) - 5/14 * log2(5/14) - 4/14 * log2(4/14) = 1.577406282852345 |
- TEMPERATURE属性
属性TEMPERATURE有3个取值,其中Hot有4个样本、Mild有6个样本、Cool有4个样本,则
1 |
H(TEMPERATURE) = - 4/14 * log2(4/14) - 6/14 * log2(6/14) - 4/14 * log2(4/14) = 1.5566567074628228 |
- HUMIDITY属性
属性HUMIDITY有2个取值,其中Normal有7个样本、High有7个样本,则
1 |
H(HUMIDITY) = - 7/14 * log2(7/14) - 7/14 * log2(7/14) = 1.0 |
- WINDY属性
属性WINDY有2个取值,其中True有6个样本、False有8个样本,则
1 |
H(WINDY) = - 6/14 * log2(6/14) - 8/14 * log2(8/14) = 0.9852281360342516 |
根据上面计算结果,我们可以计算信息增益率,如下所示:
1 |
IGR(OUTLOOK) = Info(OUTLOOK) / H(OUTLOOK) = 0.246/1.577406282852345 = 0.15595221261270145 |
2 |
IGR(TEMPERATURE) = Info(TEMPERATURE) / H(TEMPERATURE) = 0.029 / 1.5566567074628228 = 0.018629669509642094 |
3 |
IGR(HUMIDITY) = Info(HUMIDITY) / H(HUMIDITY) = 0.151/1.0 = 0.151 |
4 |
IGR(WINDY) = Info(WINDY) / H(WINDY) = 0.048/0.9852281360342516 = 0.048719680492692784 |
根据计算得到的信息增益率进行选择属性集中的属性作为决策树结点,对该结点进行分裂。从上面的信息增益率IGR可知OUTLOOK的信息增益率最大,所以我们选其作为第一个节点。
4. 算法特性
4.1 决策树的剪枝
在决策树的创建时,由于数据中的噪声和离群点,许多分枝反映的是训练数据中的异常。剪枝方法是用来处理这种过分拟合数据的问题。通常剪枝方法都是使用统计度量,剪去最不可靠的分枝。
剪枝一般分两种方法:先剪枝和后剪枝。
先剪枝方法中通过提前停止树的构造(比如决定在某个节点不再分裂或划分训练元组的子集)而对树剪枝。一旦停止,这个节点就变成树叶,该树叶可能取它持有的子集最频繁的类作为自己的类。先剪枝有很多方法,比如(1)当决策树达到一定的高度就停止决策树的生长;(2)到达此节点的实例具有相同的特征向量,而不必一定属于同一类,也可以停止生长(3)到达此节点的实例个数小于某个阈值的时候也可以停止树的生长,不足之处是不能处理那些数据量比较小的特殊情况(4)计算每次扩展对系统性能的增益,如果小于某个阈值就可以让它停止生长。先剪枝有个缺点就是视野效果问题,也就是说在相同的标准下,也许当前扩展不能满足要求,但更进一步扩展又能满足要求。这样会过早停止决策树的生长。
另一种更常用的方法是后剪枝,它由完全成长的树剪去子树而形成。通过删除节点的分枝并用树叶来替换它。树叶一般用子树中最频繁的类别来标记。后剪枝一般有两种方法:
第一种方法,也是最简单的方法,称之为基于误判的剪枝。这个思路很直接,完全的决策树不是过度拟合么,我再搞一个测试数据集来纠正它。对于完全决策树中的每一个非叶子节点的子树,我们尝试着把它替换成一个叶子节点,该叶子节点的类别我们用子树所覆盖训练样本中存在最多的那个类来代替,这样就产生了一个简化决策树,然后比较这两个决策树在测试数据集中的表现,如果简化决策树在测试数据集中的错误比较少,并且该子树里面没有包含另外一个具有类似特性的子树(所谓类似的特性,指的就是把子树替换成叶子节点后,其测试数据集误判率降低的特性),那么该子树就可以替换成叶子节点。该算法以bottom-up的方式遍历所有的子树,直至没有任何子树可以替换使得测试数据集的表现得以改进时,算法就可以终止。
第一种方法很直接,但是需要一个额外的测试数据集,能不能不要这个额外的数据集呢?为了解决这个问题,于是就提出了悲观剪枝。悲观剪枝就是递归得估算每个内部节点所覆盖样本节点的误判率。剪枝后该内部节点会变成一个叶子节点,该叶子节点的类别为原内部节点的最优叶子节点所决定。然后比较剪枝前后该节点的错误率来决定是否进行剪枝。该方法和前面提到的第一种方法思路是一致的,不同之处在于如何估计剪枝前分类树内部节点的错误率。
把一颗子树(具有多个叶子节点)的分类用一个叶子节点来替代的话,在训练集上的误判率肯定是上升的,但是在新数据上不一定。于是我们需要把子树的误判计算加上一个经验性的惩罚因子。对于一颗叶子节点,它覆盖了N_i个样本,其中有E个错误,那么该叶子节点的错误率为(E+0.5)/N_i。这个0.5(详细请参考连续性校正)就是惩罚因子,那么一颗子树,它有L个叶子节点,那么该子树的误判率估计为。这样的话,我们可以看到一颗子树虽然具有多个子节点,但由于加上了惩罚因子,所以子树的误判率计算未必占到便宜。剪枝后内部节点变成了叶子节点,其误判个数J也需要加上一个惩罚因子,变成J+0.5。那么子树是否可以被剪枝就取决于剪枝后的错误J+0.5在的标准误差内。对于样本的误差率e,我们可以根据经验把它估计成各种各样的分布模型,比如是二项式分布,或者正态分布。
那么一棵树对于一个数据来说,错误分类一个样本值为1,正确分类一个样本值为0,该树错误分类的概率(误判率)为e_1(可以通过统计出来),那么树的误判次数就是二项分布,我们可以估计出该树的误判次数均值和标准差:
其中,
把子树替换成叶子节点后,该叶子的误判次数也是一个伯努利分布,其中N是到达该叶节点的数据个数,其概率误判率e_2为(J+0.5)/N,因此叶子节点的误判次数均值为
使用训练数据,子树总是比替换为一个叶节点后产生的误差小,但是使用校正后有误差计算方法却并非如此,当子树的误判个数大过对应叶节点的误判个数一个标准差之后,就决定剪枝:
这个条件就是剪枝的标准。
通俗点讲,就是看剪枝后的错误率会不会变得很大(比剪枝前的错误率加上其标准差还大),如果剪枝后的错误率变得很高,则不剪枝,否则就剪枝。下面通过一个具体的实例来看一下到底是如何剪枝的。
例如:这是一个子决策树,其中t1,t2,t3,t4,t5为非叶子节点,t6,t7,t8,t9,t10,t11为叶子节点,这里我们可以看出来N=样本总和80,其中A类55个样本,B类25个样本。
节点 |
E(subtree) |
sd(subtree) |
E(subtree)+ sd(subtree) |
E(leaf) |
是否剪枝 |
t1 |
8 |
2.68 |
10.68 |
25.5 |
否 |
t2 |
5 |
2.14 |
7.14 |
10.5 |
否 |
t3 |
3 |
1.60 |
4.60 |
5.5 |
否 |
t4 |
4 |
1.92 |
5.92 |
4.5 |
是 |
t5 |
1 |
0.95 |
1.95 |
4.5 |
否 |
此时,只有节点t4满足剪枝标准,我们就可以把节点t4剪掉,即直接把t4换成叶子节点A。
但是并不一定非要大一个标准差,该方法被扩展成基于理想置信区间(confidence intervals, CI)的剪枝方法,该方法将叶节点的错误率e建模成为服从二项分布的随机变量,对于一个置信区间阈值CI,存在一个上界e_max,使得e<e_max以1-CI的概率成立(对于C4.5算法中默认的CI值为0.25),若p(e<e_max)>1-CI,则剪枝。更近一步,我们可以用正态分布来逼近e(只要N足够大),基于这些约束条件,C4.5算法的期望误差的上界e_max(一般用Wilson score interval)为:
式中z的选择是基于理想置信区间,假设z是一个拥有零均值和单位方差的正态随机变量,也就是N(0,1).为什么选取Wilson score interval作为上界,主要因为该上界在少样本或者存在极端概率情况下的数据集都能有一些很好的性质。详见下面链接:
关于Wilson score interval详见:http://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Normal_approximation_interval
4.2 对于连续数据的处理
离散化处理:将连续型的属性变量进行离散化处理,形成决策树的训练集,分三步:
1. 把需要处理的样本(对应根节点)或样本子集(对应子树)按照连续变量的大小从小到大进行排序
2. 假设该属性对应的不同的属性值一共有N个,那么总共有N-1个可能的候选分割阈值点,每个候选的分割阈值点的值为上述排序后的属性值中两两前后连续元素的中点
3. 用信息增益率选择最佳划分
4.3 对于缺失值的处理
缺失值:在某些情况下,可供使用的数据可能缺少某些属性的值。例如(X, y)是样本集S中的一个训练实例,X=(F1_v,F2_v, …Fn_v)。但是其属性Fi的值Fi_v未知。
处理策略:
1. 处理缺少属性值的一种策略是赋给它结点t所对应的训练实例中该属性的最常见值
2. 另外一种更复杂的策略是为Fi的每个可能值赋予一个概率。例如,给定一个布尔属性Fi,如果结点t包含6个已知Fi_v=1和4个Fi_v=0的实例,那么Fi_v=1的概率是0.6,而Fi_v=0的概率是0.4。于是,实例x的60%被分配到Fi_v=1的分支,40%被分配到另一个分支。这些片断样例(fractional examples)的目的是计算信息增益,另外,如果有第二个缺少值的属性必须被测试,这些样例可以在后继的树分支中被进一步细分。(C4.5中使用)
3. 简单处理策略就是丢弃这些样本
4.4 C4.5算法优缺点
优点:产生的分类规则易于理解且准确率较高。
缺点:在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。
作者:蓝鲸
算法决策树是一种通过对历史数据进行测算实现对新数据进行分类和预测的算法。简单来说决策树算法就是通过对已有明确结果的历史数据进行分析,寻找数据中的特征。并以此为依据对新产生的数据结果进行预测。
决策树由3个主要部分组成,分别为决策节点,分支,和叶子节点。其中决策树最顶部的决策节点是根决策节点。每一个分支都有一个新的决策节点。决策节点下面是叶子节点。每个决策节点表示一个待分类的数据类别或属性,每个叶子节点表示一种结果。整个决策的过程从根决策节点开始,从上到下。根据数据的分类在每个决策节点给出不同的结果。
构造决策树是一个复杂的工作。下面我们将介绍决策树中的ID3算法和“信息熵”的概念。并手工创建一个简单的决策树,用以说明整个构建的过程和思路。
ID3算法
构造决策树的方法有很多种,ID3是其中的一种算法。ID3算法最早是由罗斯昆(J. Ross Quinlan)1975年在悉尼大学提出的一种分类预测算法,核心是“信息熵”。ID3算法认为“互信息”高的属性是好属性,通过计算历史数据中每个类别或属性的“信息熵”获得“互信息”,并选择“互信息”最高的类别或属性作为决策树中的决策节点,将类别或属性的值做为分支继续进行分裂。不断重复这个过程,直到生成一棵完整的决策树。
信息熵的含义及分类
信息熵是信息论中的一个重要的指标,是由香农在1948年提出的。香农借用了热力学中熵的概念来描述信息的不确定性。因此信息学中的熵和热力学的熵是有联系的。根据Charles H. Bennett对Maxwell’s Demon的重新解释,对信息的销毁是一个不可逆过程,所以销毁信息是符合热力学第二定律的。而产生信息,则是为系统引入负(热力学)熵的过程。 所以信息熵的符号与热力学熵应该是相反的 。
简单的说信息熵是衡量信息的指标,更确切的说是衡量信息的不确定性或混乱程度的指标。信息的不确定性越大,熵越大。决定信息的不确定性或者说复杂程度主要因素是概率。决策树中使用的与熵有关的概念有三个:信息熵,条件熵和互信息。下面分别来介绍这三个概念的含义和计算方法。
信息熵是用来衡量一元模型中信息不确定性的指标。信息的不确定性越大,熵的值也就越大。而影响熵值的主要因素是概率。这里所说的一元模型就是指单一事件,而不确定性是一个事件出现不同结果的可能性。例如抛硬币,可能出现的结果有两个,分别是正面和反面。而每次抛硬币的结果是一个非常不确定的信息。因为根据我们的经验或者历史数据来看,一个均匀的硬币出现正面和反面的概率相等,都是50%。因此很难判断下一次出现的是正面还是反面。这时抛硬币这个事件的熵值也很高。而如果历史数据告诉我们这枚硬币在过去的100次试验中99次都是正面,也就是说这枚硬币的质量不均匀,出现正面结果的概率很高。那么我们就很容易判断下一次的结果了。这时的熵值很低,只有0.08。
我们把抛硬币这个事件看做一个随机变量S,它可能的取值有2种,分别是正面x1和反面x2。每一种取值的概率分别为P1和P2。 我们要获得随机变量S的取值结果至少要进行1次试验,试验次数与随机变量S可能的取值数量(2种)的对数函数Log有联系。Log2=1(以2为底)。因此熵的计算公式是:
在抛硬币的例子中,我们借助一元模型自身的概率,也就是前100次的历史数据来消除了判断结果的不确定性。而对于很多现实生活中的问题,则无法仅仅通过自身概率来判断。例如:对于天气情况,我们无法像抛硬币一样通过晴天,雨天和雾霾在历史数据中出现的概率来判断明天的天气,因为天气的种类很多,并且影响天气的因素也有很多。同理,对于网站的用户我们也无法通过他们的历史购买频率来判断这个用户在下一次访问时是否会完成购买。因为用户是的购买行为存在着不确定性,要消除这些不确定性需要更多的信息。例如用户历史行为中的广告创意,促销活动,商品价格,配送时间等信息。因此这里我们不能只借助一元模型来进行判断和预测了,需要获得更多的信息并通过二元模型或更高阶的模型了解用户的购买行为与其他因素间的关系来消除不确定性。衡量这种关系的指标叫做条件熵。
条件熵是通过获得更多的信息来消除一元模型中的不确定性。也就是通过二元或多元模型来降低一元模型的熵。我们知道的信息越多,信息的不确定性越小。例如,只使用一元模型时我们无法根据用户历史数据中的购买频率来判断这个用户本次是否也会购买。因为不确定性太大。在加入了促销活动,商品价格等信息后,在二元模型中我们可以发现用户购买与促销活动,或者商品价格变化之间的联系。并通过购买与促销活动一起出现的概率,和不同促销活动时购买出现的概率来降低不确定性。
计算条件熵时使用到了两种概率,分别是购买与促销活动的联合概率P(c),和不同促销活动出现时购买也出现的条件概率E(c)。以下是条件熵E(T,X)的计算公式。条件熵的值越低说明二元模型的不确定性越小。
互信息是用来衡量信息之间相关性的指标。当两个信息完全相关时,互信息为1,不相关时为0。在前面的例子中用户购买与促销活动这两个信息间的相关性究竟有多高,我们可以通过互信息这个指标来度量。具体的计算方法就熵与条件熵之间的差。用户购买的熵E(T)减去促销活动出现时用户购买的熵E(T,X)。以下为计算公式:
熵,条件熵和互信息是构建决策树的三个关键的指标。下面我们将通过一个 维基百科 中的实例说明创建决策树的过程。
构建决策树实例
这是一家高尔夫球俱乐部的历史数据,里面记录了不同天气状况用户来打高尔夫球的历史记录。我们要做的是通过构建决策树来预测用户是否会来打高尔夫球。这里用户是否来打球是一个一元模型,具有不确定性,熵值很高。我们无法仅通过Yes和No的频率来判断用户明天是否会来。因此,需要借助天气的信息来减少不确定性。下面分别记录到了4种天气情况,我们通过计算条件熵和互信息来开始构建决策树的第一步:构建根决策点。
构建根决策节点
构建根决策点的方法就是寻找4种天气情况中与打高尔夫球相关性最高的一个。首先我们来看Play Golf这个一元模型的熵,来看看这件事的不确定性有多高.
一元模型的熵
在一元模型中,仅通过历史数据的概率来看预测Play Golf是一件非常不确定的事情,在14条历史数据中,打球的概率为64%,不打球的概率为36%。熵值达到了0.940。这与之前抛硬币的例子很像。在无法改变历史数据的概率时,我们需要借助更多的信息来降低不确定性。也就是计算条件熵。
二元模型条件熵
计算二元模型的条件熵需要知道Play Golf与4种天气情况一起出现的联合概率,以及在不同天气情况下Play Golf出现的条件概率。下面我们分别来计算这两类概率。
联合概率
以上是经过分别计算后4种天气情况与Play Golf同时出现的联合概率值。
条件概率
同时我们也分别计算出了4种天气情况下,不同取值时Play Golf的条件概率值。并通过联合概率与条件概率求得4种天气情况与Play Golf间的条件熵。
互信息
在已知Play Golf的一元模型熵和不同天气条件下的二元模型熵后。我们就可以通过互信息来度量哪种天气与Play Golf的相关性最高了。
通过互信息的值可以发现,4种天气中Outlook的值最大。说明Outlook与Play Golf的相关性最高。因此我们选择Outlook作为决策树的根节点来构建决策树。
构建根节点
在整个决策树中,Outlook因为与Play Golf的相关性最高,所以作为决策树的根节点。以Outlook作为根节点后,决策树出现了三个分支,分别是Outlook的三个不同的取值Sunny,Overcast和Rainy。其中Overcast所对应的Play Golf都是Yes,因此这个分支的叶子节点为Yes。(后面构建分支决策节点时会看到)另外两个分支我们将使用和前面一样的方法,通过计算熵,条件熵和互信息来挑选下一个分支的决策节点。
构建分支决策节点
下面我们继续构建Sunny,Overcast和Rainy这三个分支的决策节点,首先来看下Overcast节点,这个节点只有一种结果,因此无需在继续分裂。
构建分支节点
Outlook 节点Overcast分支
在Outlook根节点下的Overcast分支中,Play Golf只有一种结果Yes,因此Overcast分支停止分裂。叶子节点的值为Yes。
Outlook 节点Sunny分支
在Outlook根节点下的Sunny分支中,单独形成了另一个表。此时由于Outlook以及作为决策树的根节点了,因此所需考虑的天气情况为3种,我们继续对这个表确定决策节点。从3种天气情况中找出Sunny分支下的决策节点。方法及步骤和前面一致,计算熵,条件熵和互信息,并以互信息最大的作为Sunny分支的决策节点进行分裂。
首先计算Play Golf的一元模型熵,可以看到在Sunny这一分支中根据Play Golf自身的历史数据 No和Yes的概率分布为40%和60%,熵值为0.971。具有极高的不确定性。因此我们继续计算条件熵。
以下是三种天气情况分别与Play Golf的联合概率和条件概率计算结果。这里可以看到Wind有些与众不同,Wind为FALSE时都为Play Golf的值都为Yes。
通过计算获得三种天气情况与Play Golf的条件概率,其中Wind的值为0。
互信息
计算三种天气情况与Play Golf的互信息值,也就是相关性。值越大相关性越高。三种天气中Wind的互信息值最高,为0.971。说明Sunny分支下Wind和Play Golf的相关性最高。因此选择Wind作为Sunny分支的决策节点。
构建分支决策节点(Windy)
在Outlook根节点的Sunny分支下,经过计算互信息的值Wind与Play Golf相关性最高,因此Wind作为Sunny的决策节点。Wind有两个分支,分别为FALSE和TRUE。当Wind为FALSE时,Play Golf的结果为Yes。Wind为TRUE时结果为No。
Outlook 节点Rainy分支
Outlook根节点还有一个分支是Rainy。以下是Outlook下Rainy的分支数据表。我们从这个表中挑选出Rainy分支下的决策节点。由于Outlook以及作为决策树的根节点,Wind成为了Sunny分支下的决策节点,因此我们需要考虑的天气情况就只剩下两种Temp和Humidity。
首先计算在Rainy分支下Play Golf的熵。从历史数据看No和Yes的概率为60%和40%,熵为0.971,一元模型依靠自身概率的不确定性较高。加入两个天气情况的信息来计算条件熵。
通过计算两种天气情况与Play Golf的联合概率和条件概率发现,情况与Sunny分支类似。Humidity应该与Play Golf的相关性较高。
通过计算获得Temp和Humidity与Play Golf的条件熵,其中Humidity与Play Golf的条件熵为0。
互信息
Play Golf熵减去两种天气与Play Golf的条件熵获得互信息的值。Humidity值最大,说明相关性最高。因此Humidity被选为Rainy分支的决策节点。
构建分支决策节点(Humidity)
在Outlook的Rainy分支下,Humidity作为决策节点有两个分支,分别为High和Normal。所有High分支都对应Play Golf的No,所有Normal分支都对应了Play Golf的Yes。因此停止继续分裂。
到此为止我们通过Play Golf与天气情况的历史数据构建了决策树。下面我们在从较高的维度来看下整个决策树与历史数据表间的关系。
数据表与决策树
通过将决策树中每个决策点还原为原始数据表可以发现,每一个决策点都对应了一张数据表。从根决策节点开始,我们通过计算熵寻找与Play Golf最相关的天气信息,来建立决策点及分支,并反复迭代这一过程。直到最终构建完整的决策树。
使用决策树进行预测
文章开始的时候我们说过,决策树是用来进行分类和预测的。具体过程如下。当我们构建好决策树后,当有新的信息发送时,我们利用已有的决策树逻辑对新的信息结构进行判断。当信息的内容与决策树一致时,就进入下一分支进行判断,并通过叶子节点获得分类的结果。例如,当新的一天开始时,我们就可以通过4个天气特征来判断用户是否会来打高尔夫球。以下是具体预测流程的示意图,首先寻找新信息中的根决策节点Outlook,根据Outlook的取值进入到Sunny分支,在Sunny分支中继续判断下一决策点Windy的取值,新的信息中Windy的取值为FALSE,根据决策树中的逻辑返回Yes。因此在新信息中通过对天气情况的判断预测用户会来打高尔夫球。
通过随机森林提高准确率
决策树是建立在已知的历史数据及概率上的,一课决策树的预测可能会不太准确,提高准确率最好的方法是构建随机森林(Random Forest)。所谓随机森林就是通过随机抽样的方式从历史数据表中生成多张抽样的历史表,对每个抽样的历史表生成一棵决策树。由于每次生成抽样表后数据都会放回到总表中,因此每一棵决策树之间都是独立的没有关联。将多颗决策树组成一个随机森林。当有一条新的数据产生时,让森林里的每一颗决策树分别进行判断,以投票最多的结果作为最终的判断结果。以此来提高正确的概率。