推荐书: Python开发最佳实践

信息熵信息增益率基尼系数原理和pandas实战

分享时@该用户已经被封, 我就能回答你的问题奥!

文章目录
  1. 1. 案例和数据集
  2. 2. 信息熵怎么算
  3. 3. 条件信息熵怎么算
  4. 4. 信息增益
  5. 5. 属性的信息增益与属性的类别数的关系
  6. 6. 信息增益率


信息增益(Info Gain), 信息增益率(Info Gain Ratio)和 基尼指数(Gini Index)都是在做决策树时试用的分支选择策略, 下面我们试用numpy来实现这几个指标, 以便加深对这些指标的理解。

下面我们来引入用到的库:

1
2
3
4
5
6
7
import numpy as np
# 进行数据整理
import pandas as pd
# 数据
import io
# 验证结果
from scipy import stats

案例和数据集

学习决策树常用的一个数据集就是”机器学习(周志华)》 西瓜数据集3.0”, 下面我把数据粘贴出来, 你们就不必下载了, 直接硬编码到python种使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
data_str = output = io.StringIO('''编号,色泽,根蒂,敲声,纹理,脐部,触感,密度,含糖率,好瓜
1,青绿,蜷缩,浊响,清晰,凹陷,硬滑,0.697,0.46,是
2,乌黑,蜷缩,沉闷,清晰,凹陷,硬滑,0.774,0.376,是
3,乌黑,蜷缩,浊响,清晰,凹陷,硬滑,0.634,0.264,是
4,青绿,蜷缩,沉闷,清晰,凹陷,硬滑,0.608,0.318,是
5,浅白,蜷缩,浊响,清晰,凹陷,硬滑,0.556,0.215,是
6,青绿,稍蜷,浊响,清晰,稍凹,软粘,0.403,0.237,是
7,乌黑,稍蜷,浊响,稍糊,稍凹,软粘,0.481,0.149,是
8,乌黑,稍蜷,浊响,清晰,稍凹,硬滑,0.437,0.211,是
9,乌黑,稍蜷,沉闷,稍糊,稍凹,硬滑,0.666,0.091,否
10,青绿,硬挺,清脆,清晰,平坦,软粘,0.243,0.267,否
11,浅白,硬挺,清脆,模糊,平坦,硬滑,0.245,0.057,否
12,浅白,蜷缩,浊响,模糊,平坦,软粘,0.343,0.099,否
13,青绿,稍蜷,浊响,稍糊,凹陷,硬滑,0.639,0.161,否
14,浅白,稍蜷,沉闷,稍糊,凹陷,硬滑,0.657,0.198,否
15,乌黑,稍蜷,浊响,清晰,稍凹,软粘,0.36,0.37,否
16,浅白,蜷缩,浊响,模糊,平坦,硬滑,0.593,0.042,否
17,青绿,蜷缩,沉闷,稍糊,稍凹,硬滑,0.719,0.103,否''')

data = pd.read_csv(data_str)
data.set_index('编号', inplace=True)
data
输出(html):
色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜
编号
1 青绿 蜷缩 浊响 清晰 凹陷 硬滑 0.697 0.460
2 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 0.774 0.376
3 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 0.634 0.264
4 青绿 蜷缩 沉闷 清晰 凹陷 硬滑 0.608 0.318
5 浅白 蜷缩 浊响 清晰 凹陷 硬滑 0.556 0.215
6 青绿 稍蜷 浊响 清晰 稍凹 软粘 0.403 0.237
7 乌黑 稍蜷 浊响 稍糊 稍凹 软粘 0.481 0.149
8 乌黑 稍蜷 浊响 清晰 稍凹 硬滑 0.437 0.211
9 乌黑 稍蜷 沉闷 稍糊 稍凹 硬滑 0.666 0.091
10 青绿 硬挺 清脆 清晰 平坦 软粘 0.243 0.267
11 浅白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057
12 浅白 蜷缩 浊响 模糊 平坦 软粘 0.343 0.099
13 青绿 稍蜷 浊响 稍糊 凹陷 硬滑 0.639 0.161
14 浅白 稍蜷 沉闷 稍糊 凹陷 硬滑 0.657 0.198
15 乌黑 稍蜷 浊响 清晰 稍凹 软粘 0.360 0.370
16 浅白 蜷缩 浊响 模糊 平坦 硬滑 0.593 0.042
17 青绿 蜷缩 沉闷 稍糊 稍凹 硬滑 0.719 0.103

