文本相似度,顾名思义是指两个文本(文章)之间的相似度,在搜索引擎、推荐系统、论文鉴定、机器翻译、自动应答、命名实体识别、拼写纠错等领域有广泛的应用。
与之相对应的,还有一个概念——文本距离——指的是两个文本之间的距离。文本距离和文本相似度是负相关的——距离小,“离得近”,相似度高;距离大,“离得远”,相似度低。业务上不会对这两个概念进行严格区分,有时用文本距离,有时则会用文本相似度。
欧氏距离是数学中的一个非常经典的距离,公式如下: 文本向量 A={一,二,三,四},即 x1 = 一,x2 = 二,x3 = 三,x4 = 四 文本向量 B={一,四,六,八},即 y1 = 一,y2 = 四,y3 = 六,y4 = 八 这里规定,若 xi=yi,则 xi-yi=0;若 xi≠yi,|xi-yi|=1。 所以,欧氏距离d是 1。
(1)适用场景 编码检测等类似领域。两串编码必须完全一致,才能通过检测,这时一个移位或者一个错字,可能会造成非常严重的后果。比如下图第一个二维码是 “这是一篇文本相似度的文章”,第二个是 “这是一篇文本相似度文章”。从人的理解来看,这两句话相似度非常高,但是生成的二维码却千差万别。 (2)不适用场景 文本相似度,意味着要能区分相似 / 差异的程度,而欧氏距离更多的只能区分出是否完全一样。而且,欧氏距离对位置、顺序非常敏感,比如 “我的名字是孙行者” 和“孙行者是我的名字”,在人看来,相似度非常高,但是用欧氏距离计算,两个文本向量每个位置的值都不同,即完全不匹配。
和欧氏距离非常相似(把平方换成了绝对值,拿掉了根号),公式如下: 适用场景同欧氏距离。
顾名思义,编辑距离指的是将文本 A 编辑成文本 B 需要的最少变动次数(每次只能增加、删除或修改一个字)。编辑距离是对称的,即将 A 转化成 B 的最小变动次数和将 B 转化成 A 的最小变动次数是相等的。 同时,编辑距离与文本的顺序有关。
(1)适用场景
编辑距离算出来很小,文本相似度肯定很高。如果用算法语言来说的话,就是准确率很高(即虽然会漏掉一些好的 case,但可以确保选出来的 case 一定非常好)。
(2)不适用场景
反过来说,虽然准确率很高,但召回率不高。在某些业务场景中,漏掉的 case 会引起严重后果,比如 “批发零售” 和“零售批发”,人的理解应该非常相似,可编辑距离却是 4,相当于完全不匹配,这显然不符合预期。
杰卡德相似度,指的是文本 A 与文本 B 中交集的字数除以并集的字数,公式非常简单: 杰卡德相似度与文本的位置、顺序均无关。比如 “王者荣耀” 和“荣耀王者”的相似度是 100%。无论 “王者荣耀” 这 4 个字怎么排列,最终相似度都是 100%。在某些情况下,会先将文本分词,再以词为单位计算相似度。比如将 “王者荣耀” 切分成 “王者 / 荣耀”,将“荣耀王者” 切分成“荣耀 / 王者”,那么交集就是{王者,荣耀},并集也是{王者,荣耀},相似度恰好仍是 100%。
(1)适用场景 对字 / 词的顺序不敏感的文本,比如前述的 “零售批发” 和“批发零售”,可以很好地兼容。 长文本,比如一篇论文,甚至一本书。如果两篇论文相似度较高,说明交集比较大,很多用词是重复的,存在抄袭嫌疑。 (2)不适用场景 重复字符较多的文本,比如 “这是是是是是是一个文本” 和“这是一个文文文文文文本”,这两个文本有很多字不一样,直观感受相似度不会太高,但计算出来的相似度却是 100%(交集 = 并集)。 对文字顺序很敏感的场景,比如 “一九三八年” 和“一八三九年”,杰卡德相似度是 100%,意思却完全不同。
余弦相似度的灵感来自于数学中的余弦定理,这里对数学内容不做过多解释,直接上公式: 其中,A、B 分别是文本一、文本二对应的 n 维向量。 举例: 文本A是 “一个雨伞”,文本B是 “下雨了开雨伞”,它们的并集是 {一,个,雨,伞,下,了,开},共 7 个字。 若并集中的第 1 个字符在文本一中出现了 n 次,则 A1=n(n=0,1,2……)。若并集中的第 2 个字符在文本一中出现了 n 次,则 A2=n(n=0,1,2……)。依此类推,算出 A3、A4、……、A7,B1、B2、……、B7,最终得到: A=(1,1,1,1,0,0,0) B=(0,0,2,1,1,1,1) 将 A、B 代入计算公式,得到 1)适用场景
余弦相似度和杰卡德相似度虽然计算方式差异较大,但性质上很类似(与文本的交集高度相关),所以适用场景也非常类似。 余弦相似度相比杰卡德相似度最大的不同在于它考虑到了文本的频次,比如上面例子出现了 2 次 “雨”,和只出现 1 次“雨”,相似度是不同的;再比如“这是是是是是是一个文本” 和“这是一个文文文文文文本”,余弦相似度是 39%,整体上符合 “相同的内容少于一半,但超过 1/3” 的观感(仅从文本来看,不考虑语义)。
(2)不适用场景
向量之间方向相同,但大小不同的情况(这种情况下余弦相似度是 100%)。比如 “太棒了” 和“太棒了太棒了太棒了”,向量分别是(1,1,1)和(3,3,3),计算出的相似度是 100%。
这时候要根据业务场景进行取舍,有些场景下我们认为它们意思差不多,只是语气程度不一样,这时候余弦相似度是很给力的;有些场景下我们认为它们差异很大,哪怕意思差不多,但从文本的角度来看相似度并不高(最直白的,一个 3 个字,一个 9 个字),这时候余弦相似度就爱莫能助了。