【问题标题】:How to tweak the NLTK sentence tokenizer如何调整 NLTK 句子标记器
【发布时间】:2012-12-15 06:44:20
【问题描述】:

我正在使用 NLTK 分析一些经典文本,并且遇到了逐句标记文本的麻烦。例如,这是我从 Moby Dick 获得的 sn-p 信息:

import nltk
sent_tokenize = nltk.data.load('tokenizers/punkt/english.pickle')

'''
(Chapter 16)
A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but
that's a rather cold and clammy reception in the winter time, ain't it, Mrs. Hussey?"
'''
sample = 'A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but that\'s a rather cold and clammy reception in the winter time, ain\'t it, Mrs. Hussey?"'

print "\n-----\n".join(sent_tokenize.tokenize(sample))
'''
OUTPUT
"A clam for supper?
-----
a cold clam; is THAT what you mean, Mrs.
-----
Hussey?
-----
" says I, "but that\'s a rather cold and clammy reception in the winter time, ain\'t it, Mrs.
-----
Hussey?
-----
"
'''

考虑到 Melville 的语法有点过时,我不希望这里完美,但 NLTK 应该能够处理终端双引号和像“Mrs.”这样的标题。然而,由于分词器是无监督训练算法的结果,我不知道如何修改它。

有人推荐更好的句子标记器吗?我更喜欢我可以破解的简单启发式算法,而不必训练自己的解析器。

【问题讨论】:

    标签: python nlp nltk


    【解决方案1】:

    您可以修改 NLTK 的预训练英语句子标记器,通过将它们添加到集合 _params.abbrev_types 来识别更多缩写词。例如:

    extra_abbreviations = ['dr', 'vs', 'mr', 'mrs', 'prof', 'inc', 'i.e']
    sentence_tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
    sentence_tokenizer._params.abbrev_types.update(extra_abbreviations)
    

    请注意,必须在指定缩写时不带最后一个句点,但要包括任何内部句点,如上面的'i.e'。其他分词器参数详见the relevant documentation.

    【讨论】:

    • 这应该是最佳答案。如果您只是创建一个新的分词器,您将无法获得英语分词器的所有现有功能。
    • 它似乎对我不起作用,而最佳答案却是。
    • @Alter 你必须像这样使用它:sentence_tokenizer.tokenize(text)
    • 这也适用于无需重新训练的腌制自定义标记器。 (对于 Punkt 不支持的语言)
    【解决方案2】:

    所以我遇到了类似的问题,并在上​​面尝试了 vpekar 的解决方案。

    也许我的情况是某种边缘情况,但我在应用替换后观察到相同的行为,但是,当我尝试用放在它们之前的引号替换标点符号时,我得到了我正在寻找的输出。据推测,缺乏对 MLA 的遵守不如将原始引文保留为一个句子那么重要。

    为了更清楚:

    text = text.replace('?"', '"?').replace('!"', '"!').replace('."', '".')
    

    如果 MLA 很重要,尽管您可以随时返回并在重要的地方撤销这些更改。

    【讨论】:

      【解决方案3】:

      您需要向标记器提供缩写列表,如下所示:

      from nltk.tokenize.punkt import PunktSentenceTokenizer, PunktParameters
      punkt_param = PunktParameters()
      punkt_param.abbrev_types = set(['dr', 'vs', 'mr', 'mrs', 'prof', 'inc'])
      sentence_splitter = PunktSentenceTokenizer(punkt_param)
      text = "is THAT what you mean, Mrs. Hussey?"
      sentences = sentence_splitter.tokenize(text)
      

      现在是:

      ['is THAT what you mean, Mrs. Hussey?']
      

      更新:如果句子的最后一个单词附有撇号或引号(如 Hussey?'),这将不起作用。因此,解决此问题的一种快速而肮脏的方法是在撇号和句子结尾符号(.!?)之后的引号前放置空格:

      text = text.replace('?"', '? "').replace('!"', '! "').replace('."', '. "')
      

      【讨论】:

      • 啊,很高兴知道。奇怪的是,如果我通过您的解决方案运行我的问题中的完整句子,这将不起作用。知道为什么吗?
      • 刚刚在答案中添加了更多信息。
      • 我通常会避免使用“谢谢”cmets,但它确实到位:谢谢!
      • 你如何处理句子有撇号但你想得到偏移量的特殊情况?即使用span_tokenize 方法。建议的解决方法会更改原始偏移量。
      • 这个答案的问题是它没有“调整”现有的英语分词器。如果您从头开始创建一个,您将失去许多您可能想要的其他功能。见stackoverflow.com/a/25375857/4582054
      【解决方案4】:

      您可以通过将realign_boundaries 参数设置为True 来告诉PunktSentenceTokenizer.tokenize 方法在句子的其余部分中包含“终端”双引号。示例见下面的代码。

      我不知道一种干净的方法来防止像Mrs. Hussey 这样的文本被分成两个句子。然而,这是一个

      • 将所有出现的Mrs. Hussey 更改为Mrs._Hussey,
      • 然后将文本拆分成带有sent_tokenize.tokenize的句子,
      • 然后对于每个句子,将Mrs._Hussey 解开回Mrs. Hussey

      我希望我知道一个更好的方法,但这可能会在紧要关头。


      import nltk
      import re
      import functools
      
      mangle = functools.partial(re.sub, r'([MD]rs?[.]) ([A-Z])', r'\1_\2')
      unmangle = functools.partial(re.sub, r'([MD]rs?[.])_([A-Z])', r'\1 \2')
      
      sent_tokenize = nltk.data.load('tokenizers/punkt/english.pickle')
      
      sample = '''"A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but that\'s a rather cold and clammy reception in the winter time, ain\'t it, Mrs. Hussey?"'''    
      
      sample = mangle(sample)
      sentences = [unmangle(sent) for sent in sent_tokenize.tokenize(
          sample, realign_boundaries = True)]    
      
      print u"\n-----\n".join(sentences)
      

      产量

      "A clam for supper?
      -----
      a cold clam; is THAT what you mean, Mrs. Hussey?"
      -----
      says I, "but that's a rather cold and clammy reception in the winter time, ain't it, Mrs. Hussey?"
      

      【讨论】:

      • 更新:将此答案的一部分与上述答案合并
      猜你喜欢
      • 2015-05-16
      • 2013-02-10
      • 2016-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      相关资源
      最近更新 更多