预测分词---Python自然语言处理(8)

本文涉及的产品
NLP 自学习平台,3个模型定制额度 1个月
NLP自然语言处理_基础版,每接口每天50万次
NLP自然语言处理_高级版,每接口累计50万次
简介: 预测分词---Python自然语言处理(8)

前言


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


在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("秦机","的"))


运行之后,效果如下:


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


构建词网


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

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


对应的此图如下所示:


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


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

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))


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


维特比算法


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


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


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


1.前向:由起点出发从前往后遍历节点,更新从起点到该节点的最下花费以及前驱指针

2.后向:由终点出发从后往前回溯前驱指针,取得最短路径


维特比算法用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))


有的人可能有疑问,因为二元模型里,本身就存在秦机 和

科技这个样本。这么做不是多此一举吗?那好,我们替换sent的文本内容为“北京和广州”,这个样本可不在模型中。运行之后,效果如下:



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

相关文章
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】python之人工智能应用篇——文本生成技术
文本生成是指使用自然语言处理技术,基于给定的上下文或主题自动生成人类可读的文本。这种技术可以应用于各种领域,如自动写作、聊天机器人、新闻生成、广告文案创作等。
19 8
|
13天前
|
自然语言处理 数据可视化 搜索推荐
基于python直播平台数据的文本分析,包括LDA主题分析、分词以及网络语义分析,生成网络图
本文探讨了基于Python的直播平台数据文本分析方法,包括LDA主题分析、分词和网络语义分析,旨在揭示用户观点和需求,优化用户体验,并辅助运营方制定改进策略,同时通过生成词云图和网络图提供数据驱动的决策支持。
基于python直播平台数据的文本分析,包括LDA主题分析、分词以及网络语义分析,生成网络图
|
1月前
|
机器学习/深度学习 自然语言处理 TensorFlow
使用Python实现深度学习模型:文本生成与自然语言处理
【7月更文挑战第14天】 使用Python实现深度学习模型:文本生成与自然语言处理
44 12
|
30天前
|
机器学习/深度学习 自然语言处理 机器人
使用Python实现深度学习模型:自然语言理解与问答系统
【7月更文挑战第20天】 使用Python实现深度学习模型:自然语言理解与问答系统
38 0
使用Python实现深度学习模型:自然语言理解与问答系统
|
2月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的应用与性能比较
分词算法在自然语言处理中的应用与性能比较
|
1月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的应用与性能比较
分词算法在自然语言处理中的应用与性能比较
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
Python自然语言处理实战:文本分类与情感分析
本文探讨了自然语言处理中的文本分类和情感分析技术,阐述了基本概念、流程,并通过Python示例展示了Scikit-learn和transformers库的应用。面对多义性理解等挑战,研究者正探索跨域适应、上下文理解和多模态融合等方法。随着深度学习的发展,这些技术将持续推动人机交互的进步。
62 1
|
1月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的基本原理与应用场景
分词算法在自然语言处理中的基本原理与应用场景
|
2月前
|
机器学习/深度学习 数据采集 人工智能
Python 高级实战:基于自然语言处理的情感分析系统
**摘要:** 本文介绍了基于Python的情感分析系统,涵盖了从数据准备到模型构建的全过程。首先,讲解了如何安装Python及必需的NLP库,如nltk、sklearn、pandas和matplotlib。接着,通过抓取IMDb电影评论数据并进行预处理,构建情感分析模型。文中使用了VADER库进行基本的情感分类,并展示了如何使用`LogisticRegression`构建机器学习模型以提高分析精度。最后,提到了如何将模型部署为实时Web服务。本文旨在帮助读者提升在NLP和情感分析领域的实践技能。
61 0
|
自然语言处理 搜索推荐 算法
python 结巴分词(jieba)学习
来源:http://www.gowhich.com/blog/147?utm_source=tuicool&amp;utm_medium=referral 源码下载的地址:https://github.com/fxsjy/jieba 演示地址:http://jiebademo.ap01.aws.af.cm/ 特点 1,支持三种分词模式:     a,精确模式,试图将句
2016 0