python自定义拼音输入法_用Python从0开始实现一个中文拼音输入法
众所周知,中文输入法是一个历史悠久的问题,但也实在是个繁琐的活,不知道这是不是网上很少有人分享中文拼音输入法的原因,接着这次NLP Project的机会,我觉得实现一发中文拼音输入法,看看水有多深,结果发现还挺深的,但是基本效果还是能出来的,而且看别的组都做得挺好的,这次就分 享一下我们做的结果吧。 (注:此文假设读者已经具备一些隐马尔可夫模型的知识)
任务描述
实现一个中文拼音输入法。
经过分析,分为以下几个模块来对中文拼音输入法进行实现:
核心功能包括拼音切分(SplitPinyin.py)
HMM模型训练(TrainMatrix.py)
Trie树构建与搜索接口实现(PinyinTrie.py)
维特比算法实现以及提供给UI的服务接口(GodTian_Pinyin.py)
最后的UI实现(gui.py)
技术路线
在中文拼音输入法中,我们需要完成拼音序列到汉字序列的转换,比如输入“nihao”,输入法会给出我们想输入的字“你好”,到这里我们就可以问出几个问题:
**如何切分拼音? **
如: 用户输入”xiana”, 输入法应该判断用户想输入”xian a”(闲啊) 还是”xia na”(夏娜) 还是”xi an a”(西安啊)?
如何实时给用户以反馈?
对于切分好的拼音,怎样找出用户最想输入的一串中文显示给用户?
用户输入的拼音是错的的情况下,如何容忍这种错误?该如何显示?
也许我们还能问出更多的问题,中文拼音输入法就是这样,总有可以继续抠下去的细节。
那么我们如何解决上面的问题?我们的方案如下:
如何切分拼音?
这 里我们暂时采用最长匹配的方式,也就是说,如果用户输入的首个串是拼音或者是某个合法拼音的前缀,那么我们会继续向后发现,等待用户输入,直到用户输完后 发现这个字符(假设是第n个)与原来n-1个不是合法的拼音也不是合法的拼音的前缀,那么此时将前面n-1串切分成拼音,这就完成了一个拼音的发现,比如 说输入”xiant”(想输xiantian),则我们会扫描这个串,一直到”xian”,到”xiant”的时候发现既不是合法拼音的前缀也不是合法拼 音,那么从t前面划分开,得到”xian’t”,同样的道理发现后续的拼音。
在实时任务中,用户即使没有输完我们仍应该显示东西,那么我们先切分 拼音,最多只会有最后一个是不完整的拼音前缀,那么我们将完整的和不完整的分开处理。假设是”xian’t”的情况,我们将”xian”放入 viterbi算法中,通过HMM得出概率最大的一个输出串,然后将最后的”t”在训练过的Trie树中搜索出所有以”t”为前缀的字,以及他们出现的频 率,取频率最高的若干个,作为viterbi算法的下一个状态的可能集合,然后得到他们的拼音,与前面n-1个拼音组合起来跑Viterbi算法,得到最 可能的一个中文串,由于这些频率最高的字的拼音(即我们可能的观测值)可能不相同,我们只能将相同音的字作为一次viterbi算法运行的下一状态,这样 viterbi跑的次数就是这些字里面不同音的个数,但是由于总数固定,异音越多,每个音对应的越少,所以总时间是没有差别的。
具体Trie树会在后面讲解。学习过程中有不懂的可以加入我们的学习交流秋秋圈784中间758后面214,与你分享Python企业当下人才需求及怎么从零基础学习Python,和学习什么内容。相关学习视频资料、开发工具都有分享
如何实时给用户以反馈?
上 面其实已经初步解释了如何实时反馈,实时反馈我们要做的就是用户每输一个字母,我们就能够显示出用户可能想要打的字,那么,以一个字母开头的拼音有很多, 每个拼音对应的字也可能有很多,也即结果有很多,但是我们又不能漏掉,所以只能考虑所有的字,比较选出概率最大的若干个字,这时候我们可以采用Trie树 来解决。Trie树就是前缀树,说白了就是将拼音的字母按顺序顺着根插入到树中,每个叶子节点就是一个拼音,这个拼音就是顺着根一路走下来取的字母的顺序 组合,这样我们就可以找出以任意字符串为前缀的所有拼音,方法就是dfs遍历每一个以其为前缀的子树的叶子节点,这时候我们叶子节点存的其实是一个字 典,key为这个拼音对应的可能的字,value为这个字出现的频率,以作为比较。
对于切分好的拼音,怎样找出用户最想输入的一串中文显示给用户?
这里我们使用隐马尔可夫模型,将用户想输入的中文字作为隐状态,用户输入的拼音为显状态,通过最大似然估计即频率估计出HMM的三个矩阵的值,最后通过viterbi算法找出概率最大的若干个中文字串显示出来。
用户输入的拼音是错的的情况下,如何容忍这种错误?该如何显示?
由于考虑到实现高度容错的复杂性,我们假设用户会输入正确的拼音,在想分割的时候会自行添加分隔符”‘“,由于大部分输入法用户绝大部分时间都会输入正确的拼音,所以,这样一个假设既简化了实现的过程,又没有损失太大的用户体验。
用到的数据
由于训练HMM模型的需要,我们从搜狗实验室找到了SogouQ用户查询数据集,预处理成合法的句子之后大约有360M,且为了避免查询句太短,我们也增加了将近30M的搜狐新闻数据作为训练语料,这里面包含了很多的长句子。
通过这两个语料的训练,我们得到了长句和短句皆可表现较好效果的HMM模型。并且我们还可以继续拓展语料,以增加我们HMM模型的准确性,这是后话,不提。
遇到的问题及解决方案,
UI界面的问题,由于UI设计的复杂性与不同系统的考虑,出现了许多莫名其妙的BUG,这使得我们花了许多时间。
viterbi算法的效率问题,由于以某个字母开头的拼音对应的字有很多个,假设我们取最优的K个,我们需要将这K个与前面已有的拼音组 合,然后跑一遍Viterbi算法,由于Viterbi算法从一个状态转移到另一个状态的计算量很大,我们使用了记忆(cache)的方法来加速,具体方 法就是记录下某一个完整拼音串所对应的viterbi算法的最后一个状态的相关情况,这样如果我们再次遇到这个拼音串(A) 加上另一个拼音(B)跑viterbi的情况,我们就不需要从这个组合串的开头开始跑viterbi算法了,而是直接从A 串跑完viterbi的最后一个状态(从记忆单元读取)开始,向B进行转移。
这个记忆单元会随着程序而一直存在,并且我们对这个对象做了持久化, 在输入法启动时我们会读取这个文件(记忆单元),这也就意味着,如果我们曾经输入过某个拼音串,那么我们以后再输入同样的拼音串的时候,不再需要跑核心算 法,而是直接显示结果,这样在速度上就取得了显著的提高,就会出现,输入法越用越好用,越用越快的好处,当然这牺牲了一些存储空间,但是如今我们都不缺存 储空间。
重复计算的问题,比如在用户觉得打错了的时候,往后退格,这时就会退到某一个前缀,但
是其实这个前缀我们是算过了的,也显示过了的,就是说 我们退回到我们以前显示过的内容的时候,如果不加优化,那么又会重新跑一遍核心的viterbi算法,这样就会很慢,那么我们还是利用cache思想,将 输入的拼音串以及对应的显示结果相对应并且存起来,这样我们就做到了飞速的退格操作。
Python语言固有的性能问题,解决这个问题只有更换语言,事实上用C++语言实现的话我相信会快很多,这在后面可以考虑用C++实现,这也是完全可行的。
性能评价
输入比较迅速,绝大多数输入能在1秒以内显示。输入过的句子再输入和退格操作都是毫秒级别的。
给出程序的运行环境
Python 2.7
需要安装的Python包: Tkinter, cPickle, pypinyin等模块
执行方法及参数
在项目Project目录下,运行
$ python gui.py
即可。
Future Works
由上面我们可以看到其实可以做的工作还很多,比如
改换编译型语言,如C++,大幅减小计算开销
不断随着用户的输入更新HMM模型
将软件嵌入系统中
我们观察到,长句输入很少有多个是想打的,不想短句可能想打的情况很多,所以很多与输入拼音串长度相同的句子我们可以换成短句。
。。。
作者:IT派森
链接:https://www.jianshu.com/p/1106048f47a7
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
python自定义拼音输入法_用Python从0开始实现一个中文拼音输入法相关推荐
- 编辑python用什么输入法_用Python从0开始实现一个中文拼音输入法!
众所周知,中文输入法是一个历史悠久的问题,但也实在是个繁琐的活,不知道这是不是网上很少有人分享中文拼音输入法的原因,接着这次NLP Project的机会,我觉得实现一发中文拼音输入法,看看水有多深,结 ...
- python自定义函数画图_利用Python绘图和可视化(长文慎入)
Python有许多可视化工具,但是我主要讲解matplotlib(http://matplotlib.sourceforge.net).此外,还可以利用诸如d3.js(http://d3js.org/ ...
- 蓝桥杯青少年创意编程python初级考察内容_第十一届蓝桥杯青少年创意编程scratch初级组编程题详解...
点击上方"启迪少儿"即可关注 今年的12月15日是第十一届蓝桥杯青少赛的第二次选拔赛,安徽.北京.福建.广东.广西.河北.黑龙江.湖南.吉林.江苏.江西.辽宁.宁夏.山西.陕西.四 ...
- python输入中文教程_如何用Python从头开始实现一个中文拼音输入法?
中文输入法是一个历史悠久的问题,但也实在是个繁琐的活,不知道这是不是网上很少有人分享中文拼音输入法的原因,接着这次NLP Project的机会,我觉得实现一发中文拼音输入法,看看水有多深,结果发现还挺 ...
- python怎么去掉视频字幕_利用Python实现字幕挂载(把字幕文件与视频合并)思路详解...
其实超简单超简单!python好现成的库,一下子省略了好多步骤! 本文在Windows环境下!linux只是不需要手动输入imagicmagick的位置! 需要用到的环境 python(基本上只要不是 ...
- 【蓝桥杯Python组】2022年第十三届蓝桥杯省赛B组Python解题思路详解
第十三届蓝桥杯省赛B组Python解题思路详解 因为今年采用线上的举办方式进行比赛,所以组委会对题目做了一定的调整,将原来的5道填空+5道编程题变成了2道填空+8道编程题,据说是为了防止抄袭.其实题目 ...
- python正则表达式提取数字比较好_python正则表达式从字符串中提取数字的思路详解...
python从字符串中提取数字 使用正则表达式,用法如下: ## 总结 ## ^ 匹配字符串的开始. ## $ 匹配字符串的结尾. ## \b 匹配一个单词的边界. ## \d 匹配任意数字. ## ...
- python处理excel大数据-Python实现大数据收集至excel的思路详解
一.在工程目录中新建一个excel文件 二.使用python脚本程序将目标excel文件中的列头写入,本文省略该部分的code展示,可自行网上查询 三.以下code内容为:实现从接口获取到的数据值写入 ...
- python virtualenv conda_在vscode中启动conda虚拟环境的思路详解
问题:cudatoolkit cudnn 通过conda 虚拟环境安装,先前已经使用virtualenv安装tf,需要在conda虚拟环境中启动外部python虚拟环境 思路:conda prompt ...
最新文章
- access数据类型百度百科_Access数据库属于什么数据库。
- 自定义Spark Partitioner提升es-hadoop Bulk效率——续
- python3.7安装wordcloud_Python中的wordcloud库安装问题及解决方法
- android源码settings中显示所有正在运行进程流程分析
- SAP ABAP Platform 1909最新版的 docker 镜像
- android封装好的Color类中的常量
- String和ByteBuffer互转
- ubuntu 编译android .img_全网可用交叉编译工具链大全
- codeIgniter3 学习笔记二(基于 MVC 开发模式实现小案例)
- R60笔记本电脑风扇清理加油过程
- matlab鼠标中键不能放大缩小,proe鼠标中键不能缩放如何解决
- 首席新媒体黎想教程:如何打造爆款裂变活动推广?
- 解决to_csv循环追加数据不会覆盖前面的数据
- 发现一个国外用来做参与式及知识迁移的网络课件 messenger-education
- C# 实现Excel单元格画边框
- 动态设置html样式或style具体属性
- 算法基础——1.4常数变易法
- verilog并行数据转换为串行输出
- ios备忘录下载安卓版_安利3款手机实用软件,安卓和ios都有份
- iOS ipv4和ipv6转换
热门文章
- 正面刚甲骨文?那不是华为GaussDB的格局
- 【ABC科创企业案例】高科数聚:把脉消费者视角,洞悉消费力趋向
- 使用xlsxwriter库将数据存储到excel
- html div隐藏滚动条不能使用,CSS隐藏滚动条但不影响正常滚动
- 机器学习特征工程之特征抽取
- 从0开始手把手带你入门Vue3-全网最全(1.1w字)
- 华为无线设备AC6605局域网WLAN网络部署-模拟器演示
- pdf加水印怎么加?3个方法你可以看看
- java小魔女大冒险_小魔女大冒险,小魔女大冒险下载,小魔女大冒险官网,礼包,活动,图片,评测,专区,论坛 - 酷酷跑手机游戏...
- SQL server基本的代码操作