熵的概念
信息熵的公式:,P(i)是事件发生的概率。
现在有一段英文字母:AABABCABAB,A 出现了 5 次,B 出现了 4 次,C 出现了 1 次。
则每个字母出现的概率为
P(A) = 0.5
P(B) = 0.4
P(C) = 0.1
则这段字符的信息熵为:
H=0.5*log(0.5)+0.4*log(0.4) +0.1*log(0.1)=1.361
也就是指,这段字符的压缩极限为:每个字母可以用1.361个字节表示。
算术编码
为了能让字母能够用1.361个字节去进行编码,于是提出了很多编码方法,比如哈夫曼编码,算术编码,游程编码等。
这里主要介绍算术编码的优缺点和编码过程。
算术编码的编码过程:
第一步:计算每个字符的出现概率
P(A) = 0.5
P(B) = 0.4
P(C) = 0.1
第二步:按照概率对0-1区间进行划分
A:0-0.5 B:0.5-0.9 C:0.9-1
第三步:开始对AABABCABAB进行编码,第一个字母为A。则对A区间按照第一步中的概率,重新分为3部分。区分结果如下:
A:0-0.25 B:0.25-0.45 C:0.45-0.5
第四步:编码第二个字母A。对第二步中的A 区间按照第一步中的概率,重新分为3部分:区分的结果如下:
A:[0, 0.125), B:[0.125, 0.225), C:[0.225, 0.25)
然后不断重复步骤4,遇到哪个字母,就对哪个字母按照概率进行划分,直到最后一个字母。
划分的结果如图:
最后一个字母的的概率区间为0.1686-0.1688,算术编码规定,在这个区间可以任选一个数作为最后的编码小数,这里选择0.16864013671875,因这个小数转为2进制的长度最小。
也就是我们的述求是最短压缩,于是我们要在[0.1686,0.1688)中间选择一个数,而且这个数的二进制要最短。这里我们选择的中间数为0.16864013671875,这个数的二进制为:0.0010011001011,去掉小数点左边的整数位0之后,最终的二进制编码为:0010011001011。
算术编码的解码过程
上面介绍了算术编码的编码过程,这里继续介绍算术编码的解码过程。
第一步:我们获取编码结束后的二进制编码:0010011001011,对其加上小数点和小数点左边的整数位,得到0.0010011001011,这个二进制编码对应的十进制的小数为Result:0.16864013671875。
第二步:开始解码第一个字符。首先初始区间为
A:[0, 0.5), B:[0.5, 0.9)[0.125, 0.225], C:[0.9, 1)
Result对应的区间字母为A,故解码的第一个字符为A
第三步:将A:[0,0.5)划分为3个区间
A:[0, 0.25), B:[0.25, 0.45), C:[0.45, 0.5)
Result在A:[0,0.25) 中,故第二个解码字符为A。
第4步:将A:[0,0.25)划分为3个区间
A:[0, 0.125), B:[0.125, 0.225), C:[0.225, 0.25)
Result在B:[0.125,0.225) 中,故第三个解码字符为B。
第5步:将B:[0.125,0.225)划分为3个区间
A:[0.125, 0.175), B:[0.175, 0.215), C:[0.215, 0.225)
Result在A:[0.125,0.175) 中,故第三个解码字符为A。
按照这个规则,直到解码出全部的字符。
结论:算术编码只需要一个数,就可以解码出全部的编码字符。
算术编码的压缩数据的原理
算术编码能够压缩数据的本质就是,在保留压缩字符数据顺序的同时,对于高频出现的字符,采用更大的小数区间。算术编码的最终目的就是在最后一次的小数区间中,找到一个编码二进制最短的十进制小数作为最终的编码结果,而这个最后一次的小数区间如何确定呢:
因为最终的目标小数区间的范围越大,区间中小数的精度就会越低,则最后的编码二进制的小数的编码长度就会越短。所以算术编码就是要让最后一次的目标小数空间越大越好。
所以算术编码中,出现频率越高的字符,对应的小数区间越大,出现频率越低的字符,对应的小数区间越小。在遍历完所有的要编码字符后,最后一次的目标区间相对就会越大,小数精度越低,可以选择的十进制小数对应的二进制码长也会越短。编码效率也会越高。
算术编码的优缺点:
优点:高效率和自适应编码效率
1、在知道编码数据的概率分布之后,算术编码相对于哈弗曼编码,最后编码的码长要更短,编码效率高,理论上。由于算术编码不需要为定长符号块分配整数长的码字,理论上可以达到编码定理所规定的最低限。。
2、同为不定长编码,算术编码的解码效率要比哈夫曼编码高。
3、采用自适应模型的算术编码比静态的算术模型,对实际的应用更加友好。(上面介绍的是静态算术编码,动态的算术编码就是每一次编码会更新字符的概率)
缺点:
1、算术编码是变长码,编码过程中移位和输出不均匀,所以要额外设置缓冲器
2、算术编码在误差扩散方面,比分组码更加严重,因为算术编码会累计错误。所以算术编码要高质量的信道,或者采用检错反馈机制进行重发。