2016-02-08
词库中既要包含每个字的拼音,也要包含常用单词/短语的读音。有些字是多音字,所以至少要保存其最常用的读音,不常用的读音多出现在单词/短语里。
好了,词库准备好了,现在手头有一句话要转换要转换为拼音,这句话是:
你好世界杯
我们的词库是这样子的:
你:nǐ 好:hǎo,hào 世:shì 界:jiè 杯:bēi 世界:shì,jiè 你好:nǐ,hǎo 苦尽甘来:kǔ,jìn,gān,lái
词库中最长的词 苦尽甘来
包含4个字。所以 你好世界杯
从4个字开始匹配:
你好世界
是否在词库中,不在; 你好世
是否在词库中,不在; 你好
是否在词库中,在,得到 nǐ,hǎo
; 世界杯
是否在词库中,不在; 世界
是否在词库中,在,得到 shì,jiè
; 杯
是否在词库中,在,得到 bēi
; 于是 你好世界杯
被转换为 nǐ,hǎo,shì,jiè,bēi
。
纯粹的基于词库的方法在实际的使用中会遇到问题,例如 提出了解决方案
这句话中 了解
会被当作一个单词,所以会得到错误的结果:
tí,chū,liǎo,jiě,jué,fāng,àn
更好的方法是先进行分词得到:
提出 了 解决 方案
然后基于词库对每个结果分别处理。
这里的拼音一般不带声调。
将汉字作为隐藏状态,拼音作为观测值,使用viterbi算法可以将多个拼音转换成合理的汉字。例如给出 ti,chu,le,jie,jue,fang,an
,viterbi算法会认为 提出了解决方案
是最合理的状态序列。
HMM需要三个分布,分别是:
这个3个分布就是三个矩阵,根据一些文本库统计出来即可。
viterbi算法基于动态规划, 维基百科 - Viterbi algorithm 给出了很好的解释和示例。
原则:
词库的格式是:
拼音:单词:权重
例如:
ni:你:0.15 ni:泥:0.12 a:啊:0.18 hao:好:0.14 nihao:你好:0.6
假如输入是 ni,hao,a
,我们计算一下各种组合的权重:
组合 | 权重 |
---|---|
你,好,啊 | 0.15×0.14×0.18 = 0.00378 |
泥,好,啊 | 0.12×0.14×0.18 = 0.003024 |
你好,啊 | 0.6×0.18 = 0.108 |
可以看出, 你好,啊
是最好的结果。
实际实现中需要用到 动态规划 , 和求有向无环图中两点之间最短距离类似。
基于上面的思路,我编写了两个工具,欢迎指教 ^^