本系列代码托管于:https://github.com/chintsan-code/machine-learning-tutorials

本篇使用的项目为:tree_shannon

信息奠基人香农(Shannon)认为“信息是用来消除随机不确定性的东西”。也就是说衡量信息量大小就看这个信息消除不确定性的程度

例如我们说“太阳明天从东方升起”,这个事件发生的概率是1,但是确实一件废话,信息量为0

但是如果说明天广州有20%的概率下雨,那这句话的信息量就比较大了。它包含了20%下雨和80%不下雨这两种情况。

我们定义不确定性函数I为事件的信息量,是事件U发生的概率p的单调递减函数:

\[H(U)\ =\ \log_2\frac{1}{p}\ =\ -\log_2p\]

所以有
$$I( 太阳明天从东方升起 )=log_2\frac{1}{1}=0$$
$$ I(广州明天下雨) =-log_2(0.2)$$
$$ I(广州明天不下雨) =-log_2(0.8)$$

在一个信源中,我们不能只要考虑单一事件发生的不确定性,而是要考虑所有情况的平均不确定性,即是I的加权平均值E,权重就是各种情况发生的概率。这个结果就是信息熵

信息熵是用来衡量事物不确定性的。信息熵越大,事物越具不确定性,事物越复杂

$$H(U)=E[I(u_i)]=E[log_2\frac{1}{p(u_i)}]=-\sum{p(u_i)log_2p(u_i)}$$

在这里\(\sum{p(u_i)}=1\) ,\(U=\{u_1,u_2……\}\), 是所有情况的集合

下面来看代码:

def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    labelCounts = {}
    for featVec in dataSet:  # the the number of unique elements and their occurance
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key]) / numEntries
        shannonEnt -= prob * log(prob, 2)  # log base 2
    return shannonEnt

整个程序计算了两次信息熵:
\(H_1=\{“yes”,”no”\},p(“yes”)=0.4,p(“no”)=0.6\)
\(H_2=\{“maybe”,”yes”,”no”\}, p(“maybe”)=0.2 ,p(“yes”)=0.2,p(“no”)=0.6\)