Подтвердить что ты не робот

Как вы разбираете абзац текста в предложения? (прямо в Ruby)

Как вы принимаете абзац или большую сумму текста и разбиваете его на предложения (с использованием Ruby), принимая во внимание такие случаи, как г-н и д-р и U.S.A? (Предполагая, что вы просто помещаете предложения в массив массивов)

UPDATE: Одно из возможных решений, о которых я думал, включает использование тегатора части речи (POST) и классификатора для определения конца предложения:

Получение данных от мистера Джонса ощущало теплое солнце на его лице, когда он вышел на балкон своего летнего дома в Италии. Он был счастлив быть живым.

КЛАССИФИКАТОРОВ Г-н/ПЕРСОН Джонс/ЧЕЛОВЕК чувствовал /O/O тепло/O солнце /O включен/O его /O лицо/O как /O он/O ступил /O out/O на /O балкон/O/O his/O summer/O home/O in/O Italy/LOCATION./O He/O was/O happy/O to/O be/O alive/O./O

POST Г-н/ННП Джонс/ННП почувствовал /VBD the/DT warm/JJ sun/NN on/IN his/PRP $face/NN as/IN he/PRP stepped/VBD out/RP на /IN the/DT балкон /NN/IN его/PRP $summer/NN home/NN in/IN Italy./NNP Он /PRP был/VBD happy/JJ to/TO be/VB alive./IN

Можно ли считать, что, поскольку Италия - это место, период является допустимым окончанием предложения? С окончанием на "г-н" не будет других частей речи, можем ли мы предположить, что это не действительный период конца предложения? Это лучший ответ на мой вопрос?

Мысли?

4b9b3361

Ответ 2

Просто, чтобы было ясно, нет простого решения. Это тема исследований НЛП как быстрый поиск Google.

Однако, похоже, что есть некоторые проекты с открытым исходным кодом, связанные с поддержкой обнаружения предложений NLP, я нашел следующий набор инструментов на основе Java:

openNLP

Дополнительный комментарий: Проблема принятия решения о начале и конце предложений предложений также называется границей границ предложения (SBD) в обработка естественного языка.

Ответ 3

Взгляните на разделитель предложений Python в NLTK (набор инструментов Natural Language Tool):

токенизм предложения

На основе следующей статьи:

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

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

Я тестировал этот инструмент неофициально и, кажется, давал хорошие результаты для разных (человеческих) языков.

Портирование его на Ruby было бы нетривиальным, но это могло бы дать вам некоторые идеи.

Ответ 5

Это сложная проблема, если вы действительно заботитесь о ее правильном использовании. Вы обнаружите, что пакеты парсеров NLP, вероятно, предоставляют эту функцию. Если вы хотите что-то быстрее, вам нужно будет дублировать некоторые из этих функций с помощью обученной вероятностной функции окна токенов (вы, вероятно, захотите подсчитать фид строки как токен, так как я могу отказаться от периода, если это конец абзаца).

Изменить: я рекомендую парсер Stanford, если вы можете использовать Java. У меня нет рекомендаций для других языков, но мне очень интересно узнать, что еще есть, что есть с открытым исходным кодом.

Ответ 6

К сожалению, я не рубиновый парень, но, может быть, пример в perl заставит вас идти в правильном направлении. Используя несовместимый внешний вид для финишной пунктуации, некоторые частные случаи в не отставании, за которыми следует любое количество пробелов, за которым следует взгляд за большой буквы. Я уверен, что это не идеально, но я надеюсь, что это указывает на то, что вы в правильном направлении. Не знаете, как вы узнаете, действительно ли U.S.A в конце предложения...

#!/usr/bin/perl

$string = "Mr. Thompson is from the U.S.A. and is 75 years old. Dr. Bob is a dentist. This is a string that contains several sentances. For example this is one. Followed by another. Can it deal with a question?  It sure can!";

my @sentances = split(/(?:(?<=\.|\!|\?)(?<!Mr\.|Dr\.)(?<!U\.S\.A\.)\s+(?=[A-Z]))/, $string);

for (@sentances) {
    print $_."\n";
}

Ответ 7

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

Изменить: Поиск заглавных букв с помощью Ruby.

Другое Редактировать:

Проверяйте препинание пунктуации, которая следует за словами, которые не начинаются с прописных букв.

Ответ 8

Ответ доктора Мэннинга является наиболее подходящим, если вы рассматриваете JAVA (и Ruby тоже нелегко;)). Он здесь -

