在Python中训练NGramModel

Try*_*lks 8 python nltk n-gram python-3.x

我正在使用Python 3.5,使用Anaconda进行安装和管理.我想使用一些文本训练NGramModel(来自nltk).我的安装找不到模块nltk.model

这个问题有一些可能的答案(选择正确的答案,并解释如何做到这一点):

  1. 可以使用conda安装不同版本的nltk,以便它包含模型模块.这不仅仅是旧版本(它需要太旧),而是包含当前nltk开发的模型(或model2)分支的不同版本.
  2. 前一点中提到的nltk版本无法使用conda安装,但可以使用pip安装.
  3. 不推荐使用nltk.model,更好地使用其他一些包(解释哪个包)
  4. 有比nltk更好的选项来训练ngram模型,使用其他一些库(解释哪个库)
  5. 以上都不是,训练ngram模型最好的选择是别的(解释什么).

Ili*_*kov 18

2018年12月更新!

随着NLTK 3.4的发布,重新设计的lm模块包含ngram模型功能.请查看其文档!

我对那些感兴趣或因任何原因无法安装3.3版本的人保留旧的答案

上一个答案

首先,正如您对问题的评论中所指出的,如果培训/运行速度对您来说是一个问题,KenLM可能是更好的选择.此时nltk.model主要用于教育/原型设计,但速度并不快.

如果您仍然决定坚持使用NLTK,请继续阅读.我碰巧是分支中新NgramModel代码的作者,model我会尽力使事情清楚,这样你就可以测试代码,让我知道你的想法.由于旧实现中存在许多严重错误,我们不得不对模块进行大修,我们仍在调整新设置.

目前在此doctest文件中描述了已修改模块的预期用途.话虽如此,我会快速浏览工作流程的主要更改,因为它与旧版本有很大不同.如果您对我们如何提出新工作流程感兴趣,请参阅此主题.

最重要的是要记住,训练ngram模型现在明确分为以下3个步骤.

1.建立词汇

当ngram模型遇到训练期间没有看到的单词时,旧实现中出现了一些最烦人的错误.解决这个问题的传统方法是开始训练之前创建一个"已知"标记(单词)词汇表.

当你训练你的ngram模型时,你在词汇表中查找标记并在它们存在时增加它们的计数,否则增加计数器以获得特殊的UNKNOWN标记.我们的想法是,如果您在测试期间遇到看不见的令牌,您可以使用UNKNOWN的计数来估算其得分.

可以使用您训练的数据以外的数据创建此词汇表.例如,你的词汇可能来自Gigaword语料库,但你只训练你的模型华尔街日报.

使用此nltk.model.build_vocabulary功能.

2.训练=计算Ngrams

你有没有想过当你"训练"一个ngram模型时究竟发生了什么?从本质上讲,培训模型实际上归结为简单地计算文本中的ngrams.当然,这还涉及将文本分解为ngrams并根据您在上一步中创建的词汇检查令牌.

nltk.model.count_ngrams在涉及此任务时,适当命名的函数是您的朋友.它返回一个NgramCounter类的实例,它试图提供一个清晰的接口来访问/更新ngram计数.

3.从计数到分数(更新)

这是整个过程的最终目标,在给定某些上下文的情况下获得类似于令牌的概率.

这部分模块仍在进行中,现在只有MLE,LidstoneLaplace估算器.doctest文件中简要介绍了它们的用法.

如果你想使用不同的估算器,你必须为它编写自己的类.但是,我试图让它变得非常容易.此外,您可以将您的作品提交给NLTK并成为贡献者!

以下是您定义自己的估算器的方法:

  1. 创建一个继承自的类BaseNgramModel.
  2. 在此类中,实现您自己的score方法,该方法使用该ngram_counts属性来访问计数.

随意从已定义的模型中获取灵感ngram.py.这是基本MLE评分的示例实现:

from nltk.model import BaseNgramModel

class MLENgramModel(BaseNgramModel):

    def score(self, context, word):
        # how many times word occurs with context
        ngram_count = self.ngrams[context][word]
        # how many times the context itself occurred we take advantage of
        # the fact that self.ngram[context] is a FreqDist and has a method
        # FreqDist.N() which counts all the samples in it.
        context_count = self.ngram[context].N()

        # In case context_count is 0 we shouldn't be dividing by it 
        # and just return 0
        if context_count == 0:
            return 0
        # otherwise we can return the standard MLE score
        return ngram_count / context_count
Run Code Online (Sandbox Code Playgroud)


小智 0

尝试

import nltk
nltk.download('all')
Run Code Online (Sandbox Code Playgroud)

在你的笔记本里