- Author: 修远;
- 说明:本文为Datawhale下开源项目《李宏毅机器学习》决策树的补充内容。作者水平有限,还望学习者批评指正。
- Datawhale
学习目标:
- 学习信息量计算,原理
- 学习信息熵
- 证明0⩽H(p)⩽logn0\leqslant H(p)\leqslant logn0⩽H(p)⩽logn
- 联合概率,边缘概率
- 联合熵,条件熵,条件熵公式推导
- 互信息,互信息公式推导
- 相对熵,交叉熵
- 回顾LR中的交叉熵
- 计算给定数据集中的香农熵
熵的相关概念
1信息熵
熵 (entropy) 这一词最初来源于热力学。1948年,克劳德·爱尔伍德·香农将热力学中的熵引入信息论,所以也被称为香农熵 (Shannon entropy),信息熵 (information entropy)。首先,我们先来理解一下信息这个概念。信息是一个很抽象的概念,百度百科将它定义为:指音讯、消息、通讯系统传输和处理的对象,泛指人类社会传播的一切内容。那信息可以被量化么?可以的!香农提出的“信息熵”概念解决了这一问题。
1.1背景
一条信息的信息量和它的不确定性有着直接的关系。比如说,我们需要搞清楚一件非常非常不确定的事,或者是我们一无所知的事,就需要了解大量的信息。相反,如果我们对某件事已经有了较多的了解,我们就不需要太多的信息就能把它搞清楚。所以,从这个角度,我们可以认为,信息量的度量就等于不确定性的多少。
那么如何量化信息的度量呢?来看一个例子。2010年举行了世界杯足球赛,大家都很关心谁会是冠军。假如我错过了看世界杯,赛后我问一个知道比赛结果的观众“哪支球队是冠军"?他不愿意直接告诉我,而让我猜,并且我每猜一次,他要收一元钱才肯告诉我是否猜对了,那么我需要付给他多少钱才能知道谁是冠军呢?我可以把球队编上号,从1到 32,然后提问:“冠军的球队在1一16号中吗?"假如他告诉我猜对了,我会接着问:“冠军在1一8号中吗?"假如他告诉我猜错了,我自然知道冠军队在9一16号中。这样只需要五次,我就能知道哪支球队是冠军。
所以,谁是世界杯冠军这条消息的信息量只值5块钱。
当然,香农不是用钱,而是用“比特" ( Bit )这个概念来度量信息量。一个比特是一位二进制数,计算机中的一个字节是8比特。在上面的例子中,这条消息的信息量是5比特。(如果有朝一日有64支球队进人决赛阶段的比赛,那么“谁是世界杯冠军"的信息量就是6比特,因为要多猜一次。)读者可能已经发现,信息量的比特数和所有可能情况的对数函数log有关。(1og232=5,log264=61og_232=5,log_264=61og232=5,log264=6)
有些读者此时可能会发现实际上可能不需要猜五次就能猜出谁是冠军,因为像西班牙、巴西、德国、意大利这样的球队得冠军的可能性比日本、南非、韩国等球队大得多。因此,第一次猜测时不需要把32支球队等分成两个组,而可以把少数几支最可能的球队分成一组,把其他队分成另一组。然后猜冠军球队是否在那几支热门队中。重复这样的过程,根据夺冠概率对剩下的候选球队分组,直至找到冠军队。这样,也许三次或四次就猜出结果“
因此,当每支球队夺冠的可能性(概率)不等时, 谁是世界杯冠军"的信息量比5比特少。香农指出,它的准确信息量应该是
H=−(p(1)logp(1)+…+p(32)logp(32))H=-(p(1)logp(1)+…+p(32)logp(32))H=−(p(1)logp(1)+...+p(32)logp(32))
其中,Pi,P2,一p32分别是这32支球队夺冠的概率。香农把它称为“信息熵" (Entropy),一般用符号H表示,单位是比特。有兴趣的读者可以推算一下当32支球队夺冠概率相同时,对应的信息熵等于5比特。。对于任意一个随机变量x(比如得冠军的球队),它的熵定义如下:
H(X)=−∑x∈Xnp(x)logp(x)H(X)=-\sum_{x\in X}^{n}p(x)logp(x)H(X)=−x∈X∑np(x)logp(x)
若pip_ipi=0,则定义为0log0=0。上式中的对数以2为底或以e为底(自然对数),这是熵的单位分别称做比特(bit)。由定义可知,熵只依赖于X的分布,而与X的取值无关,所以也可将X的熵记作H§,即
H(p)=−∑i=1npilogpiH(p)=-\sum_{i=1}^{n}p_ilogp_iH(p)=−i=1∑npilogpi
1.2信息熵公式的理解:
1信息量
假如说,一个事件A:你买了一本书,另一个事件B:你将《李宏毅机器学习》的内容全都搞懂了。你买了一本所需的信息量是非常少的,你将《李宏毅机器学习》的内容全都搞懂了这所需要的信息量是非常大的,如何度量这个事件的信息量呢?事件A的信息量表示为H(A),事件B的信息量表示为H(B)。两者比较为:H(A)<H(B)H(A)<H(B)H(A)<H(B)。
我们想要在数学公式上跟我们的直觉相统一,假设X是一个事件或者一个信息的时候,它的信息量是跟概率有关的。
我们可以看到发生的几率越大,所需的信息量就越小,那我们就先假设信息量与概率的关系的为H(X)H(X)H(X)与1p(x)\frac{1}{p(x)}p(x)1有关系
两个事件的信息跟每个事件的信息量是什么样的关系
希望两者能够相加起来(有量纲的量),H(x1,x2)=H(x1)+H(x2)H(x_1,x_2)=H(x_1)+H(x_2)H(x1,x2)=H(x1)+H(x2)
信息量是大于等于0,肯定不可能是负的 H(X⩾)0H(X\geqslant) 0H(X⩾)0
构建一个函数,满足其上述的关系条件
- H(X)=log1p(x)=−logp(x)H(X)=log\frac{1}{p(x)}=-logp(x)H(X)=logp(x)1=−logp(x)
- 对数函数的底数为2
- 在信息学中,log的底数一般都为2。但是在机器学习中,底数经常是自然常数e。至于到底用哪一个,一般主要看哪个好用以及哪个好算(例如在下面进行证明的过程中,对数底数为e)
- 该函数符合我们对信息量的直觉
2信息熵
请先在脑海里先记住信息熵是信息量的数学期望
我们想求关于H(X)H(X)H(X)在以p(x)p(x)p(x)分布下的H(X)H(X)H(X)的数学期望
Entropy(X)=−∑xp(x)logH(X)Entropy(X)=-\sum_xp(x)logH(X)Entropy(X)=−x∑p(x)logH(X)
1.3证明0⩽H(p)⩽logn0\leqslant H(p)\leqslant logn0⩽H(p)⩽logn:
利用拉格朗日函数证明
-
目标函数
H(p)=−p(1)logp(1)−p(2)logp(2)…−p(n)logp(n)H(p)=-p(1)logp(1)-p(2)logp(2)…- p(n)logp(n)H(p)=−p(1)logp(1)−p(2)logp(2)...−p(n)logp(n)
-
限定条件
p(1)+p(2)+…+p(n)=1p(1)+p(2)+…+p(n)=1p(1)+p(2)+...+p(n)=1
-
构建拉格朗日函数
L(p(1),p(2),…p(n),λ)=−p(1)logp(1)−…−p(n)logp(n)+λ(p(1)+…p(n)−1)L(p(1),p(2),…p(n),\lambda)=-p(1)logp(1)-…-p(n)logp(n)+\lambda(p(1)+…p(n)-1)L(p(1),p(2),...p(n),λ)=−p(1)logp(1)−...−p(n)logp(n)+λ(p(1)+...p(n)−1)
对p(1)偏导等于0
λ−log(e∗p(1))=0\lambda-log(e*p(1))=0λ−log(e∗p(1))=0
…
对p(n)偏导等于0λ−log(e∗p(n))=0\lambda-log(e*p(n))=0λ−log(e∗p(n))=0
对其λ\lambdaλ偏导等于0
p(1)+p(2)+…+p(n)−1=0p(1)+p(2)+…+p(n)-1=0p(1)+p(2)+...+p(n)−1=0
求得:
p(1)=p(2)=…=p(n)=1np(1)=p(2)=…=p(n)=\frac{1}{n}p(1)=p(2)=...=p(n)=n1
代入目标函数得到极值
f(1n,1n,…,1n)=−(1nlog1n+…+1nlog1n)f(\frac{1}{n},\frac{1}{n},…,\frac{1}{n})=-(\frac{1}{n}log\frac{1}{n}+…+\frac{1}{n}log\frac{1}{n})f(n1,n1,...,n1)=−(n1logn1+...+n1logn1)
=−log(1n)=-log(\frac{1}{n})=−log(n1)=logn=logn=logn
信息量是对信息的度量,若没有信息时就为0,不可能出现负数的情况,得证为
0⩽H(p)⩽logn0\leqslant H(p)\leqslant logn0⩽H(p)⩽logn
2 条件熵(Conditional entropy)
2.1公式理解
设有随机变量(X,Y),其联合概率分布为P(X=xi,Y=yj)=pij,i=1…n,j=1…mP(X=x_i,Y=y_j)=p_{ij},i=1…n,j=1…mP(X=xi,Y=yj)=pij,i=1...n,j=1...m
条件熵H(Y|X)表示在已知随机变量X的条件下随机变量Y的不确定性。随机变量X给定的条件下随机变量Y的条件熵(conditional entropy)H(Y|X),定义为X给定条件下Y的条件概率分布的熵对X的数学期望
“相关的”信息能够消除不确定性
H(Y∣X)=∑I=1mpiH(Y∣X=xi)H(Y|X)=\sum_{I=1}^{m}p_iH(Y|X=x_i)H(Y∣X)=I=1∑mpiH(Y∣X=xi)
这里pip_ipi=P(X=xix_ixi),i=1,2,…n
2.2条件熵的定义式:
(X,Y)(X,Y)(X,Y)发生所包含的熵,减去X单独发生包含的熵:在X发生的前提下,Y发生“新”带来的熵
H(X,Y)−H(X)H(X,Y)-H(X)H(X,Y)−H(X)
=−∑x,ylog(x,y)p(x,y)+∑xp(x)logp(x)= -\sum_{x,y}log(x,y)p(x,y)+\sum_xp(x)logp(x)=−∑x,ylog(x,y)p(x,y)+∑xp(x)logp(x)
=−∑x,ylog(x,y)p(x,y)+∑x(∑yp(x,y))logp(x)=-\sum_{x,y}log(x,y)p(x,y)+\sum_x(\sum_yp(x,y))logp(x)=−∑x,ylog(x,y)p(x,y)+∑x(∑yp(x,y))logp(x)
=−∑x,ylog(x,y)p(x,y)+∑x,yp(x,y)logp(x)=-\sum_{x,y}log(x,y)p(x,y)+\sum_{x,y}p(x,y)logp(x)=−∑x,ylog(x,y)p(x,y)+∑x,yp(x,y)logp(x)
=−∑x,yp(x,y)logp(x,y)p(x)=-\sum_{x,y}p(x,y)log\frac{p(x,y)}{p(x)}=−∑x,yp(x,y)logp(x)p(x,y)
=−∑x,yp(x,y)logp(y∣x)=-\sum_{x,y}p(x,y)logp(y|x)=−∑x,yp(x,y)logp(y∣x)
H(X,Y)−H(X)=−∑x,yp(x,y)logp(y∣x)H(X,Y)-H(X)=-\sum_{x,y}p(x,y)logp(y|x)H(X,Y)−H(X)=−∑x,yp(x,y)logp(y∣x)
=−∑x∑yp(x,y)logp(y∣x)=-\sum_x\sum_yp(x,y)logp(y|x)=−∑x∑yp(x,y)logp(y∣x)
=−∑xp(x)(∑yp(y∣x)logp(y∣x))=-\sum_xp(x)(\sum_yp(y|x)logp(y|x))=−∑xp(x)(∑yp(y∣x)logp(y∣x))
=∑xp(x)H(Y∣X=x)=\sum_xp(x)H(Y|X=x)=∑xp(x)H(Y∣X=x)
3 联合熵:
对服从联合分布为p(x,y)p(x,y)p(x,y)的一对离散随机变量(X,Y)(X,Y)(X,Y),其联合熵H(X,Y)H(X,Y)H(X,Y)可表示为
H(X,Y)=−∑x∈X∑y∈Yp(x,y)logp(x,y)H(X,Y)=-\sum_{x\in X}\sum_{y\in Y}p(x,y)logp(x,y)H(X,Y)=−x∈X∑y∈Y∑p(x,y)logp(x,y)
4 边缘概率
当X和Y都是离散型随机变量时,X和Y的联合概率分布列了一定义为p(x,y)p(x,y)p(x,y)
-
利用p(x,y)p(x,y)p(x,y)可得XXX的分布列
pX(x)=P(X=x)=∑yp(x,y)p_X(x)=P(X=x)=\sum_{y}p(x,y)pX(x)=P(X=x)=y∑p(x,y)
-
利用p(x,y)p(x,y)p(x,y)可得YYY的分布列
pY(y)=P(Y=y)=∑xp(x,y)p_Y(y)=P(Y=y)=\sum_{x}p(x,y)pY(y)=P(Y=y)=x∑p(x,y)
5 互信息:
5.1公式理解
两个随机变量X,Y的互信息,定义为X,Y的联合分布和独立分布乘积的相对熵
- 度量两个随机变量的“相关性”
- 互信息就是随机事件X的不确定性或者说熵H(X),以及在知道随机事件Y条件下的不确定性(条件熵)的差异
I(X,Y)=D(P(X,Y)∣∣P(X)P(Y))I(X,Y)=D(P(X,Y)||P(X)P(Y))I(X,Y)=D(P(X,Y)∣∣P(X)P(Y))
I(X,Y)=∑x,yp(x,y)logp(x,y)p(x)p(y)I(X,Y)=\sum_{x,y}p(x,y)log\frac{p(x,y)}{p(x)p(y)}I(X,Y)=x,y∑p(x,y)logp(x)p(y)p(x,y)
I(X,Y)=H(X)−H(X∣Y)I(X,Y)=H(X)-H(X|Y)I(X,Y)=H(X)−H(X∣Y)
5.2 互信息的定义式:
I(X,Y)=H(X)+H(Y)−H(X,Y)I(X,Y)=H(X)+H(Y)-H(X,Y)I(X,Y)=H(X)+H(Y)−H(X,Y)
=−∑xp(x)logp(x)+(−∑yp(y)logp(y))−(−∑x,yp(x,y)logp(x,y))=-\sum_xp(x)logp(x)+(-\sum_yp(y)logp(y))-(-\sum_{x,y}p(x,y)logp(x,y))=−∑xp(x)logp(x)+(−∑yp(y)logp(y))−(−∑x,yp(x,y)logp(x,y))
=(−∑x(∑yp(x,y)logp(x))+(−∑y(∑xp(x,y)logp(y)+∑x,yp(x,y)logp(x,y)=(-\sum_x(\sum_yp(x,y)logp(x))+(-\sum_y(\sum_xp(x,y)logp(y)+\sum_{x,y}p(x,y)logp(x,y)=(−∑x(∑yp(x,y)logp(x))+(−∑y(∑xp(x,y)logp(y)+∑x,yp(x,y)logp(x,y)
=−∑x,yp(x,y)logp(x)−∑x,yp(x,y)logp(y)+∑x,ylogp(x,y)=-\sum_{x,y}p(x,y)logp(x)-\sum_{x,y}p(x,y)logp(y)+\sum_{x,y}logp(x,y)=−∑x,yp(x,y)logp(x)−∑x,yp(x,y)logp(y)+∑x,ylogp(x,y)
=∑x,yp(x,y)(logp(x,y)−logp(x)−logp(y))=\sum_{x,y}p(x,y)(logp(x,y)-logp(x)-logp(y))=∑x,yp(x,y)(logp(x,y)−logp(x)−logp(y))
=∑x,yp(x,y)logp(x,y)p(x)p(y)=\sum_{x,y}p(x,y)log\frac{p(x,y)}{p(x)p(y)}=∑x,yp(x,y)logp(x)p(y)p(x,y)
6 相对熵:
相对熵又称交叉熵,KL散度等
如果我们对于同一个随机变量 x 有两个单独的概率分布 P(x) 和 Q(x),我们可以使用 KL 散度(Kullback-Leibler (KL) divergence)来衡量这两个分布的差异
p(X),q(X)的比值取对数之后,在p(X)的概率分布上求期望
D(p∣∣q)=∑xp(x)logp(x)q(x)=Eplogp(x)q(x)D(p||q)=\sum_{x}p(x)log\frac{p(x)}{q(x)}=E_plog\frac{p(x)}{q(x)}D(p∣∣q)=x∑p(x)logq(x)p(x)=Eplogq(x)p(x)
说明:相对熵可以度量两个随机变量的“距离”
7 交叉熵:
由相对熵公式变形得:
D(p∣∣q)=∑xp(x)logp(x)q(x)D(p||q)=\sum_xp(x)log\frac{p(x)}{q(x)}D(p∣∣q)=∑xp(x)logq(x)p(x)
=∑xp(x)logp(x)−∑xp(x)logq(x)=\sum_xp(x)logp(x)-\sum_xp(x)logq(x)=∑xp(x)logp(x)−∑xp(x)logq(x)
=−H(p)+(−∑xp(x)logq(x))=-H(p)+(-\sum_xp(x)logq(x))=−H(p)+(−∑xp(x)logq(x))
等式的前一部分就是p的熵,等式的后一部分,就是交叉熵
H(p,q)=−∑xp(x)logq(x)H(p,q)=-\sum_xp(x)logq(x)H(p,q)=−∑xp(x)logq(x)
在机器学习中,我们需要评估yyy和y^\hat{y}y^之间的差距,使用KL散度刚刚好,即D(y∣∣y^)D(y||\hat{y})D(y∣∣y^)(也就是p(x)p(x)p(x),q(x)q(x)q(x)),由于KL散度中的前一部分$−H(y)4不变,故在优化过程中,只需要关注交叉熵就可以了。所以一般在机器学习中直接用用交叉熵做loss,评估模型。
8 回顾LR中的交叉熵
LR交叉熵公式
$$L(\theta)=\sum_{i=1}{m}[-yilogh_{\theta}(xi)+(1-yi)log(1-h_{\theta}(x^i))]
上式中的yiy^iyi是真实数据,hθ(xi)h_{\theta}(x^i)hθ(xi)是预测出来的数据分布(模型),我们一直想要做的是训练数据上学到的模型与真实数据分布越接近越好,即loss function最小,所以我们需要交叉熵越小越好。
综上所述,我们一直想要做的就是最小化误差(训练数据与模型上的分布的差异),即最小化相对熵。又因为前一部分-H(y)不变,最小化相对熵也就是最小化交叉熵。
得证,交叉熵可以用来计算模型分布与真实数据分布之间的差异
9计算给定数据集的香农熵:
写code之前,请查看公式
import numpy as np
def cancShannonEnt(dataSet):''':param dataSet: dataSet:return: shannonEnt'''# 计算公式前,注意数据的格式(array)numEntries = len(dataSet) # 获取数据的行数labelCounts = { } # 设置字典数据格式,想要存储的数据格式为:类别:频数for featVec in dataSet: # 获取数据集每一行的数据currentLabel = featVec[-1] # 获取特征向量的最后一列# 检查字典中key是否存在# 如果key不存在if currentLabel not in labelCounts.keys():# 将当前的标签存于字典中,并将频数置为0labelCounts[currentLabel] = 0# 如果key存在,在当前的键值上+1labelCounts[currentLabel] +=1# 数据已准备好,计算熵shannonEnt = 0.0 # 初始化信息熵for key in labelCounts: # 遍历出数据中所的类别pro = float(labelCounts[key]) /numEntries shannonEnt -= pro * np.log2(pro) # 计算信息熵return shannonEnt # 返回信息熵
参考书籍:
- 《数学之美》
- 《机器学习实战》