拼音输入法的简单实现可以归结为使用维特比算法求解汉字隐马尔可夫模型的问题:将用户输入的拼音转换为字层,使用维特比算法求解得到概率最大的一个“字链”,这个“字链”便是拼音输入法输出的文字。主要的几个步骤包括:

1、语料数据的预处理:把语料内容从文件列表中抽取出来,分句,去掉非中文字符。2、在所有语料中,计算每个汉字的出现频次。3、在所有语料中,计算当前汉字与其前面的汉字共同出现的频数,并计算其频率。4、建立输入拼音与汉字的匹配关系,构造输入拼音对应汉字的隐马尔科夫模型。5、使用维特比算法求解,得到概率最大的一个“字链”,取这个“字链”为输出的句子。6、测试准确率。

1 代码构造

根据需求和实现步骤,写3个python程序。

第一个根据输入的语料库,计算汉字出现的频次、汉字与前一个汉字共同出现的频次和语料库的总字数。

第二个,首先根据“拼音汉字表”构造拼音与汉字的对应关系,将用户输入的拼音通过这个对应关系形成一个隐马尔科夫模型。根据第一个程序得出的结果,使用维特比算法,计算得到概率最大的“字链”,将这个“字链”输出为句子。

第三个,使用测试数据集,测试输入法的准确率和整句准确率。

代码结构如下。

2 实现过程

2.1 数据预处理

模型使用2016年2月、4-11月共9个月的新浪新闻语料数据进行模型训练。在训练之前,使用re.split()对语料中每一条新闻进行分句,分句依据为特定的标点符号,作为分句的标点为:(1)中文标点“:”、“。”、“……”、“,”、“?”、“、”(2)英文标点:“:”、“,”“!”、“?”。

由于只考虑6763个一二级汉字,为提高模型的可靠性,在分句时,如果这句话出现基本汉字之外的汉字,则不将这句话纳入模型训练。另外,使用“零一二三四五六七八九”代替阿拉伯数字“123456789”。同时,在每一句话中去掉所有非中文字符。对每一个数据集的每一条新闻都做同样的分句和数据处理,得到训练句子集。

2.2 生成汉字频数矩阵

对于已经得到的句子集合,以一二级汉字为统计对象,统计每个汉字的频数、每个汉字出现在句首的频数、当前汉字与前一汉字共同出现的频数、所有汉字的累计出现频数,分别定义hzarray、headarray、hzmatrix和totalNum 4个变量来存储这些数据。hzarray、headarray是数组形式,hzmatrix是矩阵形式。

2.3 生成汉字的隐马尔科夫模型

根据拼音汉字表,生成拼音与汉字对应关系的字典,并将输入的每一个拼音转化为对应的所有汉字。假设在一个句子中,每一个汉字的出现仅与前一个汉字有关,以每一个拼音所对应的汉字作为字链中的一层,生成汉字的隐马尔科夫模型。句首汉字的出现概率与其自身出现的概率与出现在句首的概率有关,用λ1来调节。同时,在计算概率时,将相应汉字的频次从各频次矩阵中提取出来,计算各个汉字出现的频率。由于总的汉字数超过4亿,在这里将上述两个概率以频率近似以频率代替。

在完成计算后,得到汉字的隐马尔科夫模型λ=(A,B,π),其中,状态转移矩阵A为当前汉字与前一汉字共同出现的概率矩阵,观测矩阵B为当前汉字出现的概率。初始矩阵π为句首汉字概率矩阵。其计算公式如下:

汉字的隐马尔科夫链如下图。

2.4 构建维特比函数

在拼音输入时,使用.lower()函数将输入的拼音转化为小写。

(1)对第一个节点,有:

若只有一个拼音输入,取δ1(i)最大的节点,即:

当输入两个以上的汉字时,先考虑句首汉字的概率,在完成过程(1)的基础上,完成如下过程。

(2)从第2个节点开始,有:

(3)终止,得到:

(4)通过iT*,对t=T-1, T-2,...,1进行最优路径回溯:

