中文相似度匹配算法

相似度计算方法 阅读详情

基于音形码的中文字符串相似度算法

背景介绍

字符串相似度算法是指通过一定的方法,来计算两个不同字符串之间的相似程度。通常会用一个百分比来衡量字符串之间的相似程度。字符串相似度算法被应用于许多计算场景,在诸如数据清洗,用户输入纠错,推荐系统, 剽窃检测系统,自动评分系统,以及网页搜索和DNA序列匹配这些方向都有着十分广泛的应用。

 

常见的字符串相似度算法包括编辑距离算法(EditDistance),n-gram算法,JaroWinkler算法以及Soundex算法。本文接下来大略的介绍一下这几种算法,有兴趣的读者可以在互联网找到一些更详细的资料。

 

最常见的相似度算法为编辑距离算法(EditDistance),该算法将两个字符串的相似度问题,归结为将其中一个字符串转化成另一个字符串所要付出的代价。转化的代价越高,说明两个字符串的相似度越低。通常可以选择的转化方式包含插入,替换以及删除。

 

N-Gram算法则是基于这样的一个假设: 即在字符串中第n个词的出现只与前面n-1个词相关,而与其他任何词都不相关,整个字符串出现的概率就是各个词出现的概率的乘积。 N-gram本身也代表目标字符串中长度为n的子串,举例,“ARM”在“ARMY”中,便是一个3-gram。当两个字符串中,相同的n-gram越多时,两个字串就会被认为更加相似。

 

Jaro Winkler则是将n-gram算法更进了一步。将n-gram中的不匹配的部分同时进行了换位的考虑,使得能获得更准确的相似程度。JaroWinkler在比较两个较短字符串的情况下,能够取得很好的结果。

 

Soundex算法与前面几种都不太相同。该算法的特点是,它所关注的问题并非两个字符串文本上的相似程度,而是发音的近似。首先,该算法会将两个字符串分别通过一定的hash算法转换成一个hash值,该值由四个字符构成,第一个字符为英文字母,后面三个为数字。进行转化的hash算法并非随机选取,而是利用了该拉丁文字符串的读音近似值。

 

当获得了两个字符串的读音上的hash值之后,该算法再对两个hash的相似度进行计算,便可以得出输入字符串的读音相似度。

 

Soundex算法的另一个应用场景在于,用户进行模糊查询时,可以通过Soundex值进行过滤,以提高查询性能。

 

问题描述

这些常见的字符串相似度算法在处理拉丁文字的文本匹配时,都能起到非常好的效果。它们本身最初的发明者也是为了解决拉丁文字中遇到的问题。然而,对于象形文字相似度计算,比如说中文,这些算法就显得捉襟见肘了。

 

举例来说明:

 

南通市 – 难通市 – 北通市

 

对于编辑距离算法而言,南通市和难通市之间的相似度,与南通市和北通市的相似度,是一模一样的,因为两者都需要付出相同的代价来转换成另一个。 使用N-Gram算法,得出的也是相同的结果。然而,对于熟悉汉字的人来讲,南通市和难通市理应有着更加接近的相似度。因为两者的发音完全相同。

 

既然是发音的问题,那么有没有可能利用Soundex算法来解决呢? 目前看来,还是无法做到,因为Soundex算法更多的是针对拉丁文字的发音,对于中文而言,Soundex算法无能为力。

 

如果说这个例子仅仅说明是发音上的相同,拉丁文字也有相似的问题,那么下面这个例子则描述了只存在于象形文字中的相似度问题:

 

彬彬有礼 – 杉杉有礼

 

如果站在解决拉丁文字的相似度的角度来看,那么这两个字符串大约只有50%的相似度,因为在四个字符中,就有两个字符是完全不同的。这两个字符不仅外形不同,即使是发音,也是完全不同。

 

然而对于熟悉汉字的人来说,这两个输入应该有着相当高的相似度。因为第一个和第二个字符,虽然不同,却有着十分接近的字形。

 

这样的案例常常出现在录入手写输入时,举例来说,某个顾客填写了一张快递单:

 

江苏省 南通市 紫琅路 100号

 

当快递员签收快递时,可能需要在系统中录入该地址,又或者,这家快递公司采用的是先进的扫描仪器,可以将地址通过扫描仪扫入。假设顾客的字写的十分潦草,那么快递员粗心大意或者不够智能的扫描仪,都有可能导致下面的文字被错误的录入:

 

江苏省 南通市 紫路 100号

 

如何识别这样的相似中文词组,在现有的算法中,很难解决该问题。

 

中文的字符串相似度有着其独特的特征,不同于其他任何语言,而在现实世界中,我们又却是时常面临这样的问题,正如我们刚才看到的例子,其中最常见的场景便是中文纠错。

 

我们急需要需找一种新型的算法来解决该问题。

 

问题分析

想要解决中文字符串的相似度匹配问题,并且量化中文相似度的结果,必须首先对单个汉字的特性有一定的了解。“琅“和“狼”的相似度,跟“琅”和“娘”之间的相似度比较,究竟哪个更高一些,量化的依据是什么?“篮”和“南”呢?他们之间有相似之处么?只有把这些问题都搞清楚了,我们才能设计出优秀的算法,来计算中文字符串之间的相似度。

 

经过长时间的调研和准备,在工作中不断的思考总结遇到的中文相似度的问题,我们做出如下的总结,中文的相似度问题,主要归结在三个方面。

 

同音字

汉字中的同音字可谓是外国人学习中文的一大难题,两个截然不同的汉字,可能有着相同的发音。

 

当我们对两个汉字进行相似度匹配时,发音的相同或是相近,应当在考虑之列。

 

对于同音字,如果仅仅考虑其发音的相似程度,那么提供这样的一个相似度算法还是十分容易的,只需要现将汉字转化成其对应的拼音,再进行传统的相似度匹配算法,譬如编辑距离算法,即可达到很好的效果。

 

方言易混淆发音字

在中国的各个省市中,不同地区有着各自截然不同的方言。这也导致了一些口音很重的地区无法识别一些拼音之间的区别。

 

最常见的例子便是,许多南方人很难分别“L”和“N”,他们常常会将这两个音弄混,将“篮球”读作“南球”,而“刘德华”就变成了“牛德华”。

 

解决方言易混淆发音字的办法和同音字的方法很相似,只需要在将汉字转化成拼音之后,再对一些易混淆的音标再进行一次转化,然后再去识别他们的相似度即可。

 

当然,也可以在计算近似度的时候,给易混淆音标设置一个相对较高的比值,也可以解决该问题。

 

还有些常见的易混淆音标包括:

 

“AN” – “ANG”

“Z” – “ZH”

“C” – “CH”

“EN” – “ENG”

 

字形相似

最后一种相似度问题,同时也是最难解决的问题,便是汉字字形上的相似。

 

汉字,作为世界上仅存的几种象形文字之一,有着和世界主流使用的拉丁语系截然不同的表现形式。拉丁文字作为一种拼音文字,在于表音,即文字形态表示了它的发音。而象形文字,则是表意文字,一个汉字本身,便表达了它所隐含的意思。

 

在文章开篇中,我们所提到的所有相似度匹配算法,都无法恰当的区分两个不同汉字之间字形上的异同,更罔论计算他们的相似度了。

 

对于这个问题,一种朴素的思想,便是首先将汉字转化成一组的字母数字的序列,而这个转化所用到的hash算法必须能够将该汉字的字形特征保留下来。利用这样的转化,我们便将汉字字形的相似度问题,变成了两组字母数字序列的相似度问题。而这正是传统相似度匹配算法的强项。

 

这种解决方案的核心,就在于找到一个恰当的hash算法,能够将汉字进行适当的转化,并在转化结果中,保留住汉字的字形特征。

 

在另一篇论文中,作者提到了使用一种名为四角编码的汉字检字法来实现这样的算法。四角算法是由王云五于1925年发明,这种编码方式根据汉字所含的单笔或复笔对汉字进行编号,取汉字的左上角,右上角,左下角以及右下角四个角的笔形,将汉字转化成最多五位的阿拉伯数字。 通过将汉字转化成四角编码,再对四角编码的相似度进行计算,便可以得出两个汉字在字形上的相似程度。

 

