共计 1492 个字符,预计需要花费 4 分钟才能阅读完成。
背景介绍
字符串的相似度算法在许多领域都能经常用到,在数据清理、语音识别、语音纠错、搜索等领域有重要的用处。本文主要介绍基于模糊音的方式匹配中文字符串,文末还会有作者对中文相似度匹配算法的其它想法。
问题描述
在语音识别领域,由于我国方言众多,所以需要精准地匹配每个地方的方言目前还不太现实。市面上的语音识别服务基本上对普通话的识别率是最高的,但是也需要用户用很标准的普通话来讲。这就涉及到模糊音匹配的问题了。
提出问题
用户说:“大娘水饺好吃吗”,被语音识别成了“大亮睡觉好吃嘛”(举个栗子而已),这个时候怎么将语音识别后的结果转换成我想要的结果。
解决思路
中文汉字大致有几个特征:1)声母;2)韵母;3)声调;4)偏旁;5)结构;6)笔画
这几个特征中,在语音识别后的处理过程中,1、2、3的权重要高一些,其中,1、2最为重要,也就是语音识别为什么出错的原因,要做的事情就是通过模糊音将声母、韵母来进行匹配。
先将23个声母编号:
声母 | 编号 | 声母 | 编号 | 声母 | 编号 | 声母 | 编号 |
---|---|---|---|---|---|---|---|
b | 1 | p | 2 | m | 3 | f | 4 |
d | 5 | t | 6 | n | 7 | l | 7 |
g | 8 | k | 9 | h | 4 | j | B |
q | C | x | D | zh | E | ch | F |
sh | G | r | H | z | E | c | F |
s | G | y | I | w | J |
韵母编号:
韵母 | 编号 | 韵母 | 编号 | 韵母 | 编号 | 韵母 | 编号 |
---|---|---|---|---|---|---|---|
a | 1 | o | 2 | e | 3 | i | 4 |
u | 5 | v | 6 | ai | 7 | ei | 7 |
ui | 8 | ao | 9 | ou | A | iu | B |
ie | C | ue | D | er | E | an | F |
en | G | in | H | un | I | ven | J |
ang | F | eng | G | ing | H | ong | K |
ian | L | uan | M | iang | N | uang | O |
iong | P | iao | Q |
我把常用模糊音的声母和韵母各自都标成相同的,比如n、l都是7,这样便于后面处理。
将语音识别结果按照 “声母-韵母-声母-韵母” 这样的格式转换成编号就变成了“517NG8BQA9F431”,关键字中“大娘水饺”拼音编码后是“517NG8BQ”,这个时候可以看出有两个字符串已经相同了。
所以目前可以想到的基于模糊音的中文匹配算法大概就是:先将原语句通过声母表和韵母表编码,再将自建的关键词库(事先也通过这种方法编码)与其对比,如果有相同的字符串,则很大概率可以直接替换掉原文,当然也有少数情况两个关键词拼音都一样。
思维发散
目前这种方式是基于绝对匹配来做的,也就是关键词库和原语句必须完全相同才能相互替换,但是需要用到模糊匹配上面似乎这种方式已经不行了。
不过,在这种方式的基础上,再利用到Edit Distance的算法似乎也可以实现模糊匹配,找出距离最相近的关键词,这种方式我没有试过,算法可参见Edit Distance。
我真正想说的是下面的东西。
在输入法上面会有简拼的用法,相信大家很习惯了‘wzry’就会匹配到‘王者荣耀’这样的输入方式。这个用法会给我一个启发,在模糊匹配的时候,有时候不需要用到韵母,有时候也不需要用到声母,特别是在长语句当中,简拼这种方式尤其受人喜欢。我们可以将上面例子中的原语句只将声母编码出来“57GBAF3”,“大娘水饺”关键词的声母是“57GB”,这个时候如果嫌精度不够高的话,可以把韵母加在后面,原语句为“57GBAF31N8Q941”,关键词为“57GB1N8Q”,这样精度就高了点,而且可以当作hash来使用,查找的时候复杂度为O(1),这个时候再用上前面的Edit Distance的算法的话,基本上基于模糊音的中文匹配精度就很高了。
如果不只是对语音识别后的语句做调整的话,还可以在前面编码的过程中加入字形的特征,偏旁结构笔画等做到根据字形也能智能纠错。
甚至如果在有大量统计数据的情况下,将每个声母或者韵母的编号用出现的概率来表示的话,还可以定量地计算出两个字符串之间的相似度,但是遗憾没有这么大量的数据。
中文字符串相似度算法还有很多可以拓展的,还需读者自行探索下去。