首页 > 其他分享 >数据的压缩编码

数据的压缩编码

时间:2024-03-18 20:00:44浏览次数:20  
标签:编码 ell limits dfrac 压缩 数据 sum log

\(\newcommand{\E}{\mathbb{E}}\)\(\newcommand{\X}{\mathcal{X}}\)现在我们要开始讨论熵的意义,为此我们依然要回到数据的压缩编码这一核心概念上。

首先我们要严格地定义编码。在这里,我们默认是用二进制进行编码。事实上,我们将要证明的所有结论对于一般的\(\mathcal{D}\)进制而言都是成立的。在信息论中对数的底数并不重要,我们的结论并不是依赖于底数的。我们定义对随机变量\(X\)的编码就是\(\X\to \{0,1\}^*\)的映射\(C\),\(X\)的每个取值对应着一个有限01串。进一步,如果\(C\)是一个单射,也即如果任意不同的取值对应不同的01串,我们就称\(C\)是一个nonsingular(非奇异的)的编码方式。对于nonsingular的编码方式,只需要在相邻字符间加上逗号或其它分隔符,就能够通过编码后的串唯一解码出原始的字符串。但在实际应用中,使用分隔符并不是一种高效的做法。如果我们能够保证所有编码后的字符不存在其中一个串是另一个串的前缀的情况,那么我们无需分隔符就可以唯一的解码。我们称这样的编码方式为前缀码(Prefix Code)或即时码(Instantaneous Code),这样的编码方式是自带标点(Self-punctuating)的。

Kraft Inequality

当我们要求编码方式必须是前缀码时,我们就不能总是采用最短的可用字符串了。例如如果同时采用\(0\)和\(1\)作为编码,那就不可能使用任何其它串了。也就是说,对于\(|\X|=n\),如果把需要编码的字符编码后的长度排成一列\(\ell_1,\ell_2,\cdots,\ell_n\),这些长度肯定要满足某些约束。例如当\(|\X|=3\)时,\(\{1,1,2\}\)肯定不是一个可行的前缀码编码方式,而\(\{1,2,2\}\)的确是可行的。

思考编码问题的一个最常见方法就是把编码放到前缀树上去思考。在这里,前缀树是一棵二叉树。记\(\ell_{\max}\)是编码最长的字符,那么这一定是一棵深度不超过\(\ell_\max\)的树。对于前缀树而言,只有叶节点能够作为编码的终点。前缀树可以看作去除了某些子树后的满二叉树。一棵深度为\(\ell_\max\)的满二叉树,那么第\(k\)层恰好有\(2^k\)个节点,在第\(\ell_\max\)层有\(2^{\ell_\max}\)个节点。对于长度为\(\ell_i\)的编码,由于它一定没有后代,所以相较于满二叉树在第\(\ell_\max\)层会损失共\(2^{\ell_{\max}-\ell_i}\)个节点。而每个\(\ell_i\)的后代都是互不重叠的,因此在最后一层上总的损失节点数就是\(\sum\limits_{i=1}^{n}2^{\ell_\max-\ell_i}\),它一定不超过\(2^{\ell_\max}\)。这样我们就得到了不等式\(\sum\limits_{i=1}^{n}2^{-\ell_i}\leq 1\)。这称为Kraft Inequality。

而一旦我们得到了一个满足Kraft Inequality的序列\(\ell_1,\cdots,\ell_n\),那么我们可以直接在01前缀树上构造出一个合法的前缀编码。把\(\ell_1,\cdots,\ell_n\)从小到大排序,从满二叉树出发,依次找到字典序最小的深度为\(\ell_i\)的节点,移除它的后代,不断重复如上操作即可。

另一种理解Kraft Inequality的方法是二进制小数。假设第\(i\)个二进制编码记为\(y_1y_2\cdots y_{\ell_i}\),我们可以把它与二进制小数\(0.y_1y_2\cdots y_{\ell_i}\)对应。由于不存在与它有相同前缀的编码,我们可以视为这个小数独占了区间\([0.y_1y_2\cdots y_{\ell_i},0.y_1y_2\cdots y_{\ell_i}+2^{-\ell_i})\)。这恰好是一个长度为\(2^{-\ell_i}\)的区间。由于所有编码对应的区间互不重叠,一定有\(\sum\limits_{i=1}^{n}2^{\ell_i}\leq 1\)。这样我们就再一次得到了Kraft Inequality。而在这种证明中,即便编码数量是无穷(但是可数)的,这个不等式依然成立。因此,我们得到了更广义的在可数意义下的Kraft Inequality。

