Skip to content

scikkk/pinyin-input-method

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

拼音输入法 - Scik

1 基本功能

基于HMM的拼音输入法,数字0-9选择候选序列,空格键选择0号候选,减号键-向前翻页,等号键=向后翻页。

2 系统特色

  1. 实时、高效,能够即时生成候选汉字序列。
  2. 准确的排序,基本能保证目标语句出现在第一页候选汉字序列中。
  3. 支持长序列。
  4. 支持自动纠错。
  5. 根据分词结果在原拼音序列中插入',更加用户友好。

3 使用介绍

安装依赖后直接运行main.py即可。

pip install -r requirements.txt

配置文件src\conf\config.py

TRAIN_CONFIG = {
    'intact_weight': 21,  # 训练时全拼的权重
    'zcs_weight': 6,  # 训练时['zh','ch','sh']的权重
    'first_weight': 4,  # 训练时首字母的权重
}  # 训练时不同拼音所占的权重

CUT_CONFIG = {
    'has_correct': True,# 选择是否需要自动纠错
    'has_first': True,  # 选择是否支持首字母拼写
    'has_zcs': True,  # 选择是否支持['zh','ch','sh']拼写
}  

IME_CONFIG = {
    'max_pinyin_len': 52,  # 选择输入法支持的最长的拼音序列
    'candidate_per_page': 10  # 每页最多显示的候选汉字序列条数
}

4 代码模块的功能划分与描述

MYPINYIN
│
│  all_requirements.txt  // 由pip freeze生成的依赖requirements.txt  // 由pipreqs生成的依赖
├─db
│  │  correct.txt  // 用于更正错误拼音的规则
│  │  pinyin.txt  // 拼音表
│  │  preprocess.py  // 预处理数据文件的代码
│  │  wordfreq.txt  // 根据原始语料数据计算出的词频表
│  └─corpus  // 原始语料数据
├─model  // 训练得到的模型
│  │  emission_log_probability.json  // 从汉字到拼音的发射概率矩阵
│  │  start_log_probability.json  // 初始概率矩阵     
│  │  transition_log_probability.json  // 从前一个字推测后一个字的状态转移矩阵
│  └─reversecompute_nxt.json  // 根据上一个字和拼音推测最可能的下一个字reversed_emission.json  // 从拼音到汉字的发射概率矩阵reversed_transition.json  // 从后一个字推测前一个字的状态转移矩阵  
├─pathmypinyin.pth  // 用于解决python解释器找不到自建模块的问题
└─src  // 源代码main.py  // 程序入口
   ├─conf  // 配置模块config.py  // 输入法的可选配置
   ├─hmm  // 隐马尔可夫模型模块
   │  │  hmm.py  // 用viterbi算法转换拼音
   │  └─train  // 模型训练模块freqdata.py  // 用于获取词频数据对数据库进行抽象封装train.py  // 用于计算HMM模型所需要的参数结构保存在model文件夹下
   ├─interface  // 输入法界面的模块ime.py  // 输入法主程序imeui.py  // 输入法UI界面由imeui.ui自动生成imeui.ui  // 输入法UI界面
   ├─split  // 分割拼音的模块pycut.py  // 用于分割拼音的模块
   └─util  // 工具
         tools.py  // 加载文件保存文件等通用函数

5 方案描述

5.1 数据

5.1.1 语料获取

原始数据来源:https://github.com/brightmart/nlp_chinese_corpus

使用了其中的wiki2019zhwebtext2019zh

语料保存在db\corpus

5.1.2 数据清洗与整合

原始数据是json格式,直接处理开销较大,我们利用正则表达式提取其中的中文字符。

chinese = re.compile(
    r'[\d\
        |\u4e00-\u9fa5\
        |\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b\
        |\n\
      ]'
)

原始的语料由多个小文件组成,我们将其合并,然后利用jieba分词将原文分割成一个个词语,并且在此基础上计算每个词出现的次数,最终得到词频文件db\wordfreq.txt

源代码在db\preprocess.py,生成的文件形如:

的 49026416
是 13385754
我 12141126
了 11858449
在 9083079
有 6375791
…… ……
5.1.3 数据封装

为模型训练提供统一的数据接口,构建一个迭代器,每次调用返回一个(word,word_frequency)二元组,源代码在src\hmm\train\freqdata.py

