• 【数据压缩】Huffman编码


    1. 压缩编码概述

    数据压缩在日常生活极为常见,平常所用到jpg、mp3均采用数据压缩(采用Huffman编码)以减少占用空间。编码(C)是指从字符空间(A)到码字表(X)的映射。数据压缩编码指编码后信息的长度较于原始信息要短。本文试图探讨Huffman编码是如何保证唯一可译性、如何压缩、以及压缩效率如何?

    前缀码

    前缀码的任意一码字均不为其他码字的前缀,此保证了编码的唯一可译性。比如码字表{0, 01, 11, 1}001的前缀,111的前缀;当遇到字符文本011100,是应分隔为01-11-0-0还是0-11-1-0-0等?若采用前缀码编码,码字表为{0, 10, 11},则字符文本011100可即时分隔为0-11-10-0可译,所以前缀码亦被称为即时码。同时,前缀码保证了编码的唯一可译性,即字符空间(A)到码字表(X)的映射为一一映射。本文探讨的Huffman编码即为前缀码。

    根据码字长度,编码分为等长编码与变长编码。等长编码即字母表中所有码字的长度均相等,最为常见的是字长7位的ASCII码。变长编码则是码字的长度可能存在不相等。

    前缀码可表示为叶子节点为码字的编码二叉树,如图所示。

    期望编码长度

    如上图所示的两种变长编码,哪一种编码压缩效率比较好?显然,若信息编码之后的长度越小,则编码的压缩效率越好。为此,我们引出刻画量度期望编码长度

    首先我们定义字符空间(A = lbrace a_1,a_2, cdots ,a_n brace),即信息文本中有n个字符,且字符(a_i)的长度为(l_i),出现频率(即概率)为(p_i);则期望编码长度为

    [L = sumlimits_{i = 1}^n {p_i*l_i} ]

    若要期望编码长度(L)越小,学过数学的都知道,则高概率的码字字长应不长于低概率的码字字长,即满足

    [forall i,j p_i ge p_j Leftrightarrow l_i le l_j ]

    最优编码

    对于二元编码(01)的前缀码,满足McMillan-Kraft不等式

    [sumlimits_{i = 1}^n {{2^{ - l_i}}} le 1 ]

    具体的证明参看[3]。McMillan-Kraft不等式从整体上限制编码长度的下界。

    如下图所示的前缀码即满足McMillan-Kraft不等式。

    最优编码指期望编码长度最小的编码,求解最优编码等价于数学问题:

    egin{align}
    & min sumlimits_{i = 1}^n {{p_i}*{l_i}} cr
    & s.t. sum {{2^{ - {l_i}}}} le 1 label{eq:kraft}
    end{align}

    运用拉格朗日乘子法,构造目标函数
    egin{equation}
    J = sum {p_i*l_i + lambda (sum {{2^{ - l_i}}} } )
    end{equation}

    (l_i)求偏导,

    [{{partial J} over {partial l_i}} = p_i - lambda {2^{ - l_i}}ln 2 ]

    令偏导为0,得到

    [{2^{ - l_i}} = {{p_i} over {lambda ln 2}} ]

    将其代入McMillan-Kraft不等式eqref{eq:kraft}中,得到(lambda = {1 over {ln 2}}),最优编码的码字长度
    egin{equation}
    l_i = - log _{2}p_i
    end{equation}

    最优编码的期望码字长度即为字符空间的熵:
    egin{equation}
    sumlimits_{i} {p_il_i = - sumlimits_{i} {p_i log p_i} } = H(A)
    end{equation}

    由此,定义编码的冗余度(Redundancy of a code),表示编码的冗余描述:
    egin{equation}
    ho = L - H(A)
    end{equation}

    可以证明,前缀码的编码长度满足不等式
    egin{equation}
    H(A) le L le H(A) + 1
    end{equation}

    因此,前缀码的冗余度满足(0 le ho le 1)

    2. Huffman编码

    Huffman编码采用小顶堆来优化编码二叉树的建立过程,确保低概率的码字字长不短于高概率的码字,具体编码过程如下:

    1. 将字符空间的字符以概率为关键值建立小顶堆;
    2. 依次取堆顶元素两次,将该两个字符合成一棵二叉树,根节点的关键值为两个字符的概率相加;然后将该新合成的二叉树做为节点插入到小顶堆中;
    3. 重复步骤2直至小顶堆中只有一个节点,此节点即为编码二叉树。

    编码二叉树建立过程如图所示

    此字符空间有9个字符,采用等长编码则需要(4) bit;Huffman编码的期望字长则为(2.77) bit;字符空间的熵为(2.69) bit;冗余度为(2.77-2.69=0.08) bit.

    Python 3.6实现Huffman编码,代码参考了rosettacode

    # -*- coding: utf-8 -*-
    # @Time    : 2017/1/21
    # @Author  : rain
    from collections import Counter
    from heapq import heapify, heappop, heappush
    
    
    def huffman_coding(message):
        freq = Counter(message)  # counter for every character
        min_heap = [[cnt, [ch, '']] for ch, cnt in freq.items()]
        heapify(min_heap)
        while len(min_heap) > 1:
            low1 = heappop(min_heap)
            low2 = heappop(min_heap)
            for pair in low1[1:]:  # update children node
                pair[1] += '0'
            for pair in low2[1:]:  # update children node
                pair[1] += '1'
            # push [low1_cnt+low2_cnt, low1's children, low2's children]
            heappush(min_heap, [low1[0] + low2[0]] + low1[1:] + low2[1:])
        vocabulary = {pair[0]: pair[1] for pair in min_heap[0][1:]}  # text -> code
        return vocabulary
    
    sentence = 'this is an example for huffman encoding'
    print(huffman_coding(sentence))
    

    上述实现中,并没有直接构建二叉树,而是用到了一个小技巧——在小顶堆中循环编码。Huffman编码存在一个缺点:解码端要根据码字与编码之间的映射关系才能解码,即解码端与编码端应共享一棵Huffman编码树。

    3. 参考资料

    [1] Huffman, David A. "A method for the construction of minimum-redundancy codes." Proceedings of the IRE 40.9 (1952): 1098-1101.
    [2] Cover, Thomas M., and Joy A. Thomas. Elements of information theory. John Wiley & Sons, 2012.
    [3] Bernd Girod, EE398A Image and Video Compression.

  • 相关阅读:
    SQL Server 限制IP登陆
    提高MSSQL数据库读取速度,降低CPU损耗
    Windows Azure 平台开发基础系列视频
    AutoFac使用方法总结:Part III
    Python学习笔记 01 快速入门
    黑苹果~~
    Python学习笔记 02 Python基础
    Python学习笔记 04 数字
    Python学习笔记 03 Python对象
    Gridview导出excel范例
  • 原文地址:https://www.cnblogs.com/en-heng/p/4980055.html
Copyright © 2020-2023  润新知