如何拆分句子?

3
所以,我发现并目前正在使用斯坦福解析器,它非常适合分割句子。我们大部分的句子都来自AP,所以它在这方面表现得非常好。
以下是问题:
- 它会占用很多内存(高达600M) - 它真的会破坏文本格式,使我必须为后续处理制定很多边缘情况。(文档预处理API调用不允许指定ASCII / UTF8引号 - 它们立即转换为LaTeX样式,缩略词被拆分成不同的单词(显然),并且会在不同的位置放入虚假空格)
为此,我已经编写了多个补丁来补偿我真的不应该做的事情。
基本上,它已经到了使用起来与开始分割句子的问题一样令人困扰的地步。
我的其他选择是什么?是否有其他NLP类型的框架可以帮助解决问题?
我的原始问题只是能够以高概率检测句子边缘。
4个回答

5
如果您想尝试使用斯坦福分词器/解析器,请查看分词器的文档页面
如果您只想拆分句子,则不需要调用解析器本身,因此通过直接使用DocumentPreprocessor,您应该能够仅使用少量内存(一两兆字节)。
虽然分词器的可定制性有限,但您可以更改引号的处理方式。您可以尝试以下其中之一:
unicodeQuotes=false,latexQuotes=false,asciiQuotes=false
unicodeQuotes=true

第一个选项表示不进行任何引号映射,第二个选项将根据其最佳能力将单引号或双引号(如果有)更改为左引号和右引号。
虽然分词器以各种方式拆分单词以匹配Penn Treebank约定,但您应该能够从返回的标记精确地构造原始文本(请参见CoreLabel中的其他各个字段)。否则这是一个错误。

1
感谢您指引我正确的方向--http://pastie.org/2602418 <-- 这是我最终在Ruby中完成的(带有所有用例的测试套件)--我仍然想在其中加入invertible=true,但还没有深入研究如何实现。 - eyberg

1
您可以使用斯坦福自然语言处理工具在不使任何字符替换为奇怪字符(例如括号或撇号)的情况下,从文本中分离句子的一种方法是:
PTBTokenizer ptbt = new PTBTokenizer(
                    new StringReader(text), new CoreLabelTokenFactory(), "ptb3Escaping=false");
List<List<CoreLabel>> sents = (new WordToSentenceProcessor()).process(ptbt.tokenize());
Vector<String> sentences = new Vector<String>();
for (List<CoreLabel> sent : sents) {
    StringBuilder sb = new StringBuilder("");
    for (CoreLabel w : sent) sb.append(w + " ");
        sentences.add(sb.toString());
    }
}               

使用DocumentPreprocessor的标准方式会破坏你的原始文本。

1

有很多句子分割器可用,性能取决于您的具体应用。

使用PerlPython版本非常容易入门。我发现过去使用斯坦福解析器版本有些麻烦;最终我使用了一个特定领域的分割器(Genia)。我还运行了基于正则表达式的清理工具来查找错误分割的句子并重新组合它们。


很酷!感谢建议 - 将会查看这三个选项。 - eyberg
说起来,NLTK 也必须以某种形式拥有句子分割。 - nflacco

0
你可以使用NLTK(尤其是nltk.tokenize包):
import nltk
sentence_detector = nltk.data.load('tokenizers/punkt/english.pickle')
text = "This is a test. Let's try this sentence boundary detector."
text_output = sentence_detector.tokenize(text)
print('text_output: {0}'.format(text_output))

输出:

text_output: ['This is a test.', "Let's try this sentence boundary detector."]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接