关于四角号码的编码方式,并非本文的重点,感兴趣的读者,可以访问站点:http://baike.baidu.com/view/67253.htm?fr=aladdin以了解更多信息。

 

利用四角编码计算汉字相似度,可以在一定程度上解决形近字的问题。

 

然而四角编码也有其自身的问题,由于只取汉字的四角笔形,有些外形截然不同的汉字,因为四角结构相同,也拥有同样的四角编码。

 

举例说明:

量 -  6010

日 -  6010

 

即使是从未学过中文的人,也能一眼看出这两个字形上的差异,如果我们仅仅使用四角编码,则会得出这两个汉字相似度为100%的可笑结论。

 

综合以上关于汉字相似度的三种问题,我们发现,每种解决方案都旨在解决整个问题集的的一个子集。这种分不同场景的做法,常常会造成使用者的困扰,因此,我们在想,是否存在一种方法,能够将这三种解决方案合而为一,取其优点而去其缺点,一次性彻底解决中文的相似度问题?

 

这个问题引发了我的思考。

 

音形码(SoundShape Code,SSC)

为了解决文章上面描述的问题,我在工作中积累相关经验,并开发出了音形码这一汉字编码方式,来解决中文的相似度算法问题。

 

首先,什么是音形码?音形码是一种汉字的编码方式,该编码将一个汉字转化成一个十位字母数字序列,并在一定程度上保留了该汉字的发音及字形的特征。

 

下图阐述了音形码的序列中每一位的含义:


整个音形码共分两部分,第一部分是音码部分,主要覆盖了韵母,声母,补码以及声调的内容。

 

第一位,是韵母位,通过简单的替代规则,将汉字的韵母部分映射到一个字符位。汉字的拼音中一共有24种韵母,其中部分为了后期计算目的,采用相同的字符来替代,以下是一张完整的匹配表:


你会发现我们对于an和ang,所使用的是同一种转化,目的便是为了再后期计算相似度的时候,将这种差异弱化。对于没有这种需求的应用来说,完全可以自行生成映射表。

 

第二位是声母位,同样的,也是利用一张替换表来将声母转换成字符:


可以看到,z和zh用的也是相同的转化。

 

第三位则是补码,通常用于当声母和韵母之间还有一个辅音的时候,采用的是韵母表相同的替代规则。

 

第四位是声调位,分别用1,2,3,4来替代汉字中的四声。

 

第二部分是字形码。

 

第一位被称为结构位,根据汉字的不同结构,用一个字符来表示该汉字的结构。

 

接下来的四位,则依然是借用了四角编码,来描述该汉字的形态。由于四角编码表过长,在这里就不一一列举了。

 

最后一位,是汉字的笔画数位, 从一到九,分别代表该汉字的笔画为一到九,接下来是A代表10位,B代表11位,并依次类推。 Z代表35位,以及任何超过35位的都用z。

 

举例说明:汉字 “琅”,它的音形码编码是:


通过这样的方式,将汉字首先转换成了一系列的字符序列,这样我们就可以采用一定的办法,来计算他们的相似度。

 

单字相似度计算

对于单字的相似度匹配,我们采用了比较复杂的计算公式,以期获得一个比较好的计算结果。


P代表音码的相似度,S代表形码的相似度,两者各占整个单字相似度的50%。

 

单独拆解音码相似度和形码相似度:

 


这里我重新定义了 和 的含义已适应该算法,用于代表字符比较操作, 表示,若两字符相同,则返回1,不同,则返回0. 表示,若俩字符相同,则返回1, 两字符不同,则返回-1.

将两个公式进行合并,便得到最终的计算单字相似度的算法:

 

先看P部分,声母部分占据了整个音码相似度的60%,补码为30%, 而声调部分为10%。于此同时,韵母部分对最终的相似度起到 的调整作用。

 

