一. 熵的概念
1.1 信息熵
信息量对于这个事情判断的能提供的信息度。
而其实信息熵是信息量的期望(均值),它不是针对每条信息,而是针对整个不确定性结果集而言,信息熵越大,事件不确定性就越大。单条信息只能从某种程度上影响结果集概率的分布。
使用一个公式来计算记录n天数据需要的存储空间:Sn
(1.1)
S
n
=
n
×
∑
i
=
1
4
(
P
i
×
F
(
P
i
)
)
,
S_{n}=n \times \sum_{i=1}^{4}\left(P_{i} \times F\left(P_{i}\right)\right),\tag{1.1}
Sn=n×i=1∑4(Pi×F(Pi)),(1.1)
P
i
P_i
Pi表示第i个事件发生的概率;
F
(
P
i
)
F(P_i)
F(Pi) 表示存储空间的存储因子
如何确定这个函数
F
(
P
i
)
F(P_i)
F(Pi) 的形式?考虑这个函数需要满足条件:概率大的事件对应小的存储空间,说人话,就是成反比,就很容易反映出是
1
P
i
\frac{1}{P_{i}}
Pi1。
发现里面有个除号,为了不要除号,我们就可以选择取对数。理由:
- 对数操作可以让原本不符合正态分布的模型符合正态分布,比如随着模型自变量的增加,因变量的方差也增大的模型取对数后会更加稳定;
- 对数可以把乘法变加法。
这样很容易得出定义:
(1.2)
F
(
P
i
)
=
log
a
(
1
P
i
)
,
F\left(P_{i}\right)=\log _{a}\left(\frac{1}{P_{i}}\right),\tag{1.2}
F(Pi)=loga(Pi1),(1.2)
a作为底数,可以取2(处理2bit数据),10(万金油),e(处理正态分布相关的数据)
然后我们将公式1.1和公式1.2结合,可以得到
(1.3)
H
(
P
)
=
∑
i
P
(
i
)
log
a
1
P
(
i
)
=
−
∑
i
P
(
i
)
log
a
P
(
i
)
,
H(P)=\sum_{i} P(i) \log _{a} \frac{1}{P(i)}=-\sum_{i} P(i) \log _{a} P(i),\tag{1.3}
H(P)=i∑P(i)logaP(i)1=−i∑P(i)logaP(i),(1.3)
信息熵其实从某种意义上反映了信息量存储下来需要多少存储空间
总结为:根据真实分布,我们能够找到一个最优策略,以最小的代价消除系统的不确定性,而这个代价的大小就是信息熵。
1.2 交叉熵
假定在确定性更大的概率分布情况下,用更不确定的存储策略来计算,比如使用 P 的概率乘上 Q的存储因子,套用公式1.3
(2.1)
H
(
P
,
Q
)
=
∑
i
P
(
i
)
log
a
1
Q
(
i
)
,
H(\mathbf{P}, \mathbf{Q})=\sum_{i} P(i) \log _{a} \frac{1}{Q(i)},\tag{2.1}
H(P,Q)=i∑P(i)logaQ(i)1,(2.1)
1.3 相对熵
有了信息熵和交叉熵后,相对熵是用来衡量两个概率分布之间的差异,记为
D
(
P
∥
Q
)
=
H
(
P
,
Q
)
−
H
(
P
)
D(P \| Q)=H(P, Q)-H(P)
D(P∥Q)=H(P,Q)−H(P),也称为KL散度
D
K
L
(
P
∥
Q
)
=
∑
i
P
(
i
)
log
a
P
(
i
)
Q
(
i
)
D_{K L}(P \| Q)=\sum_{i} P(i) \log _{a} \frac{P(i)}{Q(i)}
DKL(P∥Q)=i∑P(i)logaQ(i)P(i)
当
P
(
i
)
=
Q
(
i
)
P(i)=Q(i)
P(i)=Q(i)的时候,该值为0,深度学习过程也是一个降低该值的过程,该值越低,训练出来的概率Q越接近样本集概率P,即越准确,或者可以理解为相对熵一把标尺,用来衡量两个函数是否相似,一样就是0,当然,这种解释十分牵强,但是更直观
计算数据集的shangnonEnt
import numpy as np
import pandas as pd
data=pd.read_csv('watermelon_3a.csv')
def calc_entropy(dataSet):
m=len(dataSet)
labelcounts={}
for i in range(m):
label=dataSet[i][-1]
labelcounts[label]=labelcounts.get(label,0)+1
entropy=0.0
for counts in labelcounts.values():
prob=counts/m
entropy-=prob*np.log2(prob)
return entropy
dataset=data.values
entropy=calc_entropy(dataset)