Day14 : 语言模型的训练与预测

作者:长行
时间:2020.05.08

简单来说,语言模型就是通过统计已经分词的语料库中一元语法和二元语法出现的频次,实现对句子的分词。

下面我们使用HanLP的相关模块实现语言模型的训练和预测。

训练

训练是指根据给定样本集估计模型参数的过程,简单来说,在语言模型中就是统计二元语法出现的频次和一元语法出现的频次。

首先,我们使用HanLP的CorpusLoader.convert2SentenceList加载语料库(空格分词格式)。

from pyhanlp import *
CorpusLoader = SafeJClass("com.hankcs.hanlp.corpus.document.CorpusLoader")  # 语料库加载Java模块corpus_path = "data\my_cws_corpus.txt"  # 语料库所在路径
sentences = CorpusLoader.convert2SentenceList(corpus_path) # 返回List<List<IWord>>类型
for sent in sentences:print(sent)

运行结果:

[商品, 和, 服务]
[商品, 和服, 物美价廉]
[服务, 和, 货币]

接着,我们使用HanLP的NatureDictionaryMaker统计一元语法和二元语法。

NatureDictionaryMaker = SafeJClass("com.hankcs.hanlp.corpus.dictionary.NatureDictionaryMaker")  # 词典模型Java模块(统计一元、二元语法)model_path = "data\my_cws_model"  # 语言模型存储路径
for sent in sentences:for word in sent:if word.label is None:word.setLabel("n")  # 赋予每个单词一个虚拟的n词性用作占位
maker = NatureDictionaryMaker()  # 构造NatureDictionaryMaker对象
maker.compute(sentences)  # 统计句子中的一元语法、二元语法
maker.saveTxtTo(model_path)  # 将统计结果存储到路径

运行后在程序目录中的data目录中,新建一元语法模型(my_cws_model.txt)、二元语法模型(my_cws_model.ngram.txt)和词性标注相关文件(my_cws_model.tr.txt)文件。

预测

预测是指利用模型对样本进行推断的过程,简单来说,就是通过我们之前统计的一元语法和二元语法的频次,推断句子的分词序列。

首先,我们使用HanLP的CoreDictionary和CoreBiGramTableDictionary加载刚才训练的语言模型。

HanLP.Config.CoreDictionaryPath = model_path + ".txt"  # 一元语法模型路径
HanLP.Config.BiGramDictionaryPath = model_path + ".ngram.txt"  # 二元语法模型路径
CoreDictionary = LazyLoadingJClass("com.hankcs.hanlp.dictionary.CoreDictionary")  # 加载一元语法模型Java模块
CoreBiGramTableDictionary = SafeJClass("com.hankcs.hanlp.dictionary.CoreBiGramTableDictionary")  # 加载二元语法模型Java模块
print(CoreDictionary.getTermFrequency("商品"))  # 测试"商品"的一元语法频次
print(CoreBiGramTableDictionary.getBiFrequency("商品", "和"))  # 测试"商品 和"的二元语法频次

运行结果:

2
1

词网是HanLP提出的特指句子中所有一元语法构成的网状结构的概念,其生成过程为:根据一元语法词典,将句子中所有单词找出来,并将起始位置相同的单词写作一行。例如,“商品和服务“的词网如下:

0:[ ]
1:[商品]
2:[]
3:[和, 和服]
4:[服务]
5:[务]
6:[ ]

下面,我们使用HanLP的WordNet模块构建词网。

from jpype import JString
WordNet = JClass("com.hankcs.hanlp.seg.common.WordNet")  # 构建词网的Java模块(词网模块)
Vertex = JClass("com.hankcs.hanlp.seg.common.Vertex")  # 构建词网的Java模块(词语存储对象)sent = "货币和服务"
trie = CoreDictionary.trie# 生成词网
searcher = trie.getSearcher(JString(sent), 0)
wordnet = WordNet(sent)
while searcher.next():wordnet.add(searcher.begin + 1,Vertex(sent[searcher.begin:searcher.begin + searcher.length], searcher.value, searcher.index))# 补充一元语法中不包含但是保证图联通必须的词
vertexes = wordnet.getVertexes()
i = 0
while i < len(vertexes):if len(vertexes[i]) == 0:  # 空白行j = i + 1for j in range(i + 1, len(vertexes) - 1):  # 寻找第一个非空行 jif len(vertexes[j]):breakwordnet.add(i, Vertex.newPunctuationInstance(sent[i - 1: j - 1]))  # 填充[i, j)之间的空白行i = jelse:i += len(vertexes[i][-1].realWord)print(wordnet)

运行结果

0:[ ]
1:[货币]
2:[]
3:[和, 和服]
4:[服务]
5:[务]
6:[ ]

最后,我们使用维特比算法来计算词网中的最短路径,以“货币和服务”的句子为例,得出其分词序列预测结果。

