zoukankan      html  css  js  c++  java
  • 使用kenlm进行文本纠错

    简介

    1. kenlm是Kenneth Heafield个人开发的语言模型工具,参考:https://kheafield.com/code/kenlm/
    2. GitHub: https://github.com/kpu/kenlm

    安装流程省略

    文本纠错应用

    模型训练

    • 准备数据
      • 哈工大信息检索研究中心(HIT CIR)语言技术平台共享资源
      http://ir.hit.edu.cn/demo/ltp/Sharing_Plan.htm
      http://ir.hit.edu.cn/demo/ltp/HIT-CIR_LTP_Corpora_Sample_v1.rar
      
      • 使用prepare.py脚本预处理,处理成如下的格式
      中 国 开 展 登 月 计 划 的 意 义
      神 舟 五 号 载 人 飞 船 带 着 亿 万 炎 黄 子 孙 的 期 盼 遨 游 九 天 。
      关 于 月 亮 的 咏 叹 比 比 皆 是 :
      我 国 古 代 , 帝 王 就 有 春 天 祭 日 、 秋 天 祭 月 的 礼 制 。
      在 民 间 , 每 逢 八 月 中 秋 , 也 有 拜 月 或 祭 月 的 风 俗 。
      关 于 月 球 的 传 说 家 喻 户 晓 :
      
    • 训练模型:文本以单字切分,使用n-gram
    bin/lmplz -o 2 --text ./data.txt  --arpa lm.arpa -S 80% --discount_fallback
    
    -o 指定n-gram
    -S 指定使用多少内存
    --discount_fallback 需要指定 不然会报下面的错
    
    Unigram tokens 205390 types 2106
    === 2/5 Calculating and sorting adjusted counts ===
    Chain sizes: 1:25272 2:18370318336 3:34444349440 4:55110959104
    /data/xqchen4/3rd/kenlm/lm/builder/adjust_counts.cc:60 in void lm::builder::{anonymous}::StatCollector::CalculateDiscounts(const lm::builder::DiscountConfig&) threw BadDiscountException because `discounts_[i].a
    mount[j] < 0.0 || discounts_[i].amount[j] > j'.ERROR: 4-gram discount out of range for adjusted count 3: -29.239872.  This means modified Kneser-Ney smoothing thinks something is weird about your data.  To override this error for e.g. a class-based model, r
    erun with --discount_fallback
    
    • 模型压缩
    bin/build_binary -s lm.arpa lm.bin
    

    demo应用测试

    • 详细请参考evaluation.py
    代码示例:
    # 使用kenlm进行文本纠错
    import kenlm
    import json
    
    def correction(lm,sentence,dict):
        result = []
        s1 = lm.perplexity(" ".join(sentence))
        for i in range(len(sentence)):
            cur_word = sentence[i]
            if cur_word not in dict:
                continue
            cur_candidates = []
            for candi in dict[cur_word]:
                new_sentence = sentence
                new_sentence[i] = candi
                s2 = lm.perplexity(" ".join(new_sentence))
                if s2 < s1:
                    cur_candidates.append({
                        "original":cur_word,
                        "correction":candi,
                        "position":i,
                        "perplexity":s2
                    })
            #存在多个候选结果,则按照perplexity得分进行排序,取top1结果
            if len(cur_candidates) > 1:
                cur_candidates.sort(key = lambda e:e.__getitem__('perplexity'))
            if len(cur_candidates) > 0:
                result.append(cur_candidates[0])
        return result
    
    if __name__ == "__main__":
        #提前训练好的模型
        lm_model_path = "./model/lm.bin"
        #别字词典
        similarity_dictionary = {"泳":["永","咏"],"事":["是"]}
        sentence = "关于月亮的泳叹比比皆事"
        #加载模型
        lm = kenlm.Model(lm_model_path)
        #别字纠错计算
        result = correction(lm,list(sentence),similarity_dictionary)
        if result:
            result.sort(key=lambda e: e.__getitem__('perplexity'))
            print(json.dumps(result,ensure_ascii=False,indent=2))
    

    Reference

  • 相关阅读:
    Android入门第六篇之ListView
    谷歌Volley网络框架讲解——第一篇
    Android网络通信库Volley简介
    Android网络通信框架Volley的学习笔记
    SharedPreferences介绍
    Android之Adapter用法总结
    ANDROID SQLITEOPENHELPER详解
    RxJava、RxBus学习
    【原创】【Andriod】自定义多行多列视图
    [转]android笔记--Intent和IntentFilter详解
  • 原文地址:https://www.cnblogs.com/duothink/p/14303130.html
Copyright © 2011-2022 走看看