【问题标题】:Does the NLTK sentence tokenizer assume correct punctuation and spacing?NLTK 句子标记器是否假定正确的标点符号和间距?
【发布时间】:2018-08-05 09:45:00
【问题描述】:

我正在尝试使用 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.1 人饿了。”来自“我们的结果是 2.1,我们很饿。”?
  • 但在我的示例中,'.' 周围的字符不是数字。

标签: nlp nltk


【解决方案1】:

虽然对于大多数西方语言来说,句子分割并不是很复杂,但正如您所遇到的那样,它仍然不时出现。为此有几个工具(例如,opennlp 和 corenlp 都有自己的模块),来自 nltk 的 sent_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] 或其他内容,也许还有 .任何标点符号。

【讨论】:

    【解决方案2】:

    只要你有足够的纯文本,Punkt 分词器(NLTK 在这里使用的)很容易训练,但据我所知,它不会考虑像 shopping.Tomorrow 这样在内部句点上拆分句子。

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 2014-12-31
      • 1970-01-01
      • 2012-12-15
      • 2022-01-25
      • 1970-01-01
      相关资源
      最近更新 更多