Python 如何调整NLTK语句标记器

Python 如何调整NLTK语句标记器,python,nlp,nltk,Python,Nlp,Nltk,我正在使用NLTK来分析一些经典文本,我在按句子标记文本时遇到了麻烦。例如,以下是我从中获得的一个片段: 考虑到Melville的语法有点过时,我并不期待完美,但是NLTK应该能够处理终端双引号和像“夫人”这样的标题。因为标记器是无监督训练算法的结果,但是,我不知道如何修补它 有人推荐更好的句子标记器吗?我更喜欢一个简单的启发,我可以黑客,而不是必须训练自己的解析器 您可以告诉PunktSentenceTokenizer.tokenize方法,通过将reallign_bounders参数设置为T

我正在使用NLTK来分析一些经典文本,我在按句子标记文本时遇到了麻烦。例如,以下是我从中获得的一个片段:

考虑到Melville的语法有点过时,我并不期待完美,但是NLTK应该能够处理终端双引号和像“夫人”这样的标题。因为标记器是无监督训练算法的结果,但是,我不知道如何修补它


有人推荐更好的句子标记器吗?我更喜欢一个简单的启发,我可以黑客,而不是必须训练自己的解析器

您可以告诉
PunktSentenceTokenizer.tokenize
方法,通过将
reallign_bounders
参数设置为
True
将“terminal”双引号包括在句子的其余部分。有关示例,请参见下面的代码

我不知道有什么干净的方法可以防止像Hussey夫人这样的文本被分成两句话。然而,这里有一个黑客

  • 将所有出现的
    Hussey夫人
    更改为
    Hussey夫人
  • 然后用
    sent\u tokenize.tokenize
    将文本拆分成句子
  • 然后,对于每个句子,将
    Hussey夫人
    分解回
    Hussey夫人
我希望我知道一个更好的方法,但这可能在紧要关头起作用


屈服

"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?"

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

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?“),则此选项无效。因此,一种快速而肮脏的方法是在撇号和引号前面加空格,这些引号跟在句尾符号(.!?)后面:


因此,我遇到了类似的问题,并尝试了上面vpekar的解决方案

也许我的是某种边缘情况,但我在应用替换后观察到了相同的行为,然而,当我尝试用放在它们前面的引号替换标点符号时,我得到了我想要的输出。据推测,不遵守《司法协助法》不如将原文保留为一句话那么重要

更清楚地说:

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

如果MLA很重要,尽管您可以随时返回并反转这些更改,无论它在哪里起作用。

您可以修改NLTK预先训练的英语句子标记器,通过将它们添加到集合
\u params.abbrev\u 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'
。有关其他标记器参数的详细信息,请参阅

Ah,很高兴知道。奇怪的是,如果我通过你的解决方案把问题中的完整句子通读一遍,这就行不通了。你知道为什么吗?只是在答案中添加了更多的信息。我通常避免使用“谢谢”的评论,但这里确实是这样:谢谢!如果句子中有撇号,但你想得到偏移量,你如何处理这种特殊情况?i、 e.使用
span_标记化
方法。建议的解决方法更改了原始偏移量。这个答案的问题是它没有“调整”现有的英语标记器。如果从头开始创建一个功能,您可能会丢失很多其他可能需要的功能。请参阅更新:此答案的合并部分与上面的部分。这应该是最重要的答案。如果您只是创建一个新的标记器,您将无法获得英语标记器的所有现有功能。它似乎对我不起作用,而最上面的答案对我起作用。@Alter您必须这样使用它:
句子\u标记器。标记化(text)
这也适用于无需重新训练的定制标记器。(适用于Punkt不支持的语言)
text = text.replace('?"', '? "').replace('!"', '! "').replace('."', '. "')
text = text.replace('?"', '"?').replace('!"', '"!').replace('."', '".')
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)