信息论概论、数据压缩、编码

信息论概论,数据压缩,编码

数据压缩:信息的有效编码

在许多压缩方法中,输入符号被映射到码字(bit sequences)。该码字集称为编码(code)。如果所有码字的长度相等,则称其为定长的编码;否则,为可变长度的编码。最重要的代码是前缀编码,即其中没有编码字是另一个编码字的前缀的编码。
如果将码字映射到二进制树(0对应于左边缘,1对应于右边缘),则可以将前缀编码中的每个符号与唯一的叶子相关联。值得注意的是,压缩(编码的)序列可以通过重复下降到树上直到到达叶子而被解码以产生输入。

信息论

信息理论是对信息以及如何处理和传达信息的研究。人们通常将香农于1948年10月发表于《贝尔系统技术学报》上的论文《A Mathematical Theory of Communication》(通信的数学理论)作为现代信息论研究的开端。
本文主要对信息沟通方面进行理论与现实情况下的探讨,并基于

Introduction to Information Theory, Data Compression, Coding Mehdi Ibm Brahim, Laura Minkova April 15, 2018

一文的理论成果进行相应的总结概括,方便一起学习信息论的小白同学一起进步,也方便我日后查找积累。理论与现实情况两者之间的最大区别在于,在现实生活中,经常会出现噪音,干扰到信息的传输方式,出于概论学习与研究我们考虑不存在噪声的通信系统。
无噪音通信系统

香农的理论

