信息熵及其计算

-- TOC --

信息论之父香农(Shannon)于1948年,将热力学中熵的概念引入到了信息论中,提出了“信息熵”这一概念。信息熵用于量化信息,将原本模糊的信息概念进行计算得出精确的信息熵值。

概念理解

信息熵,是描述信息不确定性的值,单位bit

信息熵值越高,不确定性就越高。(正如热力学中的熵,值越高,系统的混乱程度就越高。)

信息用来消除不确定性,有了信息输入(获取),就会导致熵值变小。

信息熵的计算公式为:

$$H(x)=\sum_{i}{p_i}\cdot\log_2{\cfrac{1}{p_i}}$$

可以将x理解为一个所谓的“信息系统”,这个系统内有一些事件,每个事件对应一个发生概率p。概率越大的事件,其发生时带来的信息量就越小。反之,概率越小的事件,其发生时带来的信息量就越大。

在一个系统中,各事件概率在 \([0,1]\) 这个区间,在计算对数的时候,用概率的倒数,是为了得到一个正值。(概率为0的事件不参加计算)

假设你在做一道选择题,ABCD四个选项,你完全不会这道题,只能蒙,此时四个选项对你来说,正确的概率都是\(\cfrac{1}{4}\),此时的信息熵为:

>>> import numpy as np
>>> each = (1/4) * np.log2(4)
>>> each
0.5
>>> entropy = each * 4
>>> entropy
2.0

此时你向同学求助,小明非常自信的告诉你,一定不是A,你可以排除掉A选项,但剩下的BCD三个选项,对你来说,依然是等概率。此时你获取到了一点信息,这道题的信息熵因此减少一点点:

>>> (1/3) * np.log2(3) * 3
1.5849625007211559

A选项的概率为0,就不参加计算了。

你继续向同学求助,小花告诉你,一定不是B,你可以判处掉B选项。此时这道题的信息熵为:

>>> (1/2) * np.log2(2) * 2
1.0

最后,班上的学霸骄傲地跟你说,C肯定不对呀。此时你可以确定,这道题选D。此时这道题的信息熵为:

>>> np.log2(1)
0.0

信息熵为0,已经没有任何不确定性。

信息熵计算公式中,\(log_2 \cfrac{1}{p_i}\),代表了每个事件的信息量。

信息熵是一个概率系统的期望值。

计算文本的信息熵

设每一段文本信息,都是一个独立的“信息系统”,计算过程如下:

import numpy as np

text = """
here is random text,
what is entropy...
1234567890
11111111111111111111111111
https://cs.pynote.net
https://github.com/xinlin-z
"""

chars = list(text)
charlen = len(chars)
charset = set(chars)
freqd = {c:chars.count(c) for c in charset}

entropy = 0
for c in charset:
    p = freqd[c]/charlen
    info = np.log2(1/p)
    entropy += p * info
    if c in  ('\n',' '):
        print(hex(ord(c)), round(info,2))
    else:
        print(c, round(info,2))

print('entropy', round(entropy,2))
print('charset size', len(charset))
print('bits nedded', int(np.ceil(np.log2(len(charset)))))

运行效果:

7 7.01
: 6.01
x 6.01
t 3.55
8 7.01
b 7.01
a 6.01
z 7.01
c 6.01
3 7.01
, 7.01
e 4.43
p 5.01
9 7.01
i 4.69
5 7.01
/ 4.69
d 7.01
l 7.01
r 5.43
0xa 4.2
g 7.01
0x20 4.69
. 4.43
s 4.69
6 7.01
u 7.01
y 6.01
1 2.26
2 7.01
o 5.01
w 7.01
- 7.01
4 7.01
m 6.01
0 7.01
h 4.69
n 4.43
entropy 4.5
charset size 38
bits nedded 6

注意信息1的info值(信息量),是最小的一个信息量,因为它出现的概率(频率)相对较高。

计算图像的信息熵

设一张灰度图,我们以每个pixel为中心,划出一个正方形区域,设定这个正方形区域的(最大)边长为2N+1,然后以每一个这样的正方形区域为一个“信息系统”,计算出中心点pixel的信息熵。

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt


def point_entropy(data):
    data_len = len(data)
    dset = list(set(data))
    dset_len = len(dset)
    plist = [np.size(data[data==i])/data_len for i in dset]
    return np.sum([p*np.log2(1/p) for p in plist])


color_img = Image.open('123.jpg')
grey_img = color_img.convert('L')
color_img = np.array(color_img)
grey_img = np.array(grey_img)

N = 2
shape = grey_img.shape
entropy = np.zeros_like(grey_img, dtype=np.float32)
for row in range(shape[0]):
    for col in range(shape[1]):
        lx = np.max((0,col-N))
        ly = np.max((0,row-N))
        kx = np.min((shape[1],col+N+1))
        ky = np.min((shape[0],row+N+1))
        entropy[row,col] = point_entropy(grey_img[ly:ky,lx:kx].flatten())


plt.subplot(1,2,1)
plt.imshow(grey_img, cmap=plt.cm.gray)

plt.subplot(1,2,2)
plt.imshow(entropy, cmap=plt.cm.rainbow)
plt.colorbar()

plt.show()

找一张图片,运行效果如下:

pixel_entropy.png

N值越大,计算周期就越长。

熵越小的点,表示以这个点为中心扩展N个点,这个区域内pixel值的散乱程度越小。以上图为例,最蓝的点表示这个点周围的值都一样。N值越大,越难以出现最蓝色的点,因为这个区域所有点的值完全相同的概率越低。(homogenous regions have low entropy)

交叉熵(cross-entropy)

Cross-entropy is commonly used to quantify the difference between two probability distributions. In the context of machine learning, it is a measure of error for categorical multi-class classification problems. Usually the "true" distribution (the one that your machine learning algorithm is trying to match) is expressed in terms of a one-hot distribution.

cross-entropy用来量化两个概率分布的差异。

The cross-entropy between a true distribution \(p\) and an estimated distribution is \(q\) is defined as:

\(H(p,q)=-\sum\limits_x{p(x)\log{q(x)}}\)

上面的公式,用于多分类问题,真实的p,只有一个分类是1,其它都是0,q越接近1,loss越小。

本文链接:https://cs.pynote.net/ag/202206201/

-- EOF --

-- MORE --