python自定义拼音输入法_Python与HMM实现简单拼音输入法

本文介绍了基于隐马尔科夫模型(HMM)的Python拼音输入法实现。通过解决拼音串到汉字的映射问题,利用维比特算法动态规划寻找最优路径,并通过统计词频优化模型。虽然部分诗句和易混淆拼音的正确率较低,但随着平滑参数的选择,整体正确率有所提升。代码和数据可供下载,便于进一步研究。
摘要由CSDN通过智能技术生成

一、基本思路和实现过程

1. 问题描述

给出一个拼音串,例如:qing hua da xue

如何找到对应的汉字呢?请注意,这里的拼音串不同的拼音之间是有空格隔开的,并且不包含标点符号。

2. 基于隐马尔科夫(HMM)的拼音输入法

继续考虑上面的问题。其中每个拼音都可能对应多个汉字,整体上构成一个复杂的网络,对应多种汉字组合:

我们可以把这个问题看成一个路径优化问题:我们认为汉语中每个字的出现不是偶然的,而是与上一个字存在某种联系,从而从上一个字到这个字可能存在某种概率,而且不同组合概率不同。显然这与我们的生活经验相符,比如“清华”出现的概率应该比“清话”和“清花”大。如果把这个概率看成一种路径长度,那么我们就是要找到最长的路径(只不过这里的路径“长度”是不同路径相乘得到——那么也可以将概率的对数视为真正的路径长度,但事实上没必要这么实现)。这恰好对应隐马尔可夫模型(Hidden Markov Model,HMM)。百科上的解释是它是一个含有隐含未知参数的马尔可夫过程。马尔可夫过程简单地说就是一个过程的一个状态由它的上一状态决定。之所以是隐马尔可夫模型,主要是这个状态序列是“隐藏”的。比如我们随便输入的一个句子基本上是之前没有输入过的。

考虑这样一个网络:

我们将上面的解析抽象为数学问题,目标也就是:

其中:

为了解决$P(w_i|w_{i-1})$ 可能为0的问题,采用平滑的方法:

实验中,通过选取多组参数确定最佳的$lambda$ 的取值。

此外,还有一个问题是,$w_{i-1}$ 也有可能为0. 在我的统计结果中,7272个汉字中以下汉字的出现次数为0:锿 砹 揞 茇 鞴 庳 笾 窆 瘭 醭 骖 楱 镩 榱 鹾 骣 冁 躔 蒇 傺 膪 舡 怛 赕 忉 帱 铞 髑 芏 憝 砘 裰 缍 苊 鲕 镄 篚 唪 鳆 砩 艴 钆 戤 槔 袼 虼 塥 觏 遘 诖 涫 匦 猓 蜾 馘 胲 糇 鹱 冱 擐 萑 蟪 咴 阍 劐 锪 哜 丌 墼 裥 鞯 戋 洚 鹪 僬 纟 鲒 骱 赆 獍 刭 弪 僦 鬏 醵 锩 胩 佧 蒈 闶 裉 眍 芤 蒉 悃 漤 耢 缧 缡 裣 癃 硵 镥 稆 锊 呒 鞔 硭 猸 镅 蠛 蛑 毪 镎 肭 蝻 耪 旆 堋 仳 擗 螵 缏 氕 肷 锖 鞒 劁 愀 吣 赇 肜 脎 鳋 锼 瞍 嗾 谇 唼 髟 胂 矧 铈 铴 耥 慝 掭 龆 酴 腽 芄 阢 饩 莶 蟓 枵 绁 砉 痃 泶 獯 曛 厣 阽 蛘 轺 铘 酏 狺 铕 窬 箢 眢 拶 驵 唣 趑 腙 鲰 觜 阼 齄 瘵 嫜 磔 膣 瘛 荮 瘃 窀

显然这些都是非常用字,我基本上一个都不认识。只能直接将概率设为0.

3. 维比特算法

每个拼音对应多个汉字,比如:a 阿啊呵锕吖腌嗄

从而多个拼音对应多层汉字。需要用动态规划的算法寻找最优路径:对于第一层,不需要求最大路径概率,只需要求该层各个汉字的概率。

对于后面所有层,递推关系式:

其中,$P(W_{i,j})$ 为点$W_{i,j}$ 的最佳路径值, $P(W_{i-1, k}|W_{i,j})$ 为$W_{i-1,j}$ 到$W_{i,k}$ 的发射概率。

4. 统计词频

我们需要知道每一个字出现的次数,每一个词和其他的字同时出现的次数。汉字的个数太多,共七千多个。如果两两组合构建矩阵,大小为7000*7000。当然,这个矩阵是相当稀疏的。可以考虑用字典+字典的数据结构。

