Python预测分词的实现


Posted in Python onJune 18, 2021

前言

在机器学习中,我们有了训练集的话,就开始预测。预测是指利用模型对句子进行推断的过程。在中文分词任务中也就是利用模型推断分词序列,同时也叫解码。

在HanLP库中,二元语法的解码由ViterbiSegment分词器提供。本篇将详细介绍ViterbiSegment的使用方式

 

加载模型

在前篇博文中,我们已经得到了训练的一元,二元语法模型。后续的处理肯定会基于这几个文件来处理。所以,我们首先要做的就是加载这些模型到程序中:

if __name__ == "__main__":
    MODEL_PATH = "123"
    HanLP.Config.CoreDictionaryPath = MODEL_PATH + ".txt"
    HanLP.Config.BiGramDictionaryPath = MODEL_PATH + ".ngram.txt"
    CoreDictionary = SafeJClass("com.hankcs.hanlp.dictionary.CoreDictionary")
    CoreBiGramTableDictionary = SafeJClass('com.hankcs.hanlp.dictionary.CoreBiGramTableDictionary')
    print(CoreDictionary.getTermFrequency("秦机"))
    print(CoreBiGramTableDictionary.getBiFrequency("秦机","的"))

运行之后,效果如下:

Python预测分词的实现

这里我们使用CoreDictionary.getTermFrequency()方法获取”秦机“的频次。使用CoreBiGramTableDictionary.getBiFrequency()方法获取“秦机 的”的二元语法频次。

 

构建词网

在前文中我们介绍了符号“末##末“,代表句子结尾,”始##始“代表句子开头。而词网指的是句子中所有一元语法构成的网状结构。比如MSR词典中的“秦机和科技”这个句子,是给定的一元词典。我们将句子中所有单词找出来。得到如下词网:

[始##始]
[秦机]
[]
[和,和科]
[科技]
[技]
[末##末]

对应的此图如下所示:

Python预测分词的实现

当然,这里博主只是举例说明词网的概念,“和科”并不是一个单词。

下面,我们来通过方法构建词网。具体代码如下:

def build_wordnet(sent, trie):
    JString = JClass('java.lang.String')
    Vertex = JClass('com.hankcs.hanlp.seg.common.Vertex')
    WordNet = JClass('com.hankcs.hanlp.seg.common.WordNet')
    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 + 1
            for j in range(i + 1, len(vertexes) - 1):  # 寻找第一个非空行 j
                if len(vertexes[j]):
                    break
            wordnet.add(i, Vertex.newPunctuationInstance(sent[i - 1: j - 1]))  # 填充[i, j)之间的空白行
            i = j
        else:
            i += len(vertexes[i][-1].realWord)

    return wordnet


if __name__ == "__main__":
    MODEL_PATH = "123"
    HanLP.Config.CoreDictionaryPath = MODEL_PATH + ".txt"
    HanLP.Config.BiGramDictionaryPath = MODEL_PATH + ".ngram.txt"
    CoreDictionary = SafeJClass("com.hankcs.hanlp.dictionary.CoreDictionary")
    CoreBiGramTableDictionary = SafeJClass('com.hankcs.hanlp.dictionary.CoreBiGramTableDictionary')
    print(build_wordnet("秦机和科技", CoreDictionary.trie))

运行之后,我们会得到与上图归纳差不多的内容:

Python预测分词的实现

 

维特比算法

如果现在我们赋予上述词图每条边以二元语法的概率作为距离,那么如何求解词图上的最短路径就是一个关键问题。

假设文本长度为n,则一共有2(n-1次方)种切分方式,因为每2个字符间都有2种选择:切或者不切,时间复杂度就为O(2(n-1次方))。显然不切实际,这里我们考虑使用维特比算法。

维特比算法原理:它分为前向和后向两个步骤。

  • 前向:由起点出发从前往后遍历节点,更新从起点到该节点的最下花费以及前驱指针
  • 后向:由终点出发从后往前回溯前驱指针,取得最短路径

维特比算法用python代码的实现如下:

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)]:
                # 根据距离公式计算节点距离,并维护最短路径上的前驱指针from
                to.updateFrom(node)
    # 后向回溯
    # 最短路径
    path = []
    # 从终点回溯
    f = nodes[len(nodes) - 1].getFirst()
    while f:
        path.insert(0, f)
        # 按前驱指针from回溯
        f = f.getFrom()
    return [v.realWord for v in path]

 

实战

现在我们来做个测试,我们在msr_test_gold.utf8上训练模型,为秦机和科技常见词图,最后运行维特比算法。详细代码如下所示:

if __name__ == "__main__":
    MODEL_PATH = "123"
    corpus_path = r"E:\ProgramData\Anaconda3\Lib\site-packages\pyhanlp\static\data\test\icwb2-data\gold\msr_test_gold.utf8"
    train_model(corpus_path, MODEL_PATH)
    HanLP.Config.CoreDictionaryPath = MODEL_PATH + ".txt"
    HanLP.Config.BiGramDictionaryPath = MODEL_PATH + ".ngram.txt"
    CoreDictionary = SafeJClass("com.hankcs.hanlp.dictionary.CoreDictionary")
    CoreBiGramTableDictionary = SafeJClass('com.hankcs.hanlp.dictionary.CoreBiGramTableDictionary')
    ViterbiSegment = JClass('com.hankcs.hanlp.seg.Viterbi.ViterbiSegment')
    MODEL_PATH = "123"
    HanLP.Config.CoreDictionaryPath = MODEL_PATH + ".txt"
    HanLP.Config.BiGramDictionaryPath = MODEL_PATH + ".ngram.txt"
    sent = "秦机和科技"
    wordnet = build_wordnet(sent, CoreDictionary.trie)
    print(viterbi(wordnet))

Python预测分词的实现

有的人可能有疑问,因为二元模型里,本身就存在秦机 和
科技这个样本。这么做不是多此一举吗?那好,我们替换sent的文本内容为“北京和广州”,这个样本可不在模型中。运行之后,效果如下:

Python预测分词的实现

我们发现依然能正确的分词为[北京 和 广州],这就是二元语法模型的泛化能力。至此我们走通了语料标注,训练模型,预测分词结果的完整步骤。

到此这篇关于Python预测分词的实现的文章就介绍到这了,更多相关Python预测分词内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python操作mysql中文显示乱码的解决方法
Oct 11 Python
python编程开发之日期操作实例分析
Nov 13 Python
Python实现的文本简单可逆加密算法示例
May 18 Python
Python cookbook(数据结构与算法)保存最后N个元素的方法
Feb 13 Python
DES加密解密算法之python实现版(图文并茂)
Dec 06 Python
python将list转为matrix的方法
Dec 12 Python
Python高斯消除矩阵
Jan 02 Python
Python 实现交换矩阵的行示例
Jun 26 Python
如何基于Python批量下载音乐
Nov 11 Python
开启Django博客的RSS功能的实现方法
Feb 17 Python
如何在windows下安装配置python工具Ulipad
Oct 27 Python
python语言time库和datetime库基本使用详解
Dec 25 Python
学会Python数据可视化必须尝试这7个库
python tqdm用法及实例详解
Jun 16 #Python
python使用pymysql模块操作MySQL
分析Python感知线程状态的解决方案之Event与信号量
Jun 16 #Python
Python中else的三种使用场景
Jun 16 #Python
Python基础之条件语句详解
教你怎么用Python实现GIF动图的提取及合成
You might like
PHP 图片上传实现代码 带详细注释
2010/04/29 PHP
php抓取页面与代码解析 推荐
2010/07/23 PHP
30 个很棒的PHP开源CMS内容管理系统小结
2011/10/14 PHP
Zend的Registry机制的使用说明
2013/05/02 PHP
PHP之生成GIF动画的实现方法
2013/06/07 PHP
PHP实现懒加载的方法
2015/03/07 PHP
PHP微信开发之根据用户回复关键词\位置返回附近信息
2016/06/24 PHP
使用jquery给input和textarea设定ie中的focus
2008/05/29 Javascript
javascript 类型判断代码分析
2010/03/28 Javascript
js实现同一个页面多个渐变效果的方法
2015/04/10 Javascript
JavaScript之AOP编程实例
2015/07/17 Javascript
JS 拦截全局ajax请求实例解析
2016/11/29 Javascript
微信小程序页面传值实例分析
2017/04/19 Javascript
Angular2 http jsonp的实例详解
2017/08/31 Javascript
深入掌握 react的 setState的工作机制
2017/09/27 Javascript
nodejs中函数的调用实例详解
2018/10/31 NodeJs
vue-cli2.0转3.0之项目搭建的详细步骤
2018/12/11 Javascript
微信小程序实现动态显示和隐藏某个控件功能示例
2018/12/14 Javascript
在Node.js中将SVG图像转换为PNG,JPEG,TIFF,WEBP和HEIF格式的方法
2019/08/22 Javascript
解决 window.onload 被覆盖的问题方法
2020/01/14 Javascript
Vue触发input选取文件点击事件操作
2020/08/07 Javascript
我喜欢你 抖音表白程序python版
2019/04/07 Python
Django 大文件下载实现过程解析
2019/08/01 Python
Python全局变量与global关键字常见错误解决方案
2020/10/05 Python
为有想象力的人提供的生活方式商店:Firebox
2018/06/04 全球购物
爱尔兰电脑、家电和家具购物网站:Buy It Direct
2019/07/09 全球购物
致长跑运动员广播稿
2014/01/31 职场文书
小班重阳节活动方案
2014/02/08 职场文书
模具设计与制造专业推荐信
2014/02/16 职场文书
中药学专业毕业生推荐信
2014/07/10 职场文书
经典演讲稿开场白
2014/08/25 职场文书
给老婆的检讨书1000字
2015/01/01 职场文书
2015关于重阳节的演讲稿
2015/03/20 职场文书
幼儿园工作总结2015
2015/04/01 职场文书
CSS 伪元素::marker详解
2021/06/26 HTML / CSS
Spring中bean集合注入的方法详解
2022/07/07 Java/Android