words_path = 'db\\wordfreq.txt'
def wordfreq() -> tuple:
    """ Word frequency data set, iteratively return (word, freq). """
    with open(words_path, 'r', encoding='utf-8') as fr:
        for line in fr:
            word, frequency = line.split()
            yield word, int(frequency)

5.2 拼音划分

根据输入的拼音序列生成候选的汉字序列,首先要将输入的长拼音序列分割成一个个单独的拼音。

5.2.1 划分方法

参考 再谈Python之拼音拆分 - 简书 (jianshu.com)

使用最简单的递归方式,提供一个pinyin_table,从头开始遍历拼音序列,每当遇到一个在pinyin_table出现的拼音,就递归地继续划分剩下的序列,直到划分完。代码位于src\split\pycut.py

5.2.2 pinyin_table的选择

基础的拼音表保存在db\pinyin.txt中,除此之外,为了支持首字母拼写,还增加了如下两个拼音表:

first_pytable = ('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm',
                 'n', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z')
zcs_pytable = ('zh', 'sh', 'ch')
5.2.3 自动纠错

根据日常经常出现的拼音错误情况,总结出替换表db\correct.txt,如果在配置中选择了自动纠错,会在划分前安装替换表中的规则进行纠错。

注意:自动纠错只是增加了纠错后的转换结果,用-=键前后翻页可以找到纠错前的拼音得到的转换结果,这样即使本不应该纠错也无伤大雅。

5.3 HMM模型

5.3.1 训练

训练代码位于src\hmm\train\train.py,计算出的矩阵保存在model目录下。此处用数据集中计算出的频率估计真实的概率,为了便于计算,保存的都是原概率的自然对数。为了保证输入法的实时高效,提前将所有由前一个字和后一个字的拼音推测后一个汉字的结果保存在model\reverse\compute_nxt.json中,后续转换拼音序列时直接查表即可。

  1. start_log_probability.json

    首字出现的概率:

    {
        "一": -3.8405453029044274,
        "丁": -9.536892549273839,
        ……
        "龥": -19.790367735448843
    }
  2. transition_log_probability.json

    由前一个字推测后一个字的概率:

    {
        "一": {
            "一": -6.41359328062042,
            "丁": -8.180800311192229,
            ……
            "龛": -13.794333850385367,
            "龟": -14.199798958493531
        },
        ……
    }
  3. emission_log_probability.json

    由汉字推测其拼音的概率:

    {
        "一": {
            "y": -1.8325814637483102,
            "yi": -0.1743533871447778
        },
        "丁": {
            "d": -1.8325814637483102,
            "ding": -0.1743533871447778
        },
        ……
    }
  4. reversed_emission.json

    由拼音推测汉字的概率:

    {
        "a": {
            "侒": -1.8325814637483102,
            "俺": -1.8325814637483102,
            ……
            "鼇": -1.8325814637483102
        },
    	……
    }
  5. reversed_transition.json

    由后一个字推测前一个字的概率:

    {
        "一": {
            "一": -4.453024061737384,
            "丁": -9.47711231723801,
            ……
            "龚": -10.681085121563946
        },
        ……
    }
  6. compute_nxt.json

    由前一个字和后一个字的拼音推测后一个汉字的概率:

    {
        "一": {
            "a": [
                "",
                -10.721640535695247
            ],
            "ai": [
                "",
                -11.586059436862563
            ],
            ……
            "zuo": [
                "",
                -5.6612005031209405
            ]
        },
        ……
    }
5.3.2 转换

使用维特比算法,具体代码位于src\hmm\hmm.py

5.4 交互界面

5.4.1 主程序

实现keyReleaseEvent函数,每次有按键释放就调用HMM将当前的拼音序列转化为汉字序列。

5.4.2 图形界面

采用PyQt5进行编写,利用designer.exe进行界面设计,保存为src\interface\imeui.ui,然后用命令

pyuic5.exe .\src\interface\imeui.ui -o .\src\interface\imeui.py

生成python文件src\interface\imeui.py

6 实现效果

6.1 全拼效果

image-20220710154917038

6.2 首字母效果

image-20220710160018976image-20220712004831098

6.3 混合拼音效果

image-20220710155236180

7 遇到的问题

python解释器找不到自建模块,最后解决方法是:

path\mypinyin.pth文件放入目录D:\Users\86176\anaconda3\Lib\site-packages,文件内容是

D:\_WangKe\0\mypinyin\src

即将项目路径加入运行环境,使解释器能够找到自建模块。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages