近期准备整理一下自然语言处理方面用到的技术,之前工作都是按照工作需求来走,对用到的技术算法也没有做一下系统性的整体,所以近期准备系统性的整理一下自然语言处理相关的内容。初步构想涉及 6 个方面的问题。
文本相似度的计算
文本关键词提取
文本分类
情感分析
文本主题提取
命名实体识别
常用的文本相似度的计算方式主要分为基于字符串的与基于语料库的方式。本篇先来讨论一下常用的基于字符串的相似度计算方法。
基于字符串的文本相似度计算方法如下:该方法从字符串匹配的角度出发,以字符串共现和重复程度为相似度衡量的标准。根据计算细粒度不同,可以将方法分为基于字符的方法和基于词语的方法。一类方法单纯从字符串或词语的组成考虑相似度算法,如编辑距离,汉明距离,余弦相似度,Dice 系数,欧式距离;另一类方法还加入了字符串顺序,即字符组成和字符顺序相同是字符串相似的必要条件,如最长公共子串,Jaro-Winkler, 再一类方法是采用集合的思想,将字符串看作由词语构成的集合,词语共现可用集合的交集计算,如 Jaccard。
基于字符
编辑距离 (Levenshtein)
汉明距离
LCS
Jaro-Winkler
基于词语
余弦相似度
Dice 系数
欧式距离
Jaccard
simhash+ 汉明距离
minhash
下面针对每一个计算方式来逐一介绍。
编辑距离
Levenshtein 距离是一种计算两个字符串间的差异程度的字符串度量(string metric)。我们可以认为 Levenshtein 距离就是从一个字符串修改到另一个字符串时,其中编辑单个字符(比如修改、插入、删除)所需要的最少次数。俄罗斯科学家 Vladimir Levenshtein 于 1965 年提出了这一概念。简单的例子:从字符串“kitten”修改为字符串“sitting”只需 3 次单字符编辑操作,如下:
sitten (k -> s)sittin (e -> i)sitting (_ -> g)
因此“kitten”和“sitting”的 Levenshtein 距离为 3。
汉明距离
在信息理论中,Hamming Distance 表示两个等长字符串在对应位置上不同字符的数目,我们以 d(x, y) 表示字符串 x 和 y 之间的汉明距离。从另外一个方面看,汉明距离度量了通过替换字符的方式将字符串 x 变成 y 所需要的最小的替换次数。也就是 x 与 y 取异或的过程。简单的例子:
“karolin” and “kathrin” is 3″1011101″ and “1001001” is 2
汉明距离的计算是要两个字符串的长度等长,对应位置查找不同的字符即可。
LCS(最长公共子序列)
两个字符串的最长公共子序列(LCS)是指这两个字符串中最长的有相同顺序的子序列。举例说明一下,”Hello World” 和 “Bonjour le monde” 的 LCS 是 “oorld”。如果从左到右依次扫过字符串,你会发现 o、o、r、l、d 在两个字符串中出现的顺序是一样的。其他的子序列为 “ed” 和 “old”,但是它们都比 “oorld” 要短。注意:不要和最长公共字符串混淆了,后者必须是两个字符串的子字符串,也就是字符是直接相邻的。但对公共序列来说,字符之间并不是连续,但是它们必须有相同的顺序。计算两个字符串 a 和 b 的 LCS 方法之一是通过动态规划和回溯法。
Jaro-Winkler
Jaro-Winkler Distance 是一个度量两个字符序列之间的编辑距离的字符串度量标准,是由 William E. Winkler 在 1990 年提出的 Jaro Distance 度量标准的一种变体。Jaro Distance 是两个单词之间由一个转换为另一个所需的单字符转换的最小数量。Jaro-Winkler Distance 通过前缀因子使 Jaro Distance 相同时共同前缀长度越大的相似度越高。Jaro–Winkler Distance 越小,两个字符串越相似。如果分数是 0,则表示完全不同,分数为 1 则表示完全匹配。下面为 Jaro 相似度的计算方式:
Jaro-Winkler 只是在 Jaro 的基础上,为前缀因子增加了权重而已。
简单的例子:
文中提到的算法的相关代码,稍后会在 github 中更新。