0x01 三个定义
信息
指各个事物运动的状态及状态变化的方式。人们从对周围世界的观察得到的数据中获得信息。信息是抽象的意识或知识,它是看不见、摸不到的。当由人脑的思维活动产生的一种想法仍被存储在脑子里时,它就是一种信息。
消息
指包含信息的语言、文字和图像等。消息是具体的,它载荷信息,但它不是物理性的。
信源
是向通信系统提供消息$u$的人和机器。信源输出的是以符号形式出现的具体消息,它载荷信息。信源输出的消息可归纳为两类:离散消息和连续消息。前者如字母、汉字等,后者如语音、在时间上连续变化的电参数等。
0x02 自信息量
信源$X$,其概率空间为$\begin{bmatrix}X\\ P\end{bmatrix}=\begin{bmatrix}a_1 & a_2 & \dots & a_n\\ p(a_1) & p(a_2) & \dots & p(a_n)\end{bmatrix}$,这是信源固有的,但是信源在某时刻到底会发出什么符号,接受者是不能确定的,只有当信源发出的符号通过信道的传输到达接收端后,收信者才能得到信息,消除不确定性。符号出现的概率不同,其不确定性就不同。符号出现的概率与信息量是单调递减关系。
信息量可粗略地看作消除的不确定性的大小,一段消息消除的不确定性越大,其所载荷的信息量就越大。
定义具有概率为$p(x_i)$的符号$x_i$的自信息量为
$$
I(x_i)=-\log p(x_i)
$$
自信息量的单位与所用的对数底有关。在信息论中常用的是2,此时信息量的单位为比特(bit);若取自然对数,则单位为奈特(nat);若以10为底,则单位为笛特(det);
自信息量具有以下特性:
(1) $p(x_i)=1$,$I(x_i)=0$;
(2) $p(x_i)=0$,$I(x_i)=\infty$;
(3) 非负性;
(4) 单调递减性:若$p(x_1)<p(x_2)$,则$I(x_1)>I(x_2)$;
(5) 可加性:若有两个符号$x_i$,$y_j$同时出现,可用联合概率$p(x_i,y_j)$来表示,这时的自信息量为$I(x_i,y_j)=-\log p(x_i,y_j)$,当$x_i$和$y_j$相互独立时,有$p(x_i,y_j)=p(x_i)p(y_j)$,那么就有$I(x_i,y_j)=I(x_i)+I(y_j)$。
0x03 离散信源熵
信源熵
自信息量$I(x_i)$只是表征信源中各个符号$x_i$的不确定度,而一个信源总是包含多个符号消息,各个符号消息又按概率空间的先验概率分布,因而各个符号的自信息量就不同。所以自信息量$I(x_i)$是与概率分布有关的一个随机变量,不能作为信源总体的信息量度。对这样的随机变量只能采取求平均的方法。
假设一个不透明的布袋里放了100个球,其中有80个球是红色的,20个球是白色的,若随机取出一个球,猜测其颜色。该信源的概率空间为
$$
\begin{bmatrix}x \\ p \end{bmatrix} = \begin{bmatrix} x_1 & x_2 \\ 0.8 & 0.2\end{bmatrix}
$$
其中$x_1$表示摸出的球是红球,$x_2$表示摸出的球是白球。当被告知摸出的球是红球,则获得的信息量是
$$
I(x_1)=-\log p(x_1)=-\log_2 0.8 bit
$$
当被告知摸出的球是白球,获得的信息量是
$$
I(x_2)=-\log p(x_2)=-\log_2 0.2 bit
$$
在有放回的情况下随机摸取$n$次,易知平均随机摸取一次所获得的信息量为
$$
\begin{align} &\ \ \ \ \ \frac{1}{n}[np(x_1)I(x_1)+np(x_2)I(x_2)]\nonumber
\\&=-[p(x_1)\log p(x_1)+p(x_2)\log p(x_2)]\nonumber
\\&=-\sum_{i=1}^2p(x_i)\log p(x_i)\nonumber
\end{align}
$$
上述求出的就称为平均自信息量,即平均每个符号能提供的信息量。它只与信源各符号出现的概率有关,可以用来表征信源输出信息的总体特征。他是信源中各个符号自信息量的数学期望。即
$$
\begin{equation}E(I(X))=\sum_i p(x_i)I(x_i)=-\sum_i p(x_i)\log p(x_i)\end{equation}
$$
单位为 bit/符号。
类似地,引入信源$X$的平均不确定度的概念,它是在总体平均意义上的信源不确定度。由平均不确定度的定义式(1)与统计物理学中热熵的表示形式相似,且热熵是用来度量一个物理系统的杂乱性(无序性),与这里的不确定度概念相似,所以又把信源的平均不确定度称为信源$X$的熵。信源熵是在平均意义上来表征信源的总体特性,他是信源$X$的函数,一般写成$H(X)$,$X$是指随机变量的整体(包括概率空间)。信源熵是非负量。
例子
电视屏上约有$500 \times 600 =3 \times 10^5$个格点,按每点有10个不同的灰度等级考虑,则共能组成$10^{3\times10^5}$个不同的画面。按等概计算,平均每个画面可提供的信息量为
$$
\begin{align}H(x)&=-\sum_{i=1}^n p(x_i)\log p(x_i) = -\log_2 10^{-3\times 10^5}\nonumber
\\&=3\times 10^5 \times 3.32 \approx 10^6 bit/画面\nonumber
\end{align}
$$
条件熵
在给定$y_j$条件下,$x_i$的条件自信息量为$I(x_i|y_j)$,$X$集合的条件熵$H(X|y_j)$为
$$
H(X|y_i)=\sum_i p(x_i|y_i)I(x_i|y_i)
$$
进一步在给定$Y$(即各个$y_i$)条件下,$X$集合的条件熵$H(X|Y)$定义为
$$
\begin{align} H(X|Y)&=\sum_j p(y_j)H(X|y_j) \nonumber
\\&=\sum_{ij} p(y_j)p(x_i|y_j)I(x_i|y_j) \nonumber
\\&=\sum_{ij} p(x_i,y_j)I(x_i|y_j) \nonumber
\end{align}
$$
即条件熵是在联合符号集合$H(X,Y)$上的条件自信息量的联合概率甲醛统计平均值。条件熵$H(X|Y)$表示已知$Y$后,$X$的不确定度。
相应地,在给定$X$(即各个$x_i$)条件下,$Y$集合的条件熵$H(Y|X)$定义为
$$
H(Y|X)=\sum_{ij} p(x_i,y_j)I(y_j|X_I)=-\sum_{ij}p(x_i,y_j)\log p(y_j|x_i)
$$
联合熵
联合熵是联合符号集合$(X,Y)$上的每个元素对$(x_i,y_j)$的自信息量的概率加权平均值,定义为
$$
H(X,Y)=\sum_{ij}p(x_i,y_j)I(x_i,y_j)=-\sum_{ij}p(x_i,y_j)\log p(x_i,y_j)
$$
联合熵$H(X,Y)$表示$X$和$Y$同时发生的不确定度。联合熵$H(X,Y)$与熵$H(X)$及条件熵$H(Y|X)$之间存在下列关系:
$$
H(X,Y)=H(X)+H(Y|X)=H(Y)+H(X|Y)
$$
0x04 条件熵公式推导
设随机变量为明天的天气,晴天为$a_1$,下雨为$a_2$,被告知明天晴天对应的概率和自信息量为$p(a_1)$和$I(a_1)$,被告知明天下雨对应的概率和自信息量为$p(a_2)$、$I(a_2)$,这是具体事件。而被告知今天的天气和被告知明天的天气分别对应$X$和$Y$,$X$包含两种情况:$x_1$,$x_2$,$Y$同理。如被告知今天的天气的信息熵$H(X)=p(a_1)I(a_1)+p(a_2)I(a_2)$ 。
信息熵(信源熵)即为平均不确定性、平均信息量
- $p(y_1|x_1)$ 代表在今天下雨的前提下,明天下雨的概率,其信息量$I(y_1|x_1)=-\log p(y_1|x_1)$
-
已知今天下雨,被告知明天天气,这个事件的信息熵$H(Y|x_1)=p(y_1|x_1)I(y
_1|x_1)+p(y_2|x_1)I(y_1|x_1)$ -
已知今天天气,被告知明天天气,这个事件的信息熵$H(Y|X)=p(x_1)H(Y|x_1)+p(x_2)H(Y|x2)$
由此可推导出通用公式
$$
H(Y|X)=-\sum_{ij} p(x_i,y_i)\log p(y_i|x_i)
$$
思考
可否定义$H(y_1|X)$?
即已知今天天气,被告知明天下雨。
$$
H(Y|X)=-p(y_1)p(x_2|y_1)\log (y_1|x_2)
\\H(y_1|X)=p(x_1|y_1)I(y_1|x_1)+p(x_2|y_1)I(y_1|x_2)
$$
0x05 应用实践
给出一个大小为$512\times 512$的Lena图,以$32\times 32$为区块大小,找出Lena图中信息熵最小的区块
做法
将Lena图以灰度方式读入数组,然后用32×32的滑动窗口遍历该二维数组,计算每个灰度值在此窗口中的频度,算出概率并计算此窗口的信息熵,最后找出信息熵最小的窗口。
实现
import cv2
import math
import numpy as np
image = cv2.imread("./Lena.jpg",0)
# 创建滑动窗口
img = np.lib.stride_tricks.sliding_window_view(np.array(image),(32,32))
# 记录灰度值出现频度的数组
grayscale = [0 for i in range(256)]
entropyList = [[0.0 for i in range(len(img))] for i in range(len(img))]
# 遍历窗口数组
for x in range(len(img)):
for y in range(len(img)):
print('窗口[{0}][{1}]'.format(x, y), end='')
tmp = img[x][y]
# 遍历窗口内数据
for k in range(32):
for l in range(32):
grayscale[tmp[k][l]] += 1
# 计算信息熵
entropy = 0.0
for i in grayscale:
if i != 0:
entropy += float(i / 1024) * float(math.log(1024 / i, 2))
entropyList[x][y] = entropy
print('信息熵为', entropy)
# 临时变量归零
entropy = 0.0
grayscale = [0 for i in range(256)]
# 找出最小值和其位置
minScale = 255.0
position = (0, 0)
for i,x in enumerate(entropyList):
for j,y in enumerate(x):
if y < minScale:
minScale = y
position = (i, j)
print("\n信息熵最小值:", minScale)
print("位置:", position)
# 画出区块边框
for i in range(position[1],position[1] + 32):
image[position[0]][i] = 255
image[position[0] + 31][i] = 255
for i in range(32):
image[i][position[1]] = 255
image[i][position[1] + 31] = 255
cv2.imwrite('./output.jpg',image, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
结果
信息熵最小值:1.1805713072324544
位置:(0,133)