形码部分的算法很类似,四位四角编码在形码部分算法中占据相同的比重,而整个四角编码在形码部分中则占据70%的比重,而笔画数则占据了30%的比重。最终,字形结构部分与韵母部分一致,起到了 的调整作用。

 

我们以“琅”,“狼”和“娘”三字举例。

 

“琅”字的音形码为:F70211313B

“狼”字的音型码为:F70214323A

“娘”字的音型码为:F74214343A

 

根据我们刚才所描述的算法,可以得出,“琅”和“狼”的相似度为88.75%。 而“琅”和“娘”的相似度为83.75%

 

应用场景

单字相似度的计算并非十分有用,毕竟当两个非常大的字符串进行比较时,两个字之间差异程度的细微差别,整体的相似度结果影响不是很大。

 

然而在某些场景下,诸如较短字符串的比较,或者是中文纠错的时候,单字相似度的算法则可以起到非常大的作用。

 

举例来说,用户通过搜索引擎来检索一个短语:“紫娘路”, 而在搜索引擎的词库中,并没有能够发现任何匹配的字符串,相应的,找出了两个与其类似的字符串:

“紫琅路”

“紫薇路”

 

此时,目前的搜索引擎系统无法区别出这两个字符串与用户输入哪个更加接近,因而无法向用户做出更好的推荐。 相应的,使用本文描述的中文相似度算法,便可以算出,“琅”和“狼”的相似度为88.75%(前文已得出)。 “娘”和“薇”(音形码: 8K0114424G)的相似度为14.3%。由此可以得出,“紫琅路”与输入数据较为接近。

 

另一种常见应用场景为,服务提供者拥有巨大的词库,用户输入一个错误数据之后,如何尽快的找出所有与其十分接近的词。

 

在绝对匹配的情况下,做法通常为,为词库中的每一个词,计算出一个hash值,再将hash-字串对插入到一张hash表中。当用户输入一个字串时,现将该字串的hash值计算出,再去表中进行匹配。

 

这种做法对于绝对匹配而言,效率很高,然而对于模糊查询来说,则毫无用武之地。用户只能一个字符串一个字符串的做相似度比较算法,来选出最佳的结果。该算法的时间复杂度则达到了O(n)。

 

为了解决这个问题,我们可以设计一种hash值的计算方法,使得相似的字符串拥有相同的hash值,这样当用户的字符串输入时,就可以轻易的找到一群与之十分相似的字符串,再对此进行一一比较,可以将性能提升到最大。只要算法选取合适,性能甚至可以达到O(1)。

 

而这样的方法就隐藏在音形码的编码当中。

 

对任意字符串,取每一位字符的音形码的第一位(韵母)和第五位(结构),拼成一个字符串,作为该字符串的hash值,通过这样的方式,我们可以以下字符串进行转化:

“紫琅路”: 41GE5E

“紫娘路”: 41GE5E

“紫薇路”: 41815E

 

当用户输入“紫狼路”时,将会被转化成:41GE5E,从而与“紫琅路”以及“紫娘路”的hash值一致。再通过更细节的比较,可以得出“紫琅路”为最优结果。

 

当然,不同的应用可以选取不同的音形码的位数,来得到对应用最合适的hash值。这完全可以根据需求来定制化。

 

字符串相似度计算

字串相似度的计算可以通过直接将字符串中的每个汉字转化为音形码,再将所有音形码合并起来进行EditDistance算法比较,即可获得。

 

因为中文的大字符串的比较算法,即使是EditDistance也可以得到较好的结果,在这里就不详细描述了,有兴趣的读者可以自行研究。

 

后续

整个算法源于我在开发公司的某个实体解析的产品中总结的经验,当时因为遇到这样的问题,却没有很好的解决办法。后来,在公司组织的编程马拉松竞赛中,我便选择了这样的课题来研究,并获得了很好的结果。

 

该算法还有着这样那样的缺陷,比如音形码过长问题,字串错位如何计算相似度等。但是我想,不能总等一切问题都解决再来做这些工作,而是一步解决一个问题的来不断前进。因此也希望借用这篇文章,给大家一个启发,为中文的相似度算法做出自己的贡献,那它的目的也就达到了。

 

 

