• HMM 拼音输入法


    拼音输入法案例

    https://zhuanlan.zhihu.com/p/25132270

    https://github.com/LiuRoy/Pinyin_Demo

    在网上看到一篇关于隐马尔科夫模型的介绍,觉得简直不能再神奇,又在网上找到大神的一篇关于如何用隐马尔可夫模型实现中文拼音输入的博客,无奈大神没给可以运行的代码,只能纯手动网上找到了结巴分词的词库,根据此训练得出隐马尔科夫模型,用维特比算法实现了一个简单的拼音输入法。githuh地址:LiuRoy/Pinyin_Demo

    原理简介

    隐马尔科夫模型

    抄一段网上的定义:

    隐马尔可夫模型 (Hidden Markov Model) 是一种统计模型,用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中确定该过程的隐含参数,然后利用这些参数来作进一步的分析。

    拼音输入法中可观察的参数就是拼音,隐含的参数就是对应的汉字。

    viterbi算法

    参考https://zh.wikipedia.org/wiki/维特比算法,思想是动态规划,代码比较简单就不赘述。

    优化版

    https://github.com/fanqingsong/pinyin_input_method

    模型训练

    在 corpus 目录中, 保存了一份 dict.txt, 为删减版本的jieba词库。

    此词库为默认训练词库。

    另外一个为 dict.backup.txt为原来repo的词库, 太大,训练时间太长。 所以调试阶段不适用。

    模型所在数据库有也对应两个 hmm.sqlite hmm.backup.sqlite

    运行命令

    ./bin/run.sh hmm/train.py
    

     

    viterbi实现

    代码建hmm/viterbi.py文件,此处会找到最多十个局部最优解,注意是十个局部最优解而不是十个全局最优解,但是这十个解中最优的那个是全局最优解,代码如下:

    def viterbi(pinyin_list):
        """
        viterbi算法实现输入法
    
        Args:
            pinyin_list (list): 拼音列表
        """
    
        # query the char-prob pair
        # char must in starting table, named as start_char
        # prob = start_char prob * emit_prob
        # emit_prob is the probability that start_char emit to the start_pinyin
        start_pinyin = pinyin_list[0]
    
        start_char = Emission.join_starting(start_pinyin)
        print("------ start_char -------")
        print(start_char)
    
        V = {char: prob for char, prob in start_char}
    
        print("------ V -------")
        print(V)
    
        print("
    
    ")
    
        # let's count from the second pinyin to calc viterbi matrix
        for i in range(1, len(pinyin_list)):
            pinyin = pinyin_list[i]
    
            print("------ i -------")
            print(i)
    
            print("------ pinyin -------")
            print(pinyin)
    
            prob_map = {}
    
            for phrase, prob in V.iteritems():
                print("------ phrase -------")
                print(phrase)
    
                print("------ prob -------")
                print(prob)
    
                prev_char = phrase[-1]
    
                # only get the most possible next_char, with highest probability
                result = Transition.join_emission(pinyin, prev_char)
                print("------ result -------")
                print(result)
    
                if not result:
                    continue
    
                # next_prob = transfer probability(pre_char -> next_char) * emission probability(next_char -> pinyin)
                next_char, next_prob = result
                print("-------- next_char --------")
                print(next_char)
    
                # make new V of new char path, ie phrase.
                prob_map[phrase + next_char] = next_prob + prob
    
            if prob_map:
                # update V, in order to do further research
                V = prob_map
            else:
                return V
    
            print("
    
    ")
    
        return V

     

    结果展示

    运行文件,简单的展示一下运行结果:

    ./bin/run.sh hmm/viterbi.py
    

    输出

    root@xxx:~/win10/mine/pinyin_input_method# ./bin/run.sh hmm/viterbi.py
    PYTHONPATH=/usr/local/spark/python:/usr/local/spark/python/lib/py4j-0.10.4-src.zip::/root/win10/mine/pinyin_input_method
    input:duan yu
    ------ start_char -------
    [(u'u77ed', -8.848355540206123), (u'u6bb5', -8.848355540206123)]
    ------ V -------
    {u'u6bb5': -8.848355540206123, u'u77ed': -8.848355540206123}
    
    
    ------ i -------
    1
    ------ pinyin -------
    yu
    ------ phrase -------
    段
    ------ prob -------
    -8.84835554021
    ------ result -------
    (u'u8a89', -0.1840036429769394)
    -------- next_char --------
    誉
    ------ phrase -------
    短
    ------ prob -------
    -8.84835554021
    ------ result -------
    (u'u8bed', 0.0)
    -------- next_char --------
    语
    
    
    短语 -8.84835554021
    段誉 -9.03235918318
    input:
    bye bye
    
    

    汉字转拼音(pypinyin)

    https://github.com/mozillazg/python-pinyin

    >>> from pypinyin import pinyin, lazy_pinyin, Style
    >>> pinyin('中心')
    [['zhōng'], ['xīn']]
    >>> pinyin('中心', heteronym=True)  # 启用多音字模式
    [['zhōng', 'zhòng'], ['xīn']]
    >>> pinyin('中心', style=Style.FIRST_LETTER)  # 设置拼音风格
    [['z'], ['x']]
    >>> pinyin('中心', style=Style.TONE2, heteronym=True)
    [['zho1ng', 'zho4ng'], ['xi1n']]
    >>> pinyin('中心', style=Style.TONE3, heteronym=True)
    [['zhong1', 'zhong4'], ['xin1']]
    >>> pinyin('中心', style=Style.BOPOMOFO)  # 注音风格
    [['ㄓㄨㄥ'], ['ㄒㄧㄣ']]
    >>> lazy_pinyin('中心')  # 不考虑多音字的情况
    ['zhong', 'xin']
    >>> lazy_pinyin('战略', v_to_u=True)  # 不使用 v 表示 ü
    ['zhan', 'lüe']
    # 使用 5 标识轻声
    >>> lazy_pinyin('衣裳', style=Style.TONE3, neutral_tone_with_five=True)
    ['yi1', 'shang5']

    jieba词库

    https://github.com/fxsjy/jieba/tree/master/jieba

    算法

    • 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG)
    • 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合
    • 对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法

    https://raw.githubusercontent.com/fxsjy/jieba/master/jieba/dict.txt

    AT&T 3 nz
    B超 3 n
    c# 3 nz
    C# 3 nz
    c++ 3 nz
    C++ 3 nz
    T恤 4 n
    A座 3 n
    A股 3 n
    A型 3 n
    A轮 3 n
    AA制 3 n
    AB型 3 n
    B座 3 n
    B股 3 n
    B型 3 n
    B超 3 n
    B轮 3 n
    BB机 3 n
    BP机 3 n
    C盘 3 n
    C座 3 n
    C语言 3 n
    CD盒 3 n
    CD机 3 n
    CALL机 3 n
    D盘 3 n
    D座 3 n
    D版 3 n
    E盘 3 n
    E座 3 n
    E化 3 n
    E通 3 n
    F盘 3 n
    F座 3 n
    G盘 3 n
    H盘 3 n
    H股 3 n
    I盘 3 n
    IC卡 3 n
    IP卡 3 n
    IP电话 3 n
    IP地址 3 n
    K党 3 n
    K歌之王 3 n
    N年 3 n
    O型 3 n
    PC机 3 n
    PH值 3 n
    SIM卡 3 n
    U盘 3 n
    VISA卡 3 n
    Z盘 3 n
    Q版 3 n
    QQ号 3 n
    RSS订阅 3 n
    T盘 3 n
    出处:http://www.cnblogs.com/lightsong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    <二>实现用户的增删改查接口
    <十二>vueadmintemplate
    Minimal Api<五> 添加模型验证(fluentValidate)
    <一>权限表的相关设计
    <十一>请求 axios
    Minimal Api<三>创建仓储层
    Minimal Api<二>解耦api代码,统一使用服务类注入
    Minimal Api<四>修改服务层并调用仓储层实现操作数据库
    Minimal Api<一>创建项目结构和相关插件配置
    <二>基本概念
  • 原文地址:https://www.cnblogs.com/lightsong/p/14690240.html
Copyright © 2020-2023  润新知