首先,已经构造拼音与汉字对应表,由此可以构造pinyin2hanzi词典。

其次,对所有汉字给定编码,构造词典。

再次,对所有汉字统计出现次数。

最后,对汉字矩阵统计出现次数。

方法是遍历语料库。每一行的结果需要判断汉字串(可能被各种标点符号切割)。对每个汉字串,遍历即可。

二、输入法效果展示

1. 正确率较低的样例

从上图可见大部分的句子正确率较高,但是仍有相当一部分句子正确率很低。下表为正确率在0.2以下的测试样例及输出结果(已经剔除只有一个字的“句子”)。从表可见正确率较低的句子大部分是诗句,可以通过增强这些诗句的权重来改进。另外某些句子的拼音本身就易造成歧义,比如“xiang xiang ji”的输出结果为“想象级”,而正确结果为“香香鸡”。

输入结果正确结果正确率经嗽和大厦也显示认领提惊搜狐大厦夜现食人灵体0.181818

他是最阏氏广她是罪恶之光0.166667

迹象风不方调簦合收昭山和既相逢不妨挑灯呵手照山河0.166667

府网站厮杀场斧王战死沙场0.166667

认为深麽舀水较人为什么要睡觉0.142857

策影翻沉着孩说侧影反衬著海水0.142857

和方殷小切需行何妨吟啸且徐行0.142857

务事人肥市食宿物是人非事事休0.142857

主播票等都秭归珠箔飘灯独自归0.142857

一芟夷山梁静静一闪一闪亮晶晶0.142857

立名侨侨华国天便黎明悄悄划过天边0.125

烃含四种生情也佛听寒寺钟声请野佛0.125

来岜莱巴和向上海拔来吧来吧互相伤害吧0.111111

想象级香香鸡0

新入名景泰心如明镜台0

名警一腓肽明镜亦非台0

政部自哐当争不恣狂荡0

和叙伦的桑何须论得丧0

子失败一圊向自是白衣卿相0

岩画像没烟花巷陌0

看汛防堪寻访0

评省长平生畅0

务于茉莉莎雾雨魔理沙0

校和财路见建交小荷才露尖尖角0

动枫叶芳华签署东风夜放花千树0

桂西柳子瘢痕将贵系六字班很强0

作业与庶锋舟昨夜雨疏风骤0

声喊一般选剩寒意盘旋0

一孟维码以梦为马0

将槲叶玉石碾等江湖夜雨十年灯0

五十一道午时已到0

策是杨立即测试样例集0

构负圭吾乡王苟富贵毋相忘0

泰晤拉太污啦0

有四阮西嘌醇血游丝软系飘春榭0

络虚情展溥修炼落絮轻沾扑绣帘0

2. 正确率与句子长短关系

对于每个句子,句子长短和正确率关系如下:

以最长的三个句子为例:输出结果1:安装具有复杂电子控制系统的现代知道无期待提过去相对简单而笨重的火炮系统

正确结果1:安装具有复杂电子控制系统的现代制导武器代替过去相对简单而笨重的火炮系统

输出结果2:位于美国家利福尼亚洲旧金山玩的阿尔卡特拉斯岛上的联邦监狱遭到废止

正确结果2:位于美国加利福尼亚州旧金山湾的阿尔卡特拉斯岛上的联邦监狱遭到废止

可见长句子的正确率也比较高。主要是因为测试集中的长句子词语较多,相互关联性也较强。

三、参数选择及性能分析

我选取了多组$lambda$ 的取值,并计算其对于测试集全集的正确率。

$lambda$accuracy00.469427

0.10.575385

0.20.586337

0.30.597588

0.40.608349

0.50.615254

0.60.625446

0.70.640778

0.80.654613

0.90.674134

0.950.686197

0.990.714261

0.9990.728808

0.99990.730258

0.999990.730011

10.727696

从上表及上图可见,随着$lambda$ 取值的增加,正确率逐渐增加。在$lambda$ 超过0.9后,增加得比较平稳。最高值出现在0.9999左右,而之后取0.99999和1正确率都有略微下降。因此,对于本测试集,平滑参数的加入确实能提高正确率,但是提高程度很有限。

四、代码及数据下载

下载后在data/input.txt中输入拼音串,不同的拼音用空格隔开,不同的句子之间换行。有些带有ü的拼音可以用v或u替代。运行src中的shurufa.py脚本,在data/output.txt中就是生成的汉字。

最后祝你身体健康,再见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值