克劳德·香农(Claude Shannon)开发了描述通讯系统基本方面的数学理论。它涉及利用概率论建立和研究数学模型。香农假定对于每一个可能的输入语句,都有一个对应的概率 p i p_i pi, p i p_i pi的和为1,这些我们会在接下来的熵内容中进行介绍。
香农最关注的问题是怎样进行信息传输而不是什么是信息传输。但是他的确也指出,在压缩数据时的效率同样取决于输入的内容。话虽如此,它却依旧认为这些无关紧要(’’…these semantic aspects of communication are irrelevant to the engineering problem")。

压缩比率C定义为
C = n u m b e r o f s y m b o l s i n o u t p u t n u m b e r o f s y m b o l s i n i n p u t C = \frac{number of symbols in output}{number of symbols in input} C=numberofsymbolsininputnumberofsymbolsinoutput
为了确定输出序列的预期长度,Shannon考虑了所有可能的输入.他假设可能需要压缩的每个输入序列都具有给定的概率pi,其中pi的总和为1。如果给第i个输入提供了一些长度为li位的编码,则输出位序列的预期长度w为
w = ∑ i n p i ∗ l i w = \sum_{i}^{n}{p_i*l_i} w=inpili

二叉树被证明在表示信息编码中非常有用。该树的内部节点将没有值,但是每个叶将代表一个可能的输入。每个左边缘用0表示,每个右边缘用1表示。
二叉树
也就是AABA 000,BAAA 001,ABAB 01,ABAA 1

Entropy(熵)

在信息论中,熵是衡量随机变量中信息量的量。因此,熵为任何可能编码的效率提供了理论上的限制(有时是无法优化到下限的)。
二进制熵定义如下:
ε = ∑ i n p i log ⁡ 2 1 p i \varepsilon = \sum_{i}^{n}{p_i\log_2{\frac{1}{p_i}}} ε=inpilog2pi1

p i p_i pi是不同输入序列的概率。
香农面临三个问题:

  • 1 找到一个使预期长度最小的二叉树(David Huffman解决)
  • 2 证明 E ≤ m i n ∑ i p i l i E≤min\sum_{i}{p_il_i} Eminipili即最短预期长度均大于Entropy
  • 3 对于某些二叉树,证明 E ≤ m i n ∑ i p i l i + 1 E≤min\sum_{i}{p_il_i}+1 Eminipili+1

我们将首先证明 E ≤ m i n ∑ i p i l i E≤min\sum_{i}{p_il_i} Eminipili:
证明如下:
依据卡夫不等式:
∑ 1 2 l i ≤ 1 \sum\frac{1}{2^{l_i}}\leq1 2li11
它对所有二叉树均有效。
依据泰勒展开式易知
l o g e x ≤ x − 1 log_{e}{x}\leq{x-1} logexx1

∑ i p i l i = ∑ i p i log ⁡ 2 2 l i = ∑ i p i log ⁡ 2 2 l i p i 1 p i = ∑ i p i log ⁡ 2 1 p i + ∑ i p i log ⁡ 2 ( p i 2 l i ) = ε − ( log ⁡ 2 e ) ∑ i p i log ⁡ e 1 p i 2 l i ≥ ε − ( log ⁡ 2 e ) ∑ i p i ( 1 p i 2 l i − 1 ) = ε \begin{aligned} \sum_{i}{p_il_i}&=\sum_{i}{p_i\log_{2}{2^{l_i}}}\\ &=\sum_{i}{p_i\log_{2}{2^{l_i}p_i\frac{1}{p_i}}}\\ &=\sum_{i}{p_i\log_{2}{\frac{1}{p_i}}}+\sum_{i}{p_i\log_{2}{({p_i}2^{l_i})}}\\ &=\varepsilon-(\log_{2}{e})\sum_{i}{p_i\log_{e}{\frac{1}{p_i2^{l_i}}}}\\ &\geq\varepsilon-(\log_{2}{e})\sum_{i}{p_i(\frac{1}{p_i2^{l_i}}-1)}\\ &=\varepsilon \end{aligned} ipili=ipilog22li=ipilog22lipipi1=ipilog2pi1+ipilog2(pi2li)=ε(log2e)ipilogepi2li1ε(log2e)ipi(pi2li11)=ε
我们已经成功证明结论2,现在我们继续证明结论3
令 l i = [ log ⁡ 2 1 p i ] 则 ∑ i 1 2 l i ≤ ∑ i 1 2 log ⁡ 2 1 p i ≤ ∑ p i ≤ 1 令l_i=[\log_{2}{\frac{1}{p_i}}]\\ 则\sum_{i}\frac{1}{2^{l_i}}\leq\sum_{i}\frac{1}{2^{\log_{2}{\frac{1}{p_i}}}}\leq\sum{p_i}\leq1 li=[log2pi1]i2li1i2log2pi11pi1

因此,依据卡夫的不等式,通过将长度li从小到大排序,并将li的叶子从左到右分配给二叉树中的叶子,可以找到具有给定li的编码。此编码称为Shannon-Fano code。
进而:
∑ i p i l i ≤ ∑ i p i ( 1 − log ⁡ 2 p i ) = ε + 1 \sum_{i}{p_il_i}\leq\sum_{i}{p_i(1-\log_{2}{p_i}})=\varepsilon+1 ipiliipi(1log2pi)=ε+1
结论3证毕。
例题:一串二进制文件,每个字节1出现概率为三分之一,其余为0。
问:二进制文件的熵
熵的求解代码:python

from scipy.special import comb
import math


def pi(k, n):
    return math.pow(1 / 3, k) * math.pow(2 / 3, n - k)
def fun(n):
    frst = 0
    for i in range(1, n + 1):
        frst = frst + pi(i, n) * comb(n, i) * math.log(1 / pi(i, n), 2)
    return frst

实践压缩的问题

在实践中,我们在压缩时压缩成不同的符号,在接收方面存在着分离这些符号的问题。在一堆压缩后的字符中,我们如何去将他们分离开来呢?事实上,当我们发送一串压缩后的编码字符串,即一些“编码组”的串联,接收方可能无法正确对该字符串进行划分,来对每个字符串进行正确的解码。

Example

假设我们想发一串数字,如18 23,他们的标准二进制位10010和10111,那么如果我们发送以穿1001010111,意义是不大的。他们从何处开始又从何处结束?我们无法判断。于是我们考虑到,二进制数总是以1开头的,因而我们给他们加前缀,比如00,并在接下来接上代码的字节长,比如5(101),那么这串数字可以理解为(00101)10010(00101)10111。抑或是,我们使用前缀代码,比如我们连续5个0、或是更多作为前缀编码,这个编码出现的概率极低,那么可以表示为(00000)10010(00000)10111,然而这种做法显然是低效、且极为不方便的。

解决方案

固定编码

固定宽度编码,例如以每个字符标准的8位编码,提供了另一种解决方案,具有极大的提升空间。一个关于这种改进最著名的例子是(可变宽度)前缀编码。码字将一个位序列分配给一个符号。编码是一组编码集,我们将一段编码构造成一个TRIE,每个前缀有其特殊符号,便很好的解决了分割编码的问题。

TRIES

TRIE(发音为“ try”)是一种基于树的数据结构以支持快速模式匹配的存储字符串方式。TRIE的主要应用是信息检索,所以显然,名称“ trie”来自“ retrieval”一词。在二进TRIE种,每个边沿代表一个码字中的一个比特,左边孩子的边缘代表“0”,右边孩子的边缘
代表“ 1”。每个叶子都与一个特定字符相关联。
trie树的使用为我们编码器和解码器开发提供了策略。可以先搜索一个字符,记录路径时回归根节点。
解码其实并不需要trie,它只需要执行从叶子节点回溯到根节点的过程,但通常为了效率我们一般将trie与编码结果一起发送。

前缀编码

前缀编码需要一个关于前缀的树,这个树用一些特殊方式来记录不同的前缀符号,在加密时或是用字母表或是树的父节点来完成加密。只要有了这棵关于前缀的树,任何人都可以轻松地完成编码解码。这里简单谈一下。

定义

前缀编码是一种编码系统,他们由编码前缀部分进行区分。

例子

某个trie的字符为a,b,c,d,e,每个字符有个前缀,我们不妨假设前缀为P:
P = a:00,b:01,c:10,d:110,e:111.
我们清楚地看到P是有效的前缀代码,因为P种没有哪个二进制序列是另一个的前缀。
在这里插入图片描述
在这里,abbba被翻译成0001010100,这串字符根据P可以轻松翻译出abbba,换句话说,解决了分割问题。

哈夫曼树

霍夫曼树是将 ∑ i p i l i \sum_{i}{p_il_i} ipili最小化的二叉树,其中 p i p_i pi是叶子i的权重, l i l_i li是从叶子i到根的距离。它具有以下属性:

  1. p i p_i pi值最小的两个输入距根最远。
  2. 每个内部节点都有2个子节点。
  3. p i p_i pi值最小的两个输入可以安全地成为同级。
  • 重要的是要注意,哈夫曼树不是唯一的!

Hu-Tucker算法是一种贪婪算法,旨在在给定一组输入及其pi的情况下输出霍夫曼树。它具有时间复杂度O(nlogn),出于本文主要介绍的目的,这里只简单介绍,有兴趣的朋友可以自行搜索哈夫曼有关知识技术。

  • 设置:
    将PQ设为一个二进制堆,其中包含对 ( i , p i ) (i,p_i) ipi,其对根附近的密钥 p i pi pi最小。假设有n个叶子,我们可以在总大小为2n-1的数组中保留n-1个间隔节点。让我们使用left [i]和right [i]表示节点i的子代。节点1是根。
    伪代码如下:
1 	MAKENULL(PQ) 
2 	for i = n to 2n−1 do 
3 		left[i]=right[i]= nil; 
4 		INSERT((i,pi),PQ); 
5	for i = n down to 1 do 
6 		(a,pa) = DELETEMIN(PQ); 
7 		(b,pb) = DELETEMIN(PQ); 
8 		left[i]= a; 
9 		right[i]= b; 
10 		INSERT((i,(pa + pb)),PQ);
  • 哈夫曼编码的例子:
    哈夫曼树构建过程

现在,我们将展示不同的编码方法,并比较它们与Shannon的下限的比较。
假设我们的输入是 x 1 , x 2 , . . . , x n x_1,x_2,...,x_n x1x2...xn,其中 x i x_i xi是[1,2,3]中的等概率随机元素。
因此,存在 3 n 3^n 3n个同样可能的长度为n的输入序列。
ε = log ⁡ 2 3 n = n log ⁡ 2 3 = 1.57 n \varepsilon = \log_{2}{3^n} =n\log_{2}{3} = 1.57n εlog23nnlog23=1.57n

  • 固定宽度长度
    我们使用固定宽度代码在每个输入符号中使用两位: 1 → 01 , 2 → 10 , 3 → 11 1→01,2→10,3→11 101,210,311
    因此输出的长度为2n,这不是最佳的,有更小的预期输出长度的空间。
  • 哈夫曼树法:
    考虑霍夫曼代码,其中使用霍夫曼树前缀编码逐个符号对符号进行编码:
    1 → 0 , 2 → 10 , 3 → 11 1→0,2→10,3→11 10,210,311.
    预期长度为 ∑ i p i l i = 1 3 ( 1 ) + 1 3 ( 2 ) + 1 3 ( 3 ) = 5 3 \sum_{i}{p_il_i}=\frac{1}{3}(1)+\frac{1}{3}(2)+\frac{1}{3}(3)=\frac{5}{3} ipili=31(1)+31(2)+31(3)=35
    因此,预期输出长度为 5 3 n \frac{5}{3}n 35n,远大于E≈1.57n。
    现在,让我们将固定长度d: d的每组是由霍夫曼码编码的输入符号
    预期的输出长度(以位数为单位)
    将是一组霍夫曼树代码的预期长度的 n d 倍 \frac{n}{d}倍 dn
    我们知道 w ≤ 1 + log ⁡ 2 3 d w\leq1+\log_{2}{3^d} w1+log23d
    所以总长 w ≤ n d [ log ⁡ 2 3 d ] ≤ n d [ 1 + d log ⁡ 2 3 ] = n ( log ⁡ 2 3 + 1 d ) w\leq\frac{n}{d}[\log_{2}{3^d}]\leq\frac{n}{d}[1+d\log_{2}{3}]=n(\log_{2}{3}+\frac{1}{d}) wdn[log23d]dn[1+dlog23]=n(log23+d1)
    最后,通过选择足够大的d,我们可以任意接近E。
    但是,我们不能将d设置得太大,因为计算霍夫曼代码将需要太多空间
    因为霍夫曼树上有 3 d 3^d 3d叶子。

总结

希望上文的论述,能够帮助你解决相应的数据压缩的编码解码问题,欢迎大家关注收藏。

相关文献

[1] Charles E. Leiserson, Thomas H. Cormen, and Ronald L. Rivest. Introduction to Algorithms. Cambridge, MA, 2009.
[2] Claude E. Shannon. A mathematical theory of communication. The Bell System Technical Journal, 1948.
[3] Inrene Woo Adel Magra, Emma Goune. Information theory. http://luc.devroye.org/Magra-Goune-Woo–Shannon+ InformationTheory-LectureNotes-McGillUniversity-2017.pdf, March 2017. Accessed on 2018-03-20.
[4] George Markowsky. Information theory. https://www. [5]britannica.com/science/information-theory, June 2017. Accessed on 2018-03-11.
Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest.
Introduction to Algorithms. 2009. Cambridge, MA.
[6]Claude E. Shannon. A mathematical theory of communication. The
Bell System Technical Journal, 27:379–423, 623–656, 1948.
[7]Joy A. Thomas and Thomas M. Cover. Elements of Information Theory.
Wiley Series, 2nd edition, 2006. New York.

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值