Я думаю, что есть ошибка в стандартном токенизаторе предложений 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
- это точечный алгоритм Kiss and Strunk (2006) . Это статистическая система, которая пытается изучить границы предложения, поэтому она не идеальна, но согласуется с вероятностями, сгенерированными из модели (но не обязательными человеческими правилами).
Просто хочу добавить реальный пример из BookCorpus , извлеченный из «Three Plays», опубликованного Майком Саттонсом в Smashwords.
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 , извлеченный из «Three Plays», опубликованного Майком Саттонсом в Smashwords.
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.
как разделитель предложений.