Nltk: Токенизатор предложений не разделяется правильно

Созданный на 23 нояб. 2015  ·  5Комментарии  ·  Источник: nltk/nltk

Я думаю, что есть ошибка в стандартном токенизаторе предложений 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 , то текст правильно разбивается.

inactive tokenizer

Самый полезный комментарий

Просто хочу добавить реальный пример из 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. как разделитель предложений.

Все 5 Комментарий

Это выглядит очень сложно исправить в токенизаторе предложений, если учесть, что 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. как разделитель предложений.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги