我认为标准句子标记器sent_tokenize
存在一个错误。 问题是,在某些情况下它不会将文本拆分成句子。 在这种情况下,分词器无法将文本分成两个句子:
[sent for sent in nltk.sent_tokenize('Model wears size S. Fits size.')]
这将返回['Model wears size S. Fits size.']
,而不是['Model wears size S.', 'Fits size.']
。 当.
之前的最后一个字符串只包含一个字符时,问题似乎出现了。 如果字符数为>= 2
,则它会正确拆分文本。
如果您认为 S. Fits 可能是一个人的名字和姓氏,这在句子标记器中看起来很难解决。
我认为要走的路是子类化或复制粘贴默认的 NLTK 句子标记器并修改它以适合您的应用程序。 例如,如果您不希望文本中出现此类人名,则删除处理人名的规则。 另一种选择是使用一种解决方法,例如在标记化之前将size <X>
替换size_<X>
,并在将文本拆分成句子后再次将其替换回来。
嗯。 刚刚又试了一次。 所以我提出的第一个案例没有正确拆分。 但是如果我使用不同的字符,那么它有时会分裂! 这就是为什么我写了这个快速测试:
import nltk
import pprint
pp = pprint.PrettyPrinter(indent=4)
s = 'Test {}. Test {}.'
[nltk.sent_tokenize(s.format(char, char)) for char in 'abcdefghijklmnopqrstuvwxyz']
[pp.pprint(nltk.sent_tokenize(s.format(char, char))) for char in 'abcdefghijklmnopqrstuvwxyz']
输出:
['Test a.', 'Test a.']
['Test b.', 'Test b.']
['Test c. Test c.']
['Test d. Test d.']
['Test e. Test e.']
['Test f. Test f.']
['Test g. Test g.']
['Test h. Test h.']
['Test i.', 'Test i.']
['Test j.', 'Test j.']
['Test k. Test k.']
['Test l. Test l.']
['Test m. Test m.']
['Test n. Test n.']
['Test o.', 'Test o.']
['Test p. Test p.']
['Test q.', 'Test q.']
['Test r. Test r.']
['Test s. Test s.']
['Test t. Test t.']
['Test u.', 'Test u.']
['Test v. Test v.']
['Test w. Test w.']
['Test x.', 'Test x.']
['Test y.', 'Test y.']
['Test z.', 'Test z.']
@kmike ,如您所见,它非常不一致。
@JernejJerin它不是基于规则的标记器,因此它无法使用类似正则表达式的解释来控制/解释拆分的“规则”。
用于训练sent_tokenizer
算法是
只想添加一个来自BookCorpus的真实世界示例,摘自Smashwords 的 Mike Suttons 出版的“三部曲”。
sent_tokenize('The weather is terrible, and my day was ok. You are supposed to take your medicine.')
输出
['The weather is terrible, and my day was ok. You are supposed to take your medicine.']
它确认 nltk 没有将k.
识别为句子分隔符。
最有用的评论
只想添加一个来自BookCorpus的真实世界示例,摘自Smashwords 的 Mike Suttons 出版的“三部曲”。
sent_tokenize('The weather is terrible, and my day was ok. You are supposed to take your medicine.')
输出
['The weather is terrible, and my day was ok. You are supposed to take your medicine.']
它确认 nltk 没有将
k.
识别为句子分隔符。