读研时,常去国图听讲座,其中一场便是《数学之美》的作者吴军所做的。讲座的内容记不起了,但记了个《数学之美》。于是乎,听完讲座便从网上下载。从开始看不懂,到第一遍一气呵成,再到第二遍的理解深刻,觉得有必要总结一下了。
一、统计语言模型
最早,语言学家提出用语法分析进行文字处理,但进展缓慢;香农提出用数学的办法处理自然语言的想法,而第一个利用数学方法解决自然语言处理问题的是语音和语言处理大师贾里尼克(Fred Jelinek)。
简单的统计语言模型:利用条件概率,可以简单的计算出序列S在文本中出现的概率。
统计语言模型在很多涉及到自然语言处理的领域,如机器翻译、语音识别、印刷体或手写体识别、拼写纠错、汉字输入和文献查询中,都有广泛的应用。数学的美妙把一些复杂的问题变得如此简单,当然,要解决很多细节问题。
二、谈谈中文分词
利用统计语言模型进行自然语言处理,首先要进行分词。例如把句子 “中国航天官员应邀到美国与太空总署官员开会”分成一串词: 中国 / 航天 / 官员 / 应邀 / 到 / 美国 / 与 / 太空 / 总署 / 官员 / 开会。
最早的分词方法称为“查字典”,是由北航的梁南元教授提出。八十年代,哈工大的王晓龙博士把它理论化,发展成最少次数的分词理论,这种方法对于词的二义性无能为力。后来,不少学者试图用文法规则解决分词的二义性,不很成功。90年前后,清华大学的郭进博士成功用统计语言模型解决分词的二义性问题,将分词的错误率降低了一个数量级。其原理是:保证分完后,这个句子出现的概率最大。清华大学孙茂松教授和香港科技大学吴德凯教授利用统计的方法,进一步完善了中文分词。
一般而言,不同的应用,分词的颗粒度不同。
三、隐含马尔可夫模型在语言处理中的应用
隐含马尔可夫模型是一个数学模型,到目前为之,它一直被认为是实现快速精确的语音识别系统的最成功的方法。
当我们观测到语音信号 o1,o2,o3 时,我们要根据这组信号推测出发送的句子 s1,s2,s3。显然,我们应该在所有可能的句子中找最有可能性的一个。用数学语言来描述,就是在已知 o1,o2,o3,...的情况下,求使得条件概率P(s1,s2,s3,...|o1,o2,o3....) 达到最大值的那个句子 s1,s2,s3,...利用贝叶斯公式并且省掉一个常数项,可以把上述公式等价变换成 P(o1,o2,o3,...|s1,s2,s3....) * P(s1,s2,s3,...)。在这里做两个假设:第一,s1,s2,s3,... 是一个马尔可夫链,也就是说,si 只由 si-1 决定;第二, 第 i 时刻的接收信号 oi 只由发送信号 si 决定(又称为独立输出假设,即P(o1,o2,o3,...|s1,s2,s3....)=P(o1|s1)* P(o2|s2)*P(o3|s3)...。 这样就可以很方便的计算出上述概率的最大值,进而找出要识别的句子s1,s2,s3。
隐马尔可夫处理自然语言问题最早的成功应用是语音识别,现在也应用在机器翻译、文字识别等语言处理的子领域。
四、数学之美系列四—怎样度量信息
1948 年,香农提出了“信息熵”的概念,解决了对信息的量化度量问题。信息熵越大,说明信息的不确定性越大,其定义为:
单位是比特(bit,一个二进制位)。
五、简单之美:布尔代数和搜索引擎的索引
[建立一个搜索引擎包括下载网页、建立索引、相关性排序,这里先介绍索引问题。]
不管索引如何复杂,查找的基本操作仍然是布尔运算。布尔运算把逻辑和数学联系起来了。它的最大好处是容易实现、速度快,这对于海量的信息查找是至关重要的。
最简单的文献索引结构是用一个很长的二进制数表示一个关键字是否出现在每篇文献中,有多少篇文献,就有多少位数;对于互联网的搜索引擎来讲,每一个网页就是一个文献,网页数量和所用的词的数量非常巨大,因此这个索引是巨大的,在万亿字节这个量级;早期的搜索引擎(比如 Alta Vista 以前的所有搜索引擎),由于受计算机速度和容量的限制,只能对重要的关键的主题词建立索引;现在,为了保证对任何搜索都能提供相关的网页,所有的搜索引擎都是对所有的词进行索引,索引中还需存有大量附加信息,诸如每个词出现的位置、次数等等,因此,整个索引就变得非常之大,以至于不可能用一台计算机存下。大家普遍的做法就是根据网页的序号将索引分成很多份(Shards),分别存储在不同的服务器中。每当接受一个查询时,这个查询就被分送到许许多多服务器中,这些服务器 同时并行处理用户请求,并把结果送到主服务器进行合并处理,最后将结果返回给用户。
六、图论和网络爬虫(Web Crawlers)
回想数据结构中“图”的结构,互联网其实就是一张大图,我们可以把每一个网页当作一个节点,把那些超链接(Hyperlinks)当作连接网页的弧,而网络爬虫就是利用图的遍历算法进行自动下载网页。
在网络爬虫中,使用“哈希表”(Hash Table)记录某网页是否下载过。世界上第一个网络爬虫是由麻省理工学院 (MIT)的学生马休.格雷(Matthew Gray)在 1993年写成的。一个商业的网络爬虫需要有成千上万个服务器,并且由快速网络连接起来。
七、信息论在信息处理中的应用
信息论中三个重要的概念:信息熵、互信息和相对熵。
在“数学之美系列四—怎样度量信息” 给出了信息熵的定义和解释(对不确定性的衡量),这里介绍了信息熵的一个重要应用:衡量统计语言模型的好坏。贾里尼克从信息熵出发,定义了一个称为语言模型复杂度(Perplexity)的概念,直接衡量语言模型的好坏。
“互信息”是信息熵的引申概念,它是对两个随机事件相关性的度量。其在自然语言处理中的一个应用是:在机器翻译中,使用互信息解决词义二义性(歧义性)的难题。以Bush翻译成总统布什还是灌木丛为例,具体的解决办法大致如下:首先从文本中找出和总统布什一起出现的互信息最大的一些词,比如总统、美国、国会、华盛顿等等,再用同样的方法找出和灌木丛一起出现的互信息最大的词,比如土壤、植物、野生等等。然后比较两组词出现的频率,就得出概率最大的翻译了。这种方法最初是由吉尔(Gale),丘奇(Church)和雅让斯基(Yarowsky)提出的。这种方法用来解决翻译二义性的问题,和“二、谈谈中文分词”中提到的郭进解决分词二义性问题所用的统计语言模型方法有异曲同工之妙。
相对熵是相似性的量度,熵越小,越相似。在自然语言处理中可以用来衡量两个常用词(在语法上和语义上)是否同义,或者两篇文章的内容是否相近等等。利用相对熵,可以触及信息检索中最重要的一个概念:词频率-逆向文档频率(TF/IDF)。以后会介绍使用TF/IDF对网页排序、新闻分类等应用。
八、贾里尼克的故事和现代语言处理
介绍了自然语言处理大师弗莱德·贾里尼克的生平。对我有启发:1、要懂得自己想干嘛和能干嘛,即要有自我意识;2、有了“1”之后,跨行就有基础了,按照“3”总能成功;3、事情要按照逻辑顺序一点点突破,总能做出大成就。
九、如何确定网页和查询的相关
[建立一个搜索引擎包括下载网页、建立索引、相关性排序,这里介绍查询的相关性问题。]
将某个查询分成N个关键词,则这个查询和某个网页的相关性:
TF1*IDF1 + TF2*IDF2 +... + TFN*IDFN
其中,TF1, TF2, ..., TFN是各个关键词在某个网页中的词频;IDF1, IDF2, ..., IDFN是逆文本频率指数,在此作为权重,其定义是:
D:所有网页的数量;Dw:包含关键词w的网页数量。
TF/IDF(term frequency/inverse document frequency) 的概念被公认为信息检索中最重要的发明。信息论的学者们已经发现并指出,其实 IDF 的概念就是一个特定条件下、关键词的概率分布的交叉熵(相对熵)(Kullback-Leibler Divergence)。这样,信息检索相关性的度量,又回到了信息论。
十、有限状态机和地址识别
地址的识别和分析是本地搜索必不可少的技术,尽管有许多识别和分析地址的方法,最有效的是有限状态机。
一个有限状态机是一个特殊的有向图,其在计算机科学中早期的成功应用是在程序语言编译器的设计中。一个能运行的程序在语法上必须是没有错的,所以不需要模糊匹配。而自然语言则很随意,无法用简单的语法描述。为了解决这个问题,科学家们提出了和离散的马尔可夫链大致等效的基于概率的有限状态机。
在八十年代以前,有限状态机大都应用在特定的程序上。九十年代以后,不少科学家致力于编写通用的有限状态机程序库,最成功的是前 AT&T 实验室的三位科学家,莫瑞(Mohri)、皮瑞尔(Pereira) 和瑞利(Riley)编写的一个通用的基于概率的有限状态机 C 语言工具库。
十一、Google 阿卡47 的制造者阿米特.辛格博士
好的算法,应该向阿卡47冲锋枪那样简单、有效、可靠性好而且容易读懂(或者说易操作),而不应该是故弄玄虚。好的简单方法都接近最优化的解决方案,而且还快得多,并且很容易查错 (debug)。
而能找到这些好的简单有效的方法,不是靠直觉,更不是撞大运,而是靠深入的探索分析和丰富的研究经验,是深思熟虑去伪存真的结果。
文中以阿米特·辛格博士 (Amit Singhal)为典型人物,介绍了他的一些工作案例,说明他就是为 Google 设计阿卡 47 冲锋枪的人。
十二、余弦定理和新闻的分类
对每一篇新闻,按照其实词在词汇表的位置对它们的 TF/IDF (词频乘以逆文本频率)值排序,组成该篇新闻的特征向量。求两个特征向量的夹角余弦,即可得出对应的两篇新闻的相关性:余弦越小,越不相关。
十三、信息指纹及其应用
信息指纹,可以理解为一个函数,将任何一段信息文字,映射到一个不太长的随机数,只要算法设计的好,任何两段信息的映射值都很难重复,如同人类的指纹一样。
产生信息指纹的关键算法是伪随机数产生器算法(prng)。最早的 prng 算法是由计算机之父冯诺伊曼提出来的,是平方取中法。现在常用的 MersenneTwister 算法要更加优秀。
信息指纹在加密、信息压缩和处理中有着广泛的应用。文中介绍的两个重要的应用:互联网加密和哈希函数。互联网上加密要用基于加密伪随机数产生器(csprng)。常用的算法有 MD5 或者 SHA1 等标准,它们可以将不定长的信息变成定长的 128 二进位或者 160 二进位随机数。信息指纹作为将网页地址映射为一组定长二进制数的哈希函数,甚至可以将存储空间压缩为原来的1/6,而查找效率可以提高几倍到几十倍。
十四、谈谈数学模型的重要性
这一节是我以为本书中最有意思的一节,恨不得整节移过来。但既然是读书笔记,就要克制这种冲动。总计如下。
文中,以天文学中的地心说、日心说模型为例,说明数学模型的重要性。
地心说:
两千年前古罗马时代的托勒密,真正创立了天文学并且计算出诸多天体运行轨迹。虽然其依据的模型是和今天相悖的地心说,也已被证明是错误的模型,但我们不应该以今人的知识和经验积累评价古人取得的成果。在当时,从人们的观测出发,很容易得到地球是宇宙中心的结论。托勒密用四十个小圆套大圆的方法,精确地计算出了所有行星运动的轨迹,其精度之高,让以后所有的科学家惊叹不已。
日心说:
哥白尼发现,如果以日心说为数学模型,只需要8-10个圆,就能计算出行星的运动轨迹。很遗憾的是,哥白尼的模型的误差比托勒密的要大不少,这是其被认为是邪说的一个原因。
开普勒从他的老师第谷手中继承了大量的、在当时最精确的观测数据,很幸运地发现了行星围绕太阳运转的轨道实际是椭圆形的。后来,牛顿用万有引力解释了这个问题。
这节选自吴军的一个讲座,讲座结束前,他和 Google 中国的工程师们做了以下四点总结:
1. 一个正确的数学模型应当在形式上是简单的。(托勒密的模型显然太复杂。)
2. 一个正确的模型在它开始的时候可能还不如一个精雕细琢过的错误的模型来的准确,但是,如果我们认定大方向是对的,就应该坚持下去。(日心说开始并没有地心说准确。)
3. 大量准确的数据对研发很重要。
4. 正确的模型也可能受噪音干扰,而显得不准确;这时我们不应该用一种凑合的修正方法来弥补它,而是要找到噪音的根源,这也许能通往重大发现。
十五、繁与简—自然语言处理的几位精英
一般来说,一个好的方法或数学模型是简单的。但是,也有一些特例。本文以柯林斯为例,说明繁琐美:麦克尔·柯林斯总是将问题研究到极致,执著追求完美,取得了重大科研成果。又以布莱尔为例,介绍了简单美:布莱尔总是试图寻找最简单的方法,在很多自然语言研究领域,得到了几乎最好的结果。并且,这样做的好处,当转向其他的研究方向时,不会因之前的工作而受累赘。
十六、不要把所有的鸡蛋放在一个篮子里—最大熵模型(上)
最大熵原理指出,当我们需要对一个随机事件的概率分布进行预测时,应当满足全部已知的条件,而对未知的情况不要做任何主观假设。犹如统计中假设检验对H0原假设的设定,倾向于保护已有的条件。
匈牙利著名数学家、信息论最高奖香农奖得主希萨(Csiszar)证明了对任何一组不自相矛盾的信息,最大熵模型存在且唯一,它们都有同一个非常简单的形式 -- 指数函数。
举例:下面公式是根据上下文(前两个词)和主题预测下一个词的最大熵模型,其中w3是要预测的词(王晓波或王小波)w1和w2 是它的前两个字(比如说它们分别是“出版”,和“”),也就是其上下文的一个大致估计,subject 表示主题。
在上面的公式中,有几个参数λ和 Z需要通过观测数据训练出来。最大熵模型在形式上是最漂亮的,而在实现上是最复杂的之一。
十六、不要把所有的鸡蛋放在一个篮子里—最大熵模型(下)
这一节讲的是最大熵模型的训练和应用。
最原始的训练方法是通用迭代算法GIS(generalized iterative scaling)。GIS 算法消耗时间长,而且不稳定,很少有人真正使用GIS。
八十年代,达拉皮垂提出了改进迭代算法IIS(improved iterative scaling)。这使得最大熵模型的训练时间缩短了一到两个数量级,这样最大熵模型才有可能变得实用。第一个在实际信息处理应用中验证了最大熵模型优势的,是宾夕法尼亚大学马库斯的另一个高徒原 IBM 现微软的研究员拉纳帕提(Adwait Ratnaparkhi)。拉纳帕提用最大熵模型做的词性标注系统,至今仍然是使用单一方法最好的系统。
本书作者吴军曾使用一种数学变换方法,可以将大部分最大熵模型的训练时间在 IIS 的基础上减少两个数量级。
最大熵模型快速算法的实现很复杂,到今天为止,世界上能有效实现这些算法的人也不到一百人。最大熵模型,可以说是集简与繁于一体:形式简单,实现复杂。
信息处理的很多数学手段,最大熵模型、隐含马尔可夫模型、子波变换、贝叶斯网络等等,在华尔街有很多直接的应用。
十七、闪光的不一定是金子—谈谈搜索引擎作弊问题(Search Engine Anti-SPAM)
早期最常见的作弊方法是重复关键词。在有了网页排名(page rank)以后,有了多链接法。现在,作弊的方法层出不穷。
抓作弊的方法很像信号处理中的去噪音的办法。
在图中,原始的信号混入了噪音,在数学上相当于两个信号做卷积。噪音消除的过程是一个解卷积的过程。这在信号处理中并不是什么难题。因为,从广义上讲,只要噪音不是完全随机的、并且前后有相关性,就可以检测到并且消除。
搜索引擎的作弊者所作的事,就如同在手机信号中加入了噪音,使得搜索结果的排名完全乱了。但是,作弊者的方法不可能是随机的,所有这种人为加入的噪音并不难消除。
十八、矩阵运算和文本处理中的分类问题
自然语言处理中,最常见的两类的分类问题是:主题归类和词义归类。在“余弦定理和新闻的分类”一节中提到过用特征向量的夹角余弦来评判两篇新闻的相关性。从原理上,该方法也可以用在上述两种分类,但计算量巨大,无法实际应用。
利用矩阵运算中的奇异值分解(Singular Value Decomposition,简称SVD) 可以同时圆满地解决上述两种分类。首先,可以用一个大矩A来描述一百万篇文章和五十万词的关联性。这个矩阵中,每一行对应一篇文章,每一列对应一个词。
在上面的图中,M=1 000 000,N=500 000。第i行,第j列的元素,是字典中第j个词在第i篇文章中出现的加权词频(比如,TF/IDF)。这个矩阵非常大,有一百万乘以五十万,即五千亿个元素。奇异值分解就是把上面这样一个大矩阵,分解成三个小矩阵相乘,如下图所示:分解成一个一百万乘以一百的矩阵X,一个一百乘以一百的矩阵B,和一个一百乘以五十万的矩阵Y。这三个矩阵的元素总数加起来也不过 1.5 亿,仅仅是原来的三千分之一。相应的存储量和计算量都会小三个数量级以上。
三个矩阵有非常清楚的物理含义。第一个矩阵X中的每一行表示意思相关的一类词,其中的每个非零元素表示这类词中每个词的重要性(或者说相关性),数值越大越相关。最后一个矩阵Y中的每一列表示同一主题一类文章,其中每个元素表示这类文章中每篇文章的相关性。中间的矩阵则表示词类和文章类之间的相关性。因此,只要对关联矩阵A进行一次奇异值分解,就可以同时完成了近义词分类和文章的分类。(同时得到每类文章和每类词的相关性)。
Google 中国的张智威博士和几个中国的工程师及实习生已经实现了奇异值分解的并行算法。
十九、马尔可夫链的扩展—贝叶斯网络(Bayesian Networks)
在前面的系列中多次提到马尔可夫链(MarkovChain),它描述了一种状态序列。在现实生活中,很多事物相互的关系可能是交叉的、错综复杂的,不能用一条链来串起来,而要用有向图来表示。下图描述了心血管疾病和其成因之间的关系。
上图中,圆圈表示状态,弧表示状态之间的关系,每一个关系都有一个概率描述的可信度(belief)。通过这样一张网络,可以估计出患心血管疾病的可能性。其中,每个节点概率的计算,可以用贝叶斯公式来进行,因此称之为贝叶斯网络,贝叶斯网络也被称作信念网络(belief networks)。
使用贝叶斯网络必须通过训练知道各个状态之间相关的概率。从理论上讲,其训练的复杂程度对于现在的计算机是不可计算的。对于某些应用,可以简化并在计算上实现。
IBM Watson 研究所的茨威格博士(Geoffrey Zweig) 和西雅图华盛顿大学的比尔默(Jeff Bilmes) 教授完成了一个通用的贝叶斯网络的工具包,提供给对贝叶斯网络有兴趣的研究者。
贝叶斯网络在图像处理、文字处理、支持决策等方面有很多应用。在文字处理方面,语义相近的词之间的关系可以用一个贝叶斯网络来描述。利用贝叶斯网络,可以找出近义词和相关的词,在Google 搜索和Google 广告中都有直接的应用。
二十、自然语言处理的教父—马库斯
介绍了马库斯对自然语言处理领域的主要贡献:建立了LDC语料库,包含一系列标准的语料库,是当今世界自然语言处理的所有学者都使用的工具。其中最著名的是 PennTree Bank 的语料库,覆盖多种语言(包括中文),对每一种语言都有几十万到几百万字的有代表性的句子,每个句子都有的词性标注,语法分析树等等。如今,在自然语言处理方面发表论文,几乎都要提供基于 LDC 语料库的测试结果。
马库斯不仅在自然科学领域,而且对整个计算机科学的发展,都有独到的见解。
二十一、布隆过滤器(Bloom Filter)
工作和生活中,经常要判断一个元素是否在一个集合中。计算机中,一般用哈希表来存储,查找准确而快速,但其比较占用存储空间(哈希表的存储效率一般只有 50%)。
而布隆过滤器只需要哈希表 1/8 到 1/4 的大小就能解决同样的问题。举例:假定我们存储一亿个电子邮件地址,我们先建立一个十六亿二进制(比特),即两亿字节的向量,然后将这十六亿个二进制全部设置为零。对于每一个电子邮件地址 X,我们用八个不同的随机数产生器(F1,F2, ...,F8)产生八个信息指纹(f1, f2, ..., f8)。再用一个随机数产生器 G 把这八个信息指纹映射到1到十六亿中的八个自然数g1, g2, ...,g8,把这八个位置的二进制全部设置为1。(见下图)
检测一个可疑的电子邮件地址 Y 是否在黑名单中:用相同的八个随机数产生器(F1, F2, ..., F8)对这个地址产生八个信息指纹 s1,s2,...,s8,如果 Y 在黑名单中,这八个指纹对应到布隆过滤器的八个二进制位一定是1。
布隆过滤器的好处在于快速,省空间。但是有一定的误识别率。常见的补救办法是在建立一个小的白名单,存储那些可能别误判的邮件地址。
我的看法,查找分三个台阶:第一台阶,存储所有原始数据,直接比对,这种占用了大量的空间和时间;第二台阶,用哈希表快速检索,但因需要存储哈希函数的映射值,且存储效率低,需要占用大量空间;第三台阶,使用布隆过滤器,可以理解为特殊的哈希函数,特殊之处在于映射值交叉共享存储空间,所以又快又准。
二十二、谈谈密码学的数学原理
根据信息论,密码的最高境界是使得敌人在截获密码后,对我方的所知没有任何增加,用信息论的专业术语讲,就是信息量没有增加。一般来讲,当密码之间分布均匀并且统计独立时,提供的信息最少。分布均匀使得敌人无从统计,而统计独立能保证敌人即使看到一段密码和明码后,不能破译另一段密码。文中还介绍了RSA公钥加密的算法。
二十三、输入一个汉字需要敲多少个键—谈谈香农第一定律
假定常用的汉字在二级国标里面,假定每一个汉字的频率是p1, p2, p3, ..., p6700,它们编码的长度是L1, L2, L3, ..., L6700,那么,平均编码长度是Lav=p1×L1 + p2×L2 + ... + p6700×L6700。
香农第一定律指出(以汉字为例):汉字平均编码长度的最小值是汉字信息熵决定的。也就是说任何输入法不可能突破信息熵给定的极限。汉字信息熵如下:
H = -p1 * log p1 - ... - p6700 log p6700
如果我们假定输入法只能用26个字母输入,那么每个字母可以代表 log26=4.7比特的信息。这样:
1、如果以字为单位统计,不考虑上下文相关性,汉字的信息熵在十比特以内,输入一个汉字平均需要敲 10/4.7= 2.1 次键。
2、如果以词为单位统计,不考虑上下文相关性,汉字的信息熵大约是8比特左右,输入一个汉字平均只需要敲 8/4.7=1.7 次键。这就是现在所有输入法都是基于词输入的内在原因。
3、如果再考虑上下文的相关性,对汉语建立一个基于词的统计语言模型,可以将汉字的信息熵降到6比特左右,这时,输入一个汉字只要敲 6/4.7=1.3 次键。
而事实上,很难达到第3种的输入效率,因为有如下两个难点:
1、特殊编码。需要对汉语词组特殊编码,这样会使得用户很难学或不接受(用拼音编码就能输,干嘛要学你的编码),并且学会后用着也不方便(一心无二用,一边想着要输入的内容,一边想着如何编码是很痛苦的);
2、统计语言模型占用较大内存。这个理论最小值是根据很多统计语言模型计算出来的,在产品中又不可能占用用户太多内存(没人愿意为了运行输入法而使内存球飙红),所以有的输入法提供的是压缩很厉害的统计模型,而另外一些,干脆就没有统计模型。