Существует разделитель предложений: edu.stanford.nlp.process.DocumentPreprocessor, Попробуйте выполнить команду: java edu.stanford.nlp.process.DocumentPreprocessor /u/nlp/data/lexparser/textDocument.txt

oneTokenizedSentencePerLine.txt. (Это делается через (хороший, но   эвристический) FSM, так что это быстро; Вы   не запуская вероятностный синтаксический анализатор.)

Но небольшое предложение, если мы изменим команду java edu.stanford.nlp.process.DocumentPreprocessor/u/nlp/data/lexparser/textDocument.txt > oneTokenizedSentencePerLine.txt  TO java edu.stanford.nlp.process.DocumentPreprocessor -file/u/nlp/data/lexparser/textDocument.txt > oneTokenizedSentencePerLine.txt. Он будет работать нормально, так как вам нужно указать, какой файл будет представлен в качестве входных данных. So -file для текстового файла, -html для HTML и т.д.

Ответ 9

Я не пробовал, но если английский - это единственный язык, который вас интересует, я предлагаю дать Lingua:: EN:: Readability взгляд.

Lingua:: EN:: Readability - это модуль Ruby, который вычисляет статистику по английскому тексту. Он может содержать подсчет слов, предложений и слогов. Он также может рассчитать несколько показателей удобочитаемости, таких как индекс тумана и уровень Flesch-Kincaid. Пакет включает в себя модуль Lingua:: EN:: Sentence, который разбивает английский текст на предложения, учитывающие аббревиатуры, и Lingua:: EN:: Syllable, который может угадывать количество слогов в письменном английском слове. Если доступен словарь произношения, он может искать количество слогов в словаре для большей точности

Бит, который вы хотите, находится в sentence.rb следующим образом:

module Lingua
module EN
# The module Lingua::EN::Sentence takes English text, and attempts to split it
# up into sentences, respecting abbreviations.

module Sentence
  EOS = "\001" # temporary end of sentence marker

  Titles   = [ 'jr', 'mr', 'mrs', 'ms', 'dr', 'prof', 'sr', 'sen', 'rep', 
         'rev', 'gov', 'atty', 'supt', 'det', 'rev', 'col','gen', 'lt', 
         'cmdr', 'adm', 'capt', 'sgt', 'cpl', 'maj' ]

  Entities = [ 'dept', 'univ', 'uni', 'assn', 'bros', 'inc', 'ltd', 'co', 
         'corp', 'plc' ]

  Months   = [ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 
         'aug', 'sep', 'oct', 'nov', 'dec', 'sept' ]

  Days     = [ 'mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun' ]

  Misc     = [ 'vs', 'etc', 'no', 'esp', 'cf' ]

  Streets  = [ 'ave', 'bld', 'blvd', 'cl', 'ct', 'cres', 'dr', 'rd', 'st' ]

  @@abbreviations = Titles + Entities + Months + Days + Streets + Misc

  # Split the passed text into individual sentences, trim these and return
  # as an array. A sentence is marked by one of the punctuation marks ".", "?"
  # or "!" followed by whitespace. Sequences of full stops (such as an
  # ellipsis marker "..." and stops after a known abbreviation are ignored.
  def Sentence.sentences(text)

    text = text.dup

    # initial split after punctuation - have to preserve trailing whitespace
    # for the ellipsis correction next
    # would be nicer to use look-behind and look-ahead assertions to skip
    # ellipsis marks, but Ruby doesn't support look-behind
    text.gsub!( /([\.?!](?:\"|\'|\)|\]|\})?)(\s+)/ ) { $1 << EOS << $2 }

    # correct ellipsis marks and rows of stops
    text.gsub!( /(\.\.\.*)#{EOS}/ ) { $1 }

    # correct abbreviations
    # TODO - precompile this regex?
    text.gsub!( /(#{@@abbreviations.join("|")})\.#{EOS}/i ) { $1 << '.' }

    # split on EOS marker, strip gets rid of trailing whitespace
    text.split(EOS).map { | sentence | sentence.strip }
  end

  # add a list of abbreviations to the list that used to detect false
  # sentence ends. Return the current list of abbreviations in use.
  def Sentence.abbreviation(*abbreviations)
    @@abbreviations += abbreviations
    @@abbreviations
  end
end
end
end

Ответ 10

Согласитесь с принятым ответом, использование Stanford Core NLP не имеет проблем.

Однако в 2016 году существует некоторая несовместимость, взаимодействующая с Stanford Parser с более поздние версии ядра stanford nlp (у меня были проблемы с Stanford Core NLP v3.5).

Вот что я сделал, чтобы разобрать текст в предложениях с использованием Ruby-интерфейса с помощью NLP Stanford Core:

Использование последней версии Stanford CoreNLP (версия 3.5.0 на 31/10/2014) требуется несколько дополнительных шагов:

  • Загрузите Stanford CoreNLP версия 3.5.0 из http://nlp.stanford.edu/.

  • Поместите содержимое извлеченного архива в папку /bin/ драгоценный камень stanford-core-nlp (например, [...]/gems/stanford-core-nlp-0.x/bin/) или внутри местоположения каталога, настроенного настройкой StanfordCoreNLP.jar_path.

  • Загрузите полную версию Stanford Tagger 3.5.0 из http://nlp.stanford.edu/.
  • Создайте каталог с именем 'taggers' внутри/bin/папки жгута stanford-core-nlp (например, [...]/gems/stanford-core-nlp-0.x/bin/) или внутри каталога сконфигурированный настройкой параметра StanfordCoreNLP.jar_path.
  • Поместите содержимое извлеченный архив внутри каталога taggers.
  • Загрузите файл bridge.jar из https://github.com/louismullie/stanford-core-nlp.
  • Поместите загруженный файл bridger.jar в папку /bin/ стэнфорд-сердечник-nlp (например, [...]/gems/stanford-core-nlp-0.x/bin/taggers/) или внутри каталога настраивается с помощью параметра StanfordCoreNLP.jar_path.

Затем код ruby ​​для разделения текста на предложения:

require "stanford-core-nlp"

#I downloaded the StanfordCoreNLP to a custom path:
StanfordCoreNLP.jar_path = "/home/josh/stanford-corenlp-full-2014-10-31/"

StanfordCoreNLP.use :english
StanfordCoreNLP.model_files = {}
StanfordCoreNLP.default_jars = [
  'joda-time.jar',
  'xom.jar',
  'stanford-corenlp-3.5.0.jar',
  'stanford-corenlp-3.5.0-models.jar',
  'jollyday.jar',
  'bridge.jar'
]

pipeline =  StanfordCoreNLP.load(:tokenize, :ssplit)

text = 'Mr. Josh Weir is writing some code. ' + 
  'I am Josh Weir Sr. my son may be Josh Weir Jr. etc. etc.'
text = StanfordCoreNLP::Annotation.new(text)
pipeline.annotate(text)
text.get(:sentences).each{|s| puts "sentence: " + s.to_s}

#output:
#sentence: Mr. Josh Weir is writing some code.
#sentence: I am Josh Weir Sr. my son may be Josh Weir Jr. etc. etc.

Ответ 11

Я не парень из Ruby, но RegEx, который разбился на

 ^(Mr|Mrs|Ms|Mme|Sta|Sr|Sra|Dr|U\.S\.A)[\.\!\?\"] [A-Z]

было бы лучше, если у вас есть параграф (разделить на \r\n). Это предполагает, что ваши предложения правильно обрезаны.

Очевидно, это довольно уродливый RegEx. Как насчет ввода двух пробелов между предложениями

Ответ 12

Разрыв в течение периода, за которым следует пробел, и заглавная буква не будет летать для таких титулов, как "Мистер Браун".

Периоды делают вещи трудными, но простой случай для обработки - восклицательные знаки и вопросительные знаки. Однако бывают случаи, когда это не сработает. то есть корпоративное имя Yahoo!

Ответ 13

Ну, очевидно, paragraph.split('.') не будет вырезать его

#split будет принимать регулярное выражение в качестве ответа, поэтому вы можете попробовать использовать нулевую ширину для проверки слова, начинающегося с заглавной буквы. Конечно, это разделится на собственные имена, поэтому вам придется прибегнуть к регулярному выражению, подобному этому /(Mr\.|Mrs\.|U\.S\.A ...), которое было бы ужасно уродливым, если вы программно не создали регулярное выражение.

Ответ 14

Я думаю, что это не всегда разрешимо, но вы можете разделить на основе "." (период с последующим и пустым пространством) и проверить, что слово до периода не находится в списке таких слов, как Mr, Dr, и др.

Но, конечно, ваш список может опустить некоторые слова, и в этом случае вы получите плохие результаты.

Ответ 15

БЛАГОДАРЯ

Мне очень понравилось это обсуждение, поэтому я заинтересовался парсером. Я попробовал это, и я записал несколько заметок о том, как все работает с Ruby и Rails!

Попытка пойти с регулярным выражением была кошмаром.

мои 2 цента