通过以上过程,得到字链的最佳路径I*=(i1*,i2*,...iT*),由I*查找对应的汉字,即可以组成输出的句子。

在写代码时, 放到同一个数组p_num中, 放在同一个矩阵p中。

2.5 构造测试函数

使用Levenshtein.hamming()计算实际汉字和拼音输入法输出汉字之间对应位置上不同字符的个数,用该段汉字总数减去不相符汉字的总数,得到该段汉字字符相同的汉字数。对每段汉字进行上述操作,加总除以总字数,得到准确率。整句准确率以完全相同的句子数量除以句子总数得到。

3 实现效果

在实现上,构建了testinput()和testaccuracy()两个函数。test_input()实现在命令行中输入拼音,输出汉字的效果。

testaccuracy()用作准确率测试。使用拼音数据inputdomo1.txt进行测试,取λ1=0.8,准确率为78.1%,整句准确率为25.6%。

使用新浪新闻的拼音数据input_domo2.txt测试,取λ1=0.5,拼音输入法准确率达到86.4%,整句准确率达到47.4%。

4 效果好的和效果差的,对比分析

在未分句时,使用整段新闻去掉标点和生僻字后得到的输出汉字,输入拼音“wo ai ni”会出现“我哎你”的情况。

分析发现,出现在一句话的句末的频次较高的字与出现在句前频次较高的字会有较高的概率共同出现在一起。所以,最终在计算各汉字频次时,使用分句的形式进行。为提高准确率,把阿拉伯数字转化为汉字数字,当句子中出现不在一二级汉字表中的汉字时,不将这句话纳入计算中。虽然计算时间基本不变,但是计算准确率得到提高。

同样,由于训练语料库的特点,与训练语料库同一来源新浪新闻测试集的准确率显著高于其他随机输入的拼音测试集。对于新闻中出现的热词准确率很高。

5 对照参数选择,性能分析

更改值,使用拼音数据input_domo1.txt进行测试,发现准确率变化幅度不大(如下图),但是取λ1=0.8时,准确率能够达到一个极大值。

6 总结收获

这是我人工智能课的第一次大作业,花了很多时间,也学到了不少东西。这门课我三次作业成绩也都还不错,发上来一是为了记录在公众号上,充实一下公众号的内容,提高一下公众号水平;二是也是提高我自己的自信:文科同学也能学好数学,写好代码……

实践是最好的老师。通过本次学习,提高了对马尔科夫过程、隐马尔科夫模型、维特比算法的理解,对python的编程也更为熟练。

同时,由于数据量较大,写循环函数时代码极容易出错,应该在完成一段代码后立即测试。在调试代码的过程中,曾出现过汉字与前一个汉字共同出现次数大于单个汉字出现次数的情况,原因在于在计算频次时有一个变量出现错误。另外,在维特比算法的计算过程中,出现的index较多,容易弄乱,在循环计算中对应关系也应该小心,否则极易出现错误。付出极高的时间成本。

另外,对于变量的命名最好规范,做好规划,否则变量太多后容易出错。

8 改进方案

备选汉字可以不局限于一二级汉字表,使用包含20902个汉字的基本汉字表,可以提高输入法的适用性。另外,语料库可以不局限于新闻语料,类型更为多样的语料库可以提高输出句子的准确率和整句正确率。基于字的二元模型可以换成三元甚至更多,也能够进一步提高句子的准确率和整句正确率。

