【问题标题】:Accurately splitting sentences准确分割句子
【发布时间】:2015-12-21 07:39:49
【问题描述】:

我的程序获取一个文本文件并使用split('.') 将每个句子拆分为一个列表,这意味着它会在注册句号时拆分,但它可能不准确。

举例

str='i love carpets. In fact i own 2.4 km of the stuff.'

输出

listOfSentences = ['i love carpets', 'in fact i own 2', '4 km of the stuff']

期望的输出

 listOfSentences = ['i love carpets', 'in fact i own 2.4 km of the stuff']

我的问题是:如何拆分句子的结尾而不是每个句号。

【问题讨论】:

  • listOfSentences = file.split(".")
  • 拆分成句子是一项不平凡的任务。也许你可以试试自然语言工具包。 Link 类似的问题。
  • 确实,还要考虑缩写,例如像这个。标记化和句子分割是一项非常有趣的任务,尽管没有得到充分的重视。NLTK 肯定具有标记化和句子分割功能。对于专门的解决方案,您还可以考虑将 ucto 与 python-ucto (github.com/proycon/ucto , github.com/proycon/python-ucto) 一起使用,它可以对各种语言进行标记和句子分割。 [免责声明:我是ucto的作者]

标签: python parsing nlp


【解决方案1】:

任何基于正则表达式的方法都无法处理像 “我看到史密斯先生”这样的情况,并且为这些情况添加 hack 是不可扩展的。正如用户 est 所评论的,任何严肃的实现都会使用数据。

如果你只需要处理英语,那么 spaCy 比 NLTK 更好:

from spacy.en import English
en = English()
doc = en(u'i love carpets. In fact i own 2.4 km of the stuff.')
for s in list(doc.sents):
    print s.string

更新:spaCy 现在支持多种语言。

【讨论】:

  • AFAIK 没有关于句子分割的最新定量评估。关于你说 spacy 对英语比 nltk 更好的说法:我只是经历了相反的情况,即当我几乎完全切换到 spacy 时,我认为它的句子分割性能不如 nltk punkt 对英语新闻文章的性能。
  • 你可能是对的,我不记得我到底为什么这么断言,尽管我仍然敢打赌这是真的。
【解决方案2】:

我发现https://github.com/fnl/syntok/ 非常好,实际上是所有流行的最好的。具体来说,我在英文新闻文章上测试了 nltk (punkt)、spacy 和 syntok。

import syntok.segmenter as segmenter

document = "some text. some more text"

for paragraph in segmenter.analyze(document):
    for sentence in paragraph:
        for token in sentence:
            # exactly reproduce the input
            # and do not remove "imperfections"
            print(token.spacing, token.value, sep='', end='')
    print("\n")  # reinsert paragraph separators

【讨论】:

    【解决方案3】:

    可以使用re模块的split函数来实现不拆分数字:

    >>> import re
    >>> s = 'i love carpets. In fact i own 2.4 km of the stuff.'
    >>> re.split(r'\.[^0-9]', s)
    ['i love carpets', 'In fact i own 2.4 km of the stuff.']
    

    【讨论】:

      【解决方案4】:

      如果你的句子都以“.”结尾和“.”,你可以试试正则表达式:

      import re
      
      text = "your text here. i.e. something."
      sentences = re.split(r'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s', text)
      

      来源:Python - RegEx for splitting text into sentences (sentence-tokenizing)

      【讨论】:

      • 如果句子中有Mr.(或i.e.)怎么办?你自己的例子产生["your text here", "i.e", "something."]
      【解决方案5】:

      最简单的方法是在一个点后跟一个空格分割为:

      >>> s = 'i love carpets. In fact i own 2.4 km of the stuff.'
      >>> s.split('. ')
      ['i love carpets', 'In fact i own 2.4 km of the stuff.']
      

      【讨论】:

      • 好的,但是如果有一个例子之后没有空格怎么办:population of 142,100,.[2] falling to 142,065 at the 2011 Census [2] 阻止了它的工作
      • 还有点后面的缩写呢?比如问号、感叹号等等?
      猜你喜欢
      • 2017-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      • 2019-02-11
      相关资源
      最近更新 更多