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

Как определить границы предложения с помощью OpenNLP и stringi?

Я хочу разбить следующий string на предложения:

library(NLP) # NLP_0.1-7  
string <- as.String("Mr. Brown comes. He says hello. i give him coffee.")

Я хочу продемонстрировать два разных способа. Один из пакетов openNLP:

library(openNLP) # openNLP_0.2-5  

sentence_token_annotator <- Maxent_Sent_Token_Annotator(language = "en")  
boundaries_sentences<-annotate(string, sentence_token_annotator)  
string[boundaries_sentences]  

[1] "Mr. Brown comes."   "He says hello."     "i give him coffee."  

И второе происходит из пакета stringi:

library(stringi) # stringi_0.5-5  

stri_split_boundaries( string , opts_brkiter=stri_opts_brkiter('sentence'))

[[1]]  
 [1] "Mr. "                              "Brown comes. "                    
 [3] "He says hello. i give him coffee."

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

Когда речь идет о больших данных, openNLP (очень) медленнее, чем stringi.
Есть ли способ объединить stringi (- > fast) и openNLP (- > качество)?

4b9b3361

Ответ 1

Анализ границы текста (в данном случае, граница предложения) в ICU (и, следовательно, в stringi) регулируется правилами, описанными в Unicode UAX29, см. также Руководство пользователя ICU по теме. Мы читаем:

[Правила Unicode] не могут обнаружить такие случаи, как "... Mr. Jones..."; для обнаружения таких случаев потребуется более сложный пошив.

Другими словами, это невозможно сделать без специального словаря без остановок, который фактически реализован в openNLP. Таким образом, несколько возможных сценариев включения stringi для выполнения этой задачи включают:

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

и т.д.

Ответ 2

Это может быть жизнеспособным регулярным выражением:

string <- "Mr. Brown comes. He says hello. i give him coffee."
stringi::stri_split_regex(string, "(?<!\\w\\.\\w.)(?<![A-Z][a-z]\\.)(?<=\\.|\\?|\\!)\\s")

## [[1]]
## [1] "Mr. Brown comes."   "He says hello."     "i give him coffee."

Выполняется менее эффективно:

string <- "Mr. Brown comes! He says hello. i give him coffee.  i will got at 5 p. m. eastern time.  Or somewhere in between"