用Python写一个拼音输入法相关推荐

  1. python假如输入错误重新输入_用Python写一个拼音输入法

    拼音输入法的简单实现可以归结为使用维特比算法求解汉字隐马尔可夫模型的问题:将用户输入的拼音转换为字层,使用维特比算法求解得到概率最大的一个"字链",这个"字链" ...

  2. python手机编程输入法_用Python写一个拼音输入法

    拼音输入法的简单实现可以归结为使用维特比算法求解汉字隐马尔可夫模型的问题:将用户输入的拼音转换为字层,使用维特比算法求解得到概率最大的一个"字链",这个"字链" ...

  3. 用python写一个拼音编辑器(.py版|我会把这个文件的exe版发到评论区的|随时更新|最旧1.0.1|1.0.1)

    我就写个目录吧! 目录 第一步:定义.赋值.导入 第二步:创建窗口 第三步:设置文本输入口 第四步:定义按钮反应 第五步:做按钮.输出区 第六步:窗口循环展示 最终代码(源代码):在打包成exe的时候 ...

  4. 用Python写一个命令行火车票查看器

    Linux编程点击右侧关注,免费入门到精通! 作者丨protream https://www.jianshu.com/p/f411d7e10c41 当你想查询一下火车票信息的时候,你还在上12306官 ...

  5. python写一个通讯录step by step V3.0

    python写一个通讯录step by step V3.0 更新功能: 数据库进行数据存入和读取操作 字典配合函数调用实现switch功能 其他:函数.字典.模块调用 注意问题: 1.更优美的格式化输 ...

  6. python俄罗斯方块算法详解_用 Python 写一个俄罗斯方块游戏 (

    @@ -2,34 +2,34 @@ > * 原文作者:[Dr Pommes](https://medium.com/@pommes) > * 译文出自:[掘金翻译计划](https://g ...

  7. python编写测试工具-python 写一个性能测试工具(一)

    国庆重新学习了一下go的gin高性能测试框架. 用JMeter来测试gin与flask接口的性能,差别很大. 为什么我自己不尝试写一个性能工具,性能工具的核心就是 并发 和 请求. 请求可以选择Pyt ...

  8. pythongui登录界面密码显示_用python写一个带有gui界面的密码生成器

    需要用到的库: tkinter:构建gui界面 pyperclip:复制功能 random:生成随机数 string:处理字符串 代码: from tkinter import * import ra ...

  9. python写一个通讯录V2.0

    python写一个通讯录step by step V2.0 引用知识 list + dict用于临时存储用户数据信息 cPickle用于格式化文件存取 依旧使用file来进行文件的存储 解决问题 1. ...

最新文章

  1. P1102 A-B 数对(二分,映射)难度⭐
  2. 注意力机制取代卷积网络,预测准确性提升超30%
  3. 洛谷P1832 A+B Problem(再升级)
  4. mysql判断视图是否存在_使用JDBC查询是否存在某表或视图,按月动态生成表
  5. 隔行换色案例||全选和全不选||QQ表情选择||多选下拉列表左右移动
  6. 如何一次性复制带有markdown/mathjax/latex的博客内容
  7. 函数 devm_kzalloc()
  8. 京东到家发布618消费预测报告:原来这个时间点大多人在摸鱼?
  9. vue中ast生成render
  10. 测绘 绘图 计算机,CAD及制图测绘工程制图
  11. 系统分析师知识点汇总
  12. 流程图用什么软件做?好用的流程图软件盘点
  13. python:talib 计算 SAR 用 pro_api
  14. 怎样写一个lemon的spj
  15. 纽约州立石溪分校计算机科学排名,美国纽约州立大学石溪分校排名_2019纽约州立大学石溪分校排名(USNews排名)...
  16. 让学前端不再害怕英语单词(四)
  17. Unity中模型的面数问题
  18. Unity3d 所有版本下载
  19. 作业1开发一个简单的python计算器
  20. laravel-excel使用3(老猫包子店的故事)

热门文章

  1. 曾经改变了千万人的人生经典语录
  2. 构建一阶谓词逻辑和有限域上多项式方程的同构
  3. Qt编写安防视频监控系统61-子模块5设备控制
  4. 企业文件加密软件如何做到根源防止泄密?全面专业的数据防泄密方案怎么选
  5. 转大神的日志 【大杂烩】杂7杂8的东西
  6. EEPROM,NAND,NOR,QSPI FLASH的区别
  7. 手把手教你整合SSM实现一个简单的CRUD项目
  8. matlab中ode的用法,关于matlab 的ode45用法
  9. matlab中ode指令,在Matlab中使用ODE选择步长
  10. Java实现Telegram机器人