def viterbi(wordnet):nodes = wordnet.getVertexes()# 前向遍历for i in range(0, len(nodes) - 1):for node in nodes[i]:for to in nodes[i + len(node.realWord)]:to.updateFrom(node)  # 根据距离公式计算节点距离,并维护最短路径上的前驱指针from# 后向回溯path = []  # 最短路径f = nodes[len(nodes) - 1].getFirst()  # 从终点回溯while f:path.insert(0, f)f = f.getFrom()  # 按前驱指针from回溯return [v.realWord for v in path]print(viterbi(wordnet))

运行结果

[' ', '货币', '和', '服务', ' ']

学习参考文献:《自然语言处理入门》(何晗):3.3-3.4.4

学习NLP的第14天——语言模型的训练与预测相关推荐

  1. 深度学习与自然语言处理教程(5) - 语言模型、RNN、GRU与LSTM(NLP通关指南·完结)

    作者:韩信子@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/36 本文地址:https://www.showmeai.tech/article-d ...

  2. 天池零基础入门NLP竞赛实战:Task4-基于深度学习的文本分类3-基于Bert预训练和微调进行文本分类

    Task4-基于深度学习的文本分类3-基于Bert预训练和微调进行文本分类 因为天池这个比赛的数据集是脱敏的,无法利用其它已经预训练好的模型,所以需要针对这个数据集自己从头预训练一个模型. 我们利用H ...

  3. 转载 干货 | 陪伴我学习NLP、知识图谱的那些资源(教程+书籍+网站+工具+论文...可以说很全面了)

    https://blog.csdn.net/guleileo/article/details/81140179 干货 | 陪伴我学习NLP.知识图谱的那些资源(教程+书籍+网站+工具+论文...可以说 ...

  4. 一文概述2017年深度学习NLP重大进展与趋势

    本文,我将概述 2017 年深度学习技术在 NLP 领域带来的进步.可能会有遗漏,毕竟涵盖所有论文.框架和工具难度太大.我想和大家分享这一年我最喜欢的一些研究.我认为 2017 年是 NLP 领域的重 ...

  5. 迁移学习NLP:BERT、ELMo等直观图解

    2018年是自然语言处理的转折点,能捕捉潜在意义和关系的方式表达单词和句子的概念性理解正在迅速发展.此外,NLP社区已经出现了非常强大的组件,你可以在自己的模型和管道中自由下载和使用(它被称为NLP的 ...

  6. 深度学习(1)---2017年深度学习NLP重大进展与趋势

    深度学习(DL)架构和算法在图像识别.语音处理等领域实现了很大的进展.而深度学习在自然语言处理方面的表现最初并没有那么起眼,不过现在我们可以看到深度学习对 NLP 的贡献,在很多常见的 NLP 任务中 ...

  7. 系统学习NLP(二十九)--BERT

    补充一份细节的理解:https://zhuanlan.zhihu.com/p/74090249 输入嵌入:https://www.cnblogs.com/d0main/p/10447853.html ...

  8. 系统学习NLP(二十七)--EMLo

    论文:Deep contextualized word representations 参考:https://www.cnblogs.com/huangyc/p/9860430.html https: ...

  9. Datawhale组队学习NLP之transformer Task 01

    Datawhale组队学习NLP之transformer Task 01 Transformers在NLP中的兴起 一.自然语言处理(Natural Language Processing, NLP) ...

最新文章

  1. Java oracle 超出打开游标的最大数
  2. Linux下Python脚本自启动与定时任务详解
  3. 基于WINCE6.0+S3C6410通过USB下载stepldr
  4. 64位ubuntu 12.04编译linux内核提示openssl/opensslv.h文件缺失
  5. Ajax应用需要注意的事项
  6. STM8单片机串口同时识别自定义协议和Modbus协议
  7. Android 自定义View -- 简约的折线图
  8. 买房贷款收入证明怎么开?
  9. 畅通工程(最小生成树模板)
  10. scala中的伴生对象,
  11. buck变换器设计matlab_电力电子变换器控制设计(1)
  12. Linux内核ncsi驱动源码分析(二)
  13. 揭秘:为什么羊毛党可以0元购物?
  14. 概率论中的一些基础知识——条件概率 先验概率 后验概率 似然 概率分布函数 概率密度函数
  15. 各大有名库的介绍(转)
  16. MySQL系列之Natural Join用法
  17. gensim 中文语料训练 word2vec
  18. 公众号小伙伴“进群”学习交流
  19. 前端性能优化 雅虎军规35条
  20. 【设计模式十六之装饰模式】装饰者模式

热门文章

  1. java 哪一个gc好_优秀的Java程序员必须了解的GC哪些
  2. 中国银行业对外开放报告
  3. 华为手机storage/emulated/0找不到的问题 解决方法
  4. 项目管理工具必须具备的5个功能
  5. Java学习日志Day29_数据库的约束_备份和还原_三大设计范式_多表查询
  6. [python]面向对象高级
  7. 公司组织募捐,员工积极捐款!
  8. 106.精读《数据之上·智慧之光 - 2018》
  9. h5键盘弹起遮挡输入框的处理
  10. fsck exited with status code 4