决策树理解与python代码

决策树

什么是信息熵?

假设你面前有两个盒子,盒子 A 和盒子 B。

盒子 A 里有 10 个完全相同的红色球,每次从盒子 A 中拿球,你肯定能拿到红球,结果非常确定。这种情况下,盒子 A 的不确定性就很低,它的信息熵就很小,可以认为几乎为零。
不同颜色的球

盒子 B 里有 5 个红球和 5 个蓝球,每次从盒子 B 中拿球,你不确定会拿到红球还是蓝球,结果有一定的不确定性。这种情况下,盒子 B 的不确定性比盒子 A 高,它的信息熵就比盒子 A 大。

信息熵就是用来衡量一个系统的不确定性或者混乱程度的指标。系统越不确定、越混乱,信息熵就越大;系统越确定、越有序,信息熵就越小。

数学推导

信息熵

Info ⁡ ( D ) = − ∑ k = 1 n p k log ⁡ 2 p k \operatorname{Info}(D)=-\sum_{k=1}^{\mathcal{n}}p_k\log_2p_k Info(D)=k=1npklog2pk

信息增益量

G a i n ( A ) = I n f o ( D ) − I n f o A ( D ) Gain\left(A\right)=Info\left(D\right)-Info_A\left(D\right) Gain(A)=Info(D)InfoA(D)
公式中, G a i n ( A ) Gain(A) Gain(A)代表以A特征来进行划分时的信息增益量; I n f o ( D ) Info(D) Info(D)是集合 D D D的信息熵; I n f o A ( D ) Info_A(D) InfoA(D)是按照A特征划分之后,各部分信息熵的加权和。

信息增益率

G a i n R a t i o ( A ) = G a i n ( A ) S p l i t I n f o ( A ) GainRatio\left(A\right)=\frac{Gain\left(A\right)}{SplitInfo\left(A\right)} GainRatio(A)=SplitInfo(A)Gain(A)
S p l i t I n f o ( A ) = − ∑ j = 1 m D j D × log ⁡ 2 D j D SplitInfo\left(A\right)=-\sum_{j=1}^{m}\frac{D_{j}}{D}\times\log_{2}\frac{D_{j}}{D} SplitInfo(A)=j=1mDDj×log2DDj
其中 S p l i t I n f o ( A ) SplitInfo(A) SplitInfo(A)是分类信息值, m m m是属性 A A A的类别的个数。

GINI指数

采用相同的符号,数据集 D D D的纯度可用基尼值来度量:
G i n i ( D ) = ∑ k = 1 ∣ Y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ Y ∣ p k 2   . \begin{aligned}\mathrm{Gini}(D)=&\sum_{k=1}^{|\mathcal{Y}|}\sum_{k^{\prime}\neq k}p_{k}p_{k^{\prime}}\\=&1-\sum_{k=1}^{|\mathcal{Y}|}p_{k}^{2}\:.\end{aligned} Gini(D)==k=1Yk=kpkpk1k=1Ypk2.
G i n i _ i n d e x ( D , a ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ . G i n i ( D v )   . \mathrm{Gini\_index}(D,a)=\sum_{v=1}^V\frac{|D^v|}{|D|_.}\mathrm{Gini}(D^v)\:. Gini_index(D,a)=v=1VD.DvGini(Dv).
于是,我们在候选属性集合 A A A中,选择那个使得划分后基尼指数最小的属性作为最优划分属性,即 a ∗ = arg ⁡ min ⁡ G i n _ i n d e x ( D , a ) . a_*=\arg\min Gin\_index( D, a) . a=argminGin_index(D,a).

ID3决策树python代码实现

构造一个是否去打网球的数据集:数据集中有四个特征属性和一个决策属性:

  • 第一个特征属性是“天气状况”,有三种可能的值:Sunny(晴天)、Overcast(阴天)、Rain(雨天)。
  • 第二个特征属性是“温度”,有三种可能的值:Hot(炎热)、Mild(温和)、Cool(凉爽)。
  • 第三个特征属性是“湿度”,有两种可能的值:High(高)、Normal(正常)。
  • 第四个特征属性是“风力”,有两种可能的值:Weak(弱)、Strong(强)。
  • 决策属性是“是否进行活动”,用“Yes”或“No”表示。

下面是实现代码:

import math
import pandas as pd

def entropy(data):
    counts = {}
    total = len(data)
    for row in data:
        label = row[-1]
        if label not in counts:
            counts[label] = 0
        counts[label] += 1
    ent = 0
    for label in counts:
        prob = counts[label] / total
        ent += -prob * math.log2(prob)
    return ent

def information_gain(data, attribute_index):
    total_entropy = entropy(data)
    values = set([row[attribute_index] for row in data])
    weighted_entropy = 0
    for value in values:
        subset = [row for row in data if row[attribute_index] == value]
        prob = len(subset) / len(data)
        weighted_entropy += prob * entropy(subset)
    return total_entropy - weighted_entropy

def id3(data, attributes):
    labels = [row[-1] for row in data]
    if len(set(labels)) == 1:
        return labels[0]
    if len(attributes) == 0:
        return max(set(labels), key=labels.count)
    best_attribute = max(attributes, key=lambda attr: information_gain(data, attr))
    tree = {best_attribute: {}}
    remaining_attributes = [attr for attr in attributes if attr!= best_attribute]
    values = set([row[best_attribute] for row in data])
    for value in values:
        subset = [row for row in data if row[best_attribute] == value]
        subtree = id3(subset, remaining_attributes)
        tree[best_attribute][value] = subtree
    return tree

data = [
    ['Sunny', 'Hot', 'High', 'Weak', 'No'],
    ['Sunny', 'Hot', 'High', 'Strong', 'No'],
    ['Overcast', 'Hot', 'High', 'Weak', 'Yes'],
    ['Rain', 'Mild', 'High', 'Weak', 'Yes'],
    ['Rain', 'Cool', 'Normal', 'Weak', 'Yes'],
    ['Rain', 'Cool', 'Normal', 'Strong', 'No'],
    ['Overcast', 'Cool', 'Normal', 'Strong', 'Yes'],
    ['Sunny', 'Mild', 'High', 'Weak', 'No'],
    ['Sunny', 'Cool', 'Normal', 'Weak', 'Yes'],
    ['Rain', 'Mild', 'Normal', 'Weak', 'Yes'],
    ['Sunny', 'Mild', 'Normal', 'Strong', 'Yes'],
    ['Overcast', 'Mild', 'High', 'Strong', 'Yes'],
    ['Overcast', 'Hot', 'Normal', 'Weak', 'Yes'],
    ['Rain', 'Mild', 'High', 'Strong', 'No']
]

attributes = list(range(len(data[0]) - 1))
tree = id3(data, attributes)
print(tree)

输出如下:

{0: {'Overcast': 'Yes', 'Rain': {3: {'Weak': 'Yes', 'Strong': 'No'}}, 'Sunny': {2: {'High': 'No', 'Normal': 'Yes'}}}}

如果采用 g r a p h v i z graphviz graphviz库画出来,效果如下(有些丑陋):
决策树
这里有科学有视化软件 G r a p h v i z Graphviz Graphviz介绍下载安装教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值