该数据集通常是使用前几个西瓜属性预测最后一个指标”好瓜”.

信息熵怎么算

要计算信息增益的话, 首先要知道怎么算信息熵, 它的公式是:

$$ H(X) = \sum_{i \in X} p_i log p_i $$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def entropy(data, att_name):
'''
data: 数据集
att_name: 属性名
'''
levels = data[att_name].unique()
# 信息熵
ent = 0
for lv in levels:
pi = sum(data[att_name]==lv) / data.shape[0]
ent += pi*np.log(pi)
return -ent
print('好瓜的信息熵:')
entropy(data, '好瓜')
输出(stream):
好瓜的信息熵:
输出(plain):
0.8760918930634294

使用scipy内置的stats.entropy验证我们的函数:

1
2
3
4
5
6
def entropy_scipy(data, att_name):
n = data.shape[0]
values = data[att_name].value_counts()
return stats.entropy(values/n)

assert entropy(data, '好瓜')==entropy_scipy(data, '好瓜')

条件信息熵怎么算

已知条件Y, 求X的概率就是P(X|Y), 知道的信息越多,随机事件的不确定性就越小。
书中定义:在Y条件X的条件熵:(二元模型)

引自维基百科:

因为我们已经有了交叉熵的公式, 所以我们其实可以直接算出$H(Y|X=x)$

1
2
3
4
5
6
7
8
9
10
11
def conditional_entropy(data, xname, yname):
xs = data[xname].unique()
ys = data[yname].unique()
p_x = data[xname].value_counts() / data.shape[0]
ce = 0
for x in xs:
ce += p_x[x]*entropy(data[data[xname]==x], yname)
return ce

print('触感条件下, 好瓜的信息熵:')
conditional_entropy(data, '触感', '好瓜')
输出(stream):
触感条件下, 好瓜的信息熵:
输出(plain):
0.8462465738213797

信息增益

理论上我们可以证明$H(Y)>=H(Y|X)$

1
2
3
4
5
6
7
def gain(data, xname, yname):
en = entropy(data, yname)
ce = conditional_entropy(data, xname, yname)
return en - ce

print('触感的引入导致的信息增益:')
gain(data, '触感', '好瓜')
输出(stream):
触感的引入导致的信息增益:
输出(plain):
0.029845319242049695

属性的信息增益与属性的类别数的关系

属性的类别越多, 根据该属性就可以把数据切分的更细, 这样往往导致信息的混乱程度降低, 所以类别多的属性的信息增益较大, 我们可以用代码实验一下:

1
2
3
4
5
6
data['testCol'] = 0
data.iloc[10:, -1] = 1
print(gain(data, 'testCol', '触感'))
data.iloc[14:, -1] = 2
print(gain(data, 'testCol', '触感'))
print(gain(data, '密度', '触感'))
输出(stream):
0.00011925580490779186
0.0018253756129741339
0.605797499372304

信息增益率

信息增益率的提出是为了规避信息增益种属性类别数目造成的影响, 它的计算公式是:

$$ GainRatio(Y, X) = {Gain(Y, X) \over SplitInfo(X)} $$

其中:

$$ SplitInfo(X)= \sum_{i \in X} p_i log p_i = H(X) $$

1
2
3
4
5
6
def gain_ratio(data, xname, yname):
g = gain(data, xname, yname)
si = entropy(data, xname)
return g / si
print('信息增益率:')
gain_ratio(data, '触感', '好瓜')
输出(stream):
信息增益率:
输出(plain):
0.04926616447405919

注意
本文由jupyter notebook转换而来, 您可以在这里下载notebook
有问题可以直接在下方留言
或者给我发邮件675495787[at]qq.com
请记住我的网址: mlln.cn 或者 jupyter.cn