首页 > 代码库 > 机器学习之决策树学习

机器学习之决策树学习

技术分享
决策树是一个函数,以属性值向量作为输入,返回一个“决策”。
如上图,我们输入一系列属性值(天气状况,湿度,有无风)后会得到一个要不要出去玩的一个决策。

从样例构建决策树

对于原始样例集,我们选取一个最好的属性将其分裂,这样我们会产生多个样例子集,同时我们会把该属性从属性集去掉,并且继续对各个样例子集进行分裂操作,直到样例集中的所有样例具有相同的分类。显然,这是一个递归分裂的问题,在这个分裂过程中我们会遇到以下四种情况:

  1. 样例集合为空集
    说明测试样例中并没有这样的属性组合,因此返回其父节点得票最多的分类。
  2. 属性集合为空集
    属性用完了,样例集合仍然有多种分类,说明拥有相同属性组合的样例有着不同的分类,这种情况的发生是因为数据存在了噪声,此时我们返回样例集合得票最多的分类。
  3. 样例集合分类一致
    返回一个“决策”。
  4. 样例集合分类不一致
    选择一个最好的属性继续分裂。

对于这四种情况,我们采取不同的举措,从而最终构建出一棵决策树。

确定最优属性

在分裂时,我们希望能找到一个最优属性,那么到底什么样的属性是最优的呢?直观上看,我们希望能找到这样一个属性,它可以将混乱的集合分裂成不那么混乱的子集。
我们首先定义来度量集合的混乱程度:

H(V) = -ΣP(Vk)log2P(Vk)
P(Vk) = 出现Vk的概率,因此∈(0, 1)

我们研究y = -P(Vk)log2P(Vk)的单调性会发现,P(Vk)→0时,y→0; P(Vk)→1, y→0;
因此当集合中的所有分类个数一致时(集合最混乱),熵最大;相反,当集合中只有一个分类的时候,熵最小。
现在假设A属性将样例集合分为E1,E2...Ed,其中Ek有nk个样例。
对各个子集的熵进行加权求平均后获得子集的剩余期望熵:

Remainder(A) = Σnk/nHk(V)

定义信息增益来描述分裂前后熵减少了多少:

Gain(A) = HA(V) - Remainder(A)

因此使得Gain(A)最大的属性值A为最优属性。

伪代码

function DecisionTree(examples, attributes) returns a tree

    if examples is empty
        return parent‘s majority
    if attributes is empty
        return the majority of examples
    if all examples have the same classification
        return the classification
    A = the best attribute
    tree = a new tree
    for each value vk of A do
        newexamples = {e: e.A=vk}
        subtree = DecisionTree(newexamples, attributes-A)
        add subtree to tree
    return tree

随机森林

随机森林是决策树的一种优化方案,其主要思想是有放回的随机抽取多个与原始样例集大小一样的集合,然后根据这些样例集合构建多棵树,形成一个随机森林。在做决策的时候我们选取票数最高的决策作为最终的结果。

function RandomForest(examples, attributes) returns a decision
    
    forest = a empty set
    for i = 1 to k do
        exs = RandomSelectFrom(examples)
        tree = DecisionTree(exs, attributes)
        forest.append(tree)

过度拟合

?当我们把噪声作为了分类属性,那么可能会出现过度拟合的问题,表现在样例集上泛化的非常好,但在实际测试样例中却表现平平。对于这种问题,我们可以对决策树进行χ2剪枝。考查只有叶节点作为后代的测试节点,对其进行统计重要性测试。若发现该节点不相关,则将其剪枝。
?那么为什么我们不在构造时就进行重要性测试,从而提前避免分裂呢?原因是可能不存在好的属性,却存在好的属性组合。例如XOR:

a b y
0 0 1
0 1 0
1 0 0
1 1 1

不管我们选择属性a还是b进行分裂,都会发现分裂后的集合仍有一半是1,一半是0,如果这时进行剪枝的话,我们就没办法构建一棵有效的决策树。反之,如果我们先用a进行分裂,然后再用b进行分裂,我们会发现样例被很好的归类。因此单个属性a,b都不能很好的对样例进行分类,但是组合a、b却能对对样例进行分类,后剪枝正是为了解决这样一个问题。

机器学习之决策树学习