NLTK句子标记器是否假定正确的标点和空格?

时间:2018-08-05 09:45:01

标签: nlp nltk

我正在尝试使用NLTK拆分句子,并且我注意到它会将两个之间没有空格的句子视为一个句子。例如:

text = 'Today is Monday.I went shopping.'
sentences = sent_tokenize(text)
# 1) Today is Monday.I went shopping.

text = 'Today is Monday. I went shopping.'
sentences = sent_tokenize(text)
# 1) Today is Monday.
# 2) I went shopping.

有没有办法正确分割标点符号/错位的句子?

2 个答案:

答案 0 :(得分:1)

尽管对于大多数西方语言来说,句子分割不是很复杂,但是您仍然会不时发现它的问题。有几种工具(例如,opennlp和corenlp都有各自的模块),nltk的send_tokenize非常基本,并且可能基于正则表达式。您可以使用以下内容来“修复”您的输出:

import re
s = 'Today is Monday.I went shopping.Tomorrow is Tuesday.'
slices = []
for match in re.finditer('\w\.\w', s):
    slices.append(match.start()+2)
slices.append(len(s))
offset = 0
subsentences = []
for pos in sorted(slices):
    subsent = s[offset:pos]
    offset += len(subsent)
    subsentences.append(subsent)
print(subsentences)

在字字符上分割字符串,后跟点和字字符。请注意,单词字符实际上包含数字,因此您可能需要将其更改为[a-zA-Z]或其他内容,也许还要更改。任何标点符号。

答案 1 :(得分:0)

只要您有足够的纯文本,Punkt令牌生成器(NLTK在这里使用的就是什么)就很容易训练,但据我所知,它不考虑像shopping.Tomorrow那样在内部句点拆分句子

尽管通过删除现有语料库中句子之间的空格很容易创建训练数据,但我想不出支持这种情况的常用句子分割器,因为它们要么每行训练一个句子(OpenNLP)或依靠先前的令牌化步骤将其分为三个令牌(CoreNLP,还有许多其他令牌)。

如果您有任何方法可以使数据在提取/预处理步骤中看起来更像报纸上的文字(请参见我对另一个问题的回答:https://stackoverflow.com/a/44860394/461847),则使用标准工具会变得更加容易,并且您可以节省很多麻烦。

我不建议像@igor所示那样对检测到的句子进行后处理,而是建议对其进行预处理,以尝试在看起来像句子边界的个案之间插入空格,然后运行send_tokenize(),因为可能存在某些情况,例如日期可能包括句点,但不是句子边界。显然,这取决于您的数据。