字符串相似度算法 字符串相似度算法 编辑距离算法解析 阅读详情

相关推荐

文本匹配相似度计算---多种距离算法 ,多种相似度计算算法,一看就懂

常见的距离算法相似度(相关系数)计算方法 总结摘要 1.常见的距离算法 1.1欧几里得距离(Euclidean Distance) 根据两用户之间共同评价的Item为维度,建立一个多维的空间,那么通过用户对单一维度上的评价Score组成的坐标系X(s1,s2,s3……,si)即可定位该用户在这个多维度空间中的位置,那么任意两个位置之间的距离Distance(X,Y)(即:欧式距离)就能在一定程度上反应了两用户兴趣的相似程度。 欧氏距离越小,两个用户相似度就越大,欧氏距离越大,两个用户相似度就越小。 计算

Western_europe 5267

相似度算法

今天梳理的是底层的应用算法,计算相似度的。这种算法在nlp领域比较常见,其他的地方怎么用就仁者见仁啦~ 相似度算法 算法名称 简单描述 LCS 最长公共子序列 Hamming Distance 汉明距离 Cosine Similarity 余弦相似度算法 1、欧式距离(Euclidean Distance) 欧式距离全称是欧几里距离,是最易于理解的一种距离计算方式,源自欧式空间中两点间的距离公式。 平面空间内...

AnneQiQi的博客 3459

基于逆向匹配算法中文分词系统及中文文本相似度对比系统

开始之前:   该系统整体是基于C++写的,可视化界面由QT来完成,因此本文中所有列出的代码均为经过QT改造,在QT中可执行的C++代码(稍作改动就可变回纯C++)。其中其中涉及到的知识比较简单,且代码量也不高,但是用来做一个简单的课设还是可以的。话不多说,直接上我的课设报告。源程序在我主页有,需要的话自行下载。 目录问题背景应用意义主要问题计划实施方案拟采用的数据结构及算法基本流程及实现建立词典建立基本数据结构逆向匹配算法对特殊字符的处理中文文本特征词的提取及保存文本相似度对比算法词典书中词的添加及删除算

qq_42753940的博客 487

字符串相似性的几种度量方法

一: 字符串相似性的几种度量方法 https://blog.csdn.net/shijing_0214/article/details/53100992 1、余弦相似性(cosine similarity) 2、欧氏距离(Euclidean distance)  3、编辑距离(edit distance)  4、海明距离(hamming distance) 5、Dice 距离  6、...

qfikh的博客 4717

StructBERT中文语义匹配系统定制开发:添加自定义相似度算法插件

本文介绍了如何在星图GPU平台上自动化部署📚 StructBERT 中文语义智能匹配系统镜像,实现中文文本语义相似度计算。该系统基于孪生网络架构,支持添加自定义相似度算法插件,可广泛应用于电商商品匹配、客服意图识别等场景,提升文本处理的准确性和效率。

weixin_30789053的博客 372

【深度学习应用】基于Bert模型的中文语义相似度匹配算法[离线模式]

【代码】基于Bert模型的中文语义相似度匹配算法(离线模式)

有朋自远方来,不亦乐乎。 5502

几种句子相似度实现算法(简单了解一下)

最近在做一个虚拟客服的项目,简单的了解了一下中文语境的集中句子相似度算法 看了大佬的项目和博客,不明觉厉,链接送上:https://github.com/wenyangchou/SimilarCharactor SimilarCharactor 基于音形码,EditDistance的字符串纠正相似度算法 音形码格式:【韵母,声母,结构,四角编码,笔画数】 共8位 音形码相似度算法 参考...

@惊蛰的博客 2651

StructBERT中文语义匹配系统教程:自定义相似度计算逻辑扩展

本文介绍了如何在星图GPU平台上自动化部署📚 StructBERT 中文语义智能匹配系统镜像,实现高效的中文文本语义相似度计算。该系统基于先进的孪生网络架构,可应用于智能客服问答匹配、文档去重等场景,提供精准的语义理解和快速响应能力。

weixin_42608318的博客 628

