найти несколько предложений - PullRequest
5 голосов
/ 11 ноября 2009

Я хотел бы найти хороший способ найти несколько (пусть это будет два) предложений в каком-то тексте. Что будет лучше - использовать регулярное выражение или метод split? Ваши идеи?

По просьбе Джереми Стейна - есть несколько примеров

Примеры:

Введите:

Первое, что нужно сделать, это создать модель комментариев. Мы создадим это обычным способом, но с одним небольшим отличием. Если бы мы просто создавали комментарии для статьи, у нас было бы целое поле article_id в модели для хранения внешнего ключа, но в этом случае нам понадобится нечто более абстрактное.

Первые два предложения:

Первое, что нужно сделать, это создать модель Comment. Мы создадим это обычным способом, но с одним небольшим отличием.

Введите:

г. Т - один подлый чувак. Я не хотел бы драться с ним.

Первые два предложения:

г. Т - один подлый чувак. Я не хотел бы драться с ним.

Input:

Снайпер Д.С. был казнен и казнен смертельной инъекцией в тюрьме Вирджинии. Смерть была объявлена ​​в 9:11 вечера. ET.

Первые два предложения:

D.C. Снайпер был казнен, казнен смертельной инъекцией в тюрьме Вирджинии. Смерть была объявлена ​​в 9:11 вечера. ET.

Введите:

В своих заключительных замечаниях адвокат-противник сказала, что "... в этом и во многих других случаях два нарушения не могут исправить". Жюри, похоже, согласилось.

Первые два предложения:

В своих заключительных замечаниях адвокат-противник сказал, что "... в этом и во многих других случаях два нарушения не могут исправить". Жюри, похоже, согласилось.

Ребята, как видите, определить два предложения из текста не так просто. (

Ответы [ 7 ]

4 голосов
/ 12 ноября 2009

Как вы заметили, токенизация предложений немного сложнее, чем может показаться на первый взгляд. Таким образом, вы можете также воспользоваться преимуществами существующих решений. Алгоритм токенизации предложений Punkt популярен в НЛП, и в Python Natural Language Toolkit есть хорошая реализация, в которой описывается использование здесь . Они также описывают другой подход здесь .

Возможно, есть и другие реализации, или вы также можете прочитать оригинальную статью , описывающую алгоритм Punkt: Kiss, Tibor and Strunk, Jan (2006): обнаружение границы многоязычного предложения без присмотра. Компьютерная лингвистика 32: 485-525.

Вы также можете прочитать другой вопрос переполнения стека о токенизации предложения здесь .

3 голосов
/ 11 ноября 2009
 your_string = "First sentence. Second sentence. Third sentence"
 sentences = your_string.split(".")
 => ["First sentence", " Second sentence", " Third sentence"]

Нет необходимости усложнять простой код.

Редактировать : Теперь, когда вы пояснили, что реальный ввод более сложен, чем ваш первоначальный пример, вы должны игнорировать этот ответ, поскольку он не учитывает крайние случаи. Начальный взгляд на НЛП должен показать вам, что вы получаете, хотя.

Некоторые из крайних случаев, которые я видел в прошлом, были немного сложными:

  • Даты: в некоторых регионах используется дд.мм.гггг
  • Цитаты: пока он вздыхал & mdash; «Что угодно, сделай это. Сейчас. И, кстати ...». Этого было достаточно.
  • Единицы: он шел на 138 км. во время движения по шоссе.

Если вы планируете анализировать эти тексты, вам следует держаться подальше от разбиений или регулярных выражений.

1 голос
/ 12 ноября 2009

Советы и ссылки на программное обеспечение вы найдете на странице Обнаружение границ предложений Страница Википедии.

1 голос
/ 11 ноября 2009

Это обычно соответствует предложениям.

/\S(?:(?![.?!]+\s).)*[.?!]+(?=\s|$)/m

Для вашего примера двух предложений возьмите первые два совпадения.

1 голос
/ 11 ноября 2009
irb(main):005:0> a = "The first sentence. The second sentence. And the third"
irb(main):006:0> a.split(".")[0...2]
=> ["The first sentence", " The second sentence"]
irb(main):007:0>

РЕДАКТИРОВАТЬ: вот как вы обрабатываете дело «Это предложение ...... и еще. И еще ...»:

irb(main):001:0> a = "This is the first sentence ....... And the second. Let's not forget the third"
=> "This is the first sentence ....... And the second. Let's not forget the thir
d"
irb(main):002:0> a.split(/\.+/)
=> ["This is the first sentence ", " And the second", " Let's not forget the thi    rd"]

И вы можете применить тот же оператор диапазона ..., чтобы извлечь первые 2.

0 голосов
/ 11 ноября 2009

Если вы сегментируете фрагмент текста на предложения, то вам нужно начать с определения того, какие метки могут разделять предложения. В общем, это !, ? и . (но если все, что вам нужно, это . для текстов, которые вы обрабатываете, то просто согласитесь).

Теперь, поскольку они могут появляться внутри кавычек или как части сокращений, вам нужно найти каждое вхождение этих знаков препинания и запустить какой-нибудь классификатор машинного обучения, чтобы определить, начинается ли это вхождение новым предложением или это делает что-то еще. Это включает в себя данные обучения и правильно составленный классификатор. И это не будет на 100% точным, потому что, вероятно, нет способа быть на 100% точным.

Я предлагаю поискать в литературе методы сегментации предложений и взглянуть на различные наборы инструментов обработки естественного языка, которые там есть. Я еще не нашел ни одного для Ruby, но мне нравится OpenNLP (который находится в Java).

0 голосов
/ 11 ноября 2009

Если вы знаете, какие предложения искать, Regex должен хорошо выполнить поиск

((YOUR SENTENCE HERE)|(YOUR OTHER SENTENCE)){1}

Split, вероятно, занял бы довольно много памяти, так как он также сохраняет вещи, которые вам не нужны (весь текст, который не является вашим предложением), так как Regex сохраняет только искомое предложение (если оно его находит, конечно, )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...