最优编码问题

在编码时,我们不仅要保证解码不能有歧义,还要使得编码的长度尽可能短。这里的长度指的是在统计词频后期望意义下的最短。例如在英文中e出现的概率最高,我们就希望e被编码得尽量短;q出现的概率低,我们就可以让q有相对较长的编码。设字母表的概率分布函数为\(p\),第\(i\)个字符的出现概率为\(p_i\),被编码长度为\(\ell_i\)。则我们要选取合适的\(\ell_i\)的分布,最小化\(L=\sum\limits_{i=1}^{n}p_i\ell_i\)。

由于\(\ell_i\)的分布必须满足Kraft Inequality,而一旦满足了Kraft Inequality就是一个可行的编码。因此这其实就是一个不等式约束下的凸优化问题:在约束\(\sum\limits_{i=1}^{n}2^{-\ell_i}\leq 1\)下最小化\(L=\sum\limits_{i=1}^{n}p_i\ell_i\)。对于这个问题,可以根据KKT条件直接求解。但方便起见我们先用Lagrange条件在等式取紧\(\sum\limits_{i=1}^{n}2^{-\ell_i}=1\)时求出\(L\)的最小值,再证明任何编码都不可能比这个最小值更小。

根据Lagrange乘数法,\(L(\ell,\lambda)=\sum\limits_{i=1}^{n}p_i\ell_i+\lambda\left(\sum\limits_{i=1}^{n}2^{-\ell_i}-1\right)\)。于是\(\dfrac{\part L}{\part \ell_i}=p_i-\lambda\cdot 2^{-\ell_i}\ln 2=0\)。因此\(2^{-\ell_i}=\dfrac{p_i}{\lambda\ln 2}\)是个定值。代入\(\sum\limits_{i=1}^{n}2^{-\ell_i}=1\),得到\(\dfrac{\sum p_i}{\lambda \ln 2}=1\),也即\(\lambda = \dfrac{1}{\ln 2}\)。由此解得\(2^{-\ell_i}=p_i\),也就是说第\(i\)个字符应当被编码成长度为\(\ell_i=\log_2 \dfrac{1}{p_i}\)的串。这恰好是熵的定义中出现的项。如果我们重新写出期望的编码长度的式子,恰好得到\(L=\sum\limits_{i=1}^{n}p_i\log_2\dfrac{1}{p_i}\)。这就是\(H(X)\)的定义!我们还要进一步验证任何编码方式得到的\(L\)都不可能比\(H(X)\)更小。\(L-H(X)=\sum\limits_{i=1}^{n}p_i\ell_i+\sum\limits_{i=1}^{n}p_i\log p_i\)\(=\sum\limits_{i=1}^{n}p_i\log( p_i 2^{\ell_i})\)。记\(c=\sum\limits_{j=1}^{n}2^{-\ell_i}\),\(r_i=\dfrac{2^{-\ell_i}}{c}\),则\(r_i\)构成了某个概率分布\(q\)。\(L-H(X)=\sum\limits_{i=1}^{n}p_i\log \left(\dfrac{p_i}{2^{-\ell_i}}\cdot \dfrac{c}{c}\right)=\sum\limits_{i=1}^{n}p_i\log \left(\dfrac{p_i}{2^{-\ell_i}/c}\cdot \dfrac{1}{c}\right)\)\(=\sum\limits_{i=1}^{n}p_i\log\dfrac{p_i}{r_i}-\log c\)\(=D(p||r)-\log c\)。根据Kraft Inequality,\(c\leq 1\),因此\(-\log c\geq 0\)。而根据信息不等式,相对熵\(D(p||r)\geq 0\)也成立。综上,\(L\geq H(X)\)始终成立。

所以我们看到,熵的含义就是最优编码的期望编码长度。当然,\(\ell_i=-\log p_i\)不一定是整数。这个等号只有在\(X\)的所有分布密度都是\(2\)的幂次时才能取到。一个自然的问题时,既然对于一般的分布等号总是无法取到,我们能否给出一个\(L\)的上界?(在AEP一节中我们已经给出\(H(X)+\epsilon\)作为上界,但当时并没有要求编成前缀码)下面我们证明,只需向上取整取\(\ell_i=\left\lceil-\log p_i\right\rceil\)就能得到上界\(L\leq H(X)+1\)。根据\(-\log p_i \leq \ell_i \leq -\log p_i+1\),两边同时乘以\(p_i\)得到\(-p_i\log p_i\leq p_i\ell_i\leq -\log p_i+p_i\)。累加得到\(\sum\limits_{i=1}^{n}-p_i\log p_i=\)\(H(X)\leq\)\(\sum\limits_{i=1}^{n}p_i\ell_i=L\)\(\leq \sum\limits_{i=1}^{n}-p_i\log p_i+\sum\limits_{i=1}^{n}p_i\)\(=H(X)+1\)。

标签:编码,ell,limits,dfrac,压缩,数据,sum,log
From: https://www.cnblogs.com/qixingzhi/p/18081281

相关文章

  • 数据结构(六)串,Trie字符串统计---以题为例
    维护一个字符串集合,支持两种操作:Ix 向集合中插入一个字符串 x;Qx 询问一个字符串在集合中出现了多少次。共有 N 个操作,所有输入的字符串总长度不超过 105,字符串仅包含小写英文字母。输入格式第一行包含整数 N,表示操作数。接下来 N 行,每行包含一个操作指令,指令为......
  • JAVA--数据库(增删改)
    增(INSERT)#给指定字段添加数据insertinto表名(字段1,字段2...)values(值1,值2...);给全部字段添加数据insertinto表名values(值1,值2...);批量添加数据insertinto表名(字段1,字段2...)values(值1,值2...),(值1,值2...),(值1,值2...);   insertinto......
  • 数据可视化-ECharts Html项目实战(3)
    在之前的文章中,我们学习了如何创建堆积折线图,饼图以及较难的瀑布图并更改图标标题。想了解的朋友可以查看这篇文章。同时,希望我的文章能帮助到你,如果觉得我的文章写的不错,请留下你宝贵的点赞,谢谢。数据可视化-EChartsHtml项目实战(2)-CSDN博客文章浏览阅读1.2k次,点赞33次,收藏16......
  • 搭建springboot项目,链接数据库测试,并跑通流程
    步骤>>新建项目>>修改pom.xml文件>>创建文件mvc框架>>在主文件下创建Application启动类(注解@SpringBootApplication)>>resources文件下创建application.yml文件>>在domain下创建实体类(注解@Data)>>在mapper下创建mapper类(注解@Mapper)>>在service下创建接口>>在service下创建impl并......
  • OpenAI Sora训练数据非法?&ChatGPT参数规模被扒?
    关注文章底部公众号,获取更多AI新闻资讯Sora训练数据被质疑非法训练AI模型数据所面临的巨大版权争议,是这一年多全球相关人士讨论最多的话题。近日OpenAICTOMurati接受采访时,被问及Sora训练数据来源时语焉不详、支支吾吾,已经成了全网热议的话题。女记者:「Sora是用什么数......
  • 从海外开发者大会的亲身体悟聊起,谈谈 AI 与开发者关系的重构 | 编码人声
      本期「编码人声」节目中,我们聚焦于「AI与开发者关系的重构」这一主题,从嘉宾参加海外开发者大会的亲身体验开始分享,聊一聊AI技术如何影响开发者社区和生态,以及开发者如何在这一变革中找到新的位置。 我们邀请了开发者社区与技术大会的负责人、开发者生态的从业者、以......
  • Springboot+Redis:实现缓存 减少对数据库的压力
    ......
  • MySQL忘记数据库密码,怎么连接数据库(Windows环境)
    一、Navicat连接过数据库,还有连接历史记录1.找回原密码(1)打开注册列表【win+R】-->【regedit】打开注册表 (2)查找Navicat密码保存位置,找到数据库名【数据库名称ruoyi】计算机\HKEY_CURRENT_USER\SOFTWARE\PremiumSoft\Navicat\Servers\ruoyi在右侧找到pwd属性,右键点击【修改......
  • Linux安装Mysql5.7数据库
    一、前置条件系统版本:Linux CentOS7.5MySQL版本:mysql5.7.31二、操作步骤2.1、关闭mysql服务servicemysqldstop提示使用命令:systemctlstopmysqld.service2.2、grep查找已安装的mysql服务rpm-qa|grep-imysql2.3、卸载mysql:yum-yremove命令—......
  • oracle数据库执行报错:ORA-01861: 文字与格式字符串不匹配
    报错sql:selectto_date(sysdate,'yyyy-mm-dd')afromuser原因是:to_date()函数第一个参数,要求的是一个字符串格式,当这个值是一个日期格式的时候就会报错,解决方案:方案一:使用to_char(日期,'yyyy-mm-dd')将日期转为字符,再使用to_date(),方案二:修改数据库配置,让数据库隐式......