中文短句子相似度比较(PHP版本UTF8)

<?php #中文短句子相似度比较 #参考文献 http://www.doc88.com/p-2055556399236.html header("Content-type: text/html; charset=utf-8"); class ShortTextCompare{ #计算匹配文字$arr1[$i]的最小匹配偏移值 public static function PosOffset

dl425134845的专栏 4998

rails中文匹配相似度gem包对比

测试数据 ["美科学家发现人体新器官","科学家发现新器官"],["曝高云翔悉尼被捕","高云翔涉性侵被捕"],["走失柯基犬被摔死事件","柯基犬摔死后续"],["张继科景甜公布恋情","张继科公布恋情"] string-similarity(gem "string-similarity") https://github.com/mhutter/string-similarity ...

weixin_30296405的博客 168

余弦相似度 java代码_余弦相似度-java代码实现

package sim;import java.util.HashMap;import java.util.Map;import java.util.Set;/*** 字符串相似性匹配算法* Created by panther on 15-7-20.*/public class Similarity {Map vectorMap = new HashMap();int[] tempArray =...

weixin_35146639的博客 344

从词林到拼音:全面解析Java中文相似度计算的4种核心算法

本文深入解析了Java中文相似度计算的四种核心算法:词林相似度、拼音相似度、概念相似度和字面相似度。通过实战代码演示,详细阐述了各算法的原理、适用场景及在智能搜索、推荐系统、文本纠错等领域的应用。重点探讨了基于语义知识库的词林相似度计算,并提供了算法选择与性能优化的综合策略,帮助开发者构建更智能的中文文本处理应用。

ppp33的博客 114

终极指南:如何让Zotero完美识别中文文献的3个简单步骤

如果你正在使用Zotero管理中文文献,却苦于元数据乱码、PDF信息缺失,那么Jasminum(茉莉花)插件就是你的救星。这款专门为中文用户设计的Zotero插件,通过智能化的中文数据抓取、本地附件匹配和PDF大纲功能,彻底解决了中文文献管理的痛点。本文将带你从零开始,掌握让Zotero完美识别中文文献的完整方法。 ## 📚 为什么你的中文文献管理总是出问题? 想象一下这样的场景:你从知网

gitblog_01096的博客 138

StructBERT中文语义匹配实战手册:FAQ库动态加载、阈值热更新、结果排序算法说明

本文介绍了如何在星图GPU平台上自动化部署StructBERT文本相似度-中文-通用- WebUI镜像,并构建智能语义匹配系统。该镜像的核心应用场景是智能客服FAQ问答,能够基于语义理解而非关键词匹配,自动为用户查询找到最相关的答案,大幅提升客服效率与准确性。

weixin_28999139的博客 29

模糊连接实战指南:用rapidfuzz精准匹配中文数据

模糊连接是一种处理现实世界中字符串不完全一致问题的关键技术,其核心在于量化文本相似度而非简单模式匹配。它基于编辑距离、Jaccard、音码(Soundex)或语义向量等算法,将‘人眼判断是否为同一实体’转化为可配置、可复现的数值规则。该技术在客户主数据整合、跨系统用户归因、医疗ID映射等场景中不可或缺,尤其适用于中文姓名、地址、公司名等存在错别字、简繁体、拼音变体、格式差异的业务数据。本文聚焦Python生态下的生产级实践,以rapidfuzz为核心工具,结合清洗标准化、分块索引、多维置信度评估与业务约束嵌

weixin_33563728的博客 334

简答题文本自动评分

因为用户的答案中涉及到中文, 所以就必须使用中文分词器, 最终选定的是HanLP,非常的方便, 资源链接如下: https://github.com/hankcs/HanLP/tree/1.x 可以自行学习使用. 首先项目中引入HanLP的maven坐标: <dependency> <groupId>com.hankcs</groupId> <artifactId>hanlp</artifactId> <v..

长河的博客 2575
上一篇: 数据质量与信息质量
下一篇: 《实体解析与信息质量》 - 目录
数据中国
博客等级 码龄12年 136粉丝 54原创
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值