Что такое n-grams и для чего они нужны?

Определение

N-грамма – это последовательность из n-слов или знаков

В английском языке общепринятым названием является “n-gram”, русскоязычный сегмент Википедии предлагает название “N-грамма”. Для простоты, я буду использовать название “н-грамма”.

Области применения

Для чего нужны н-граммы? Для анализа текстов. Тексты разбиваются на последовательности в два, три или более слова, которые в свою очередь называются биграммами, триграммами и т.д. Н-граммы – устойчивые словосочетания двух, трех и т.д. слов, существующие в языке. На основе анализа частоты употребления н-грамм можно рассчитать вероятность появления того или иного предложения, составленного из н-грамм, в реальном человеческом языке. Таким образом, н-граммы используются в следующих областях машинного Анализа Естественного Языка (Natural Language Processing):

  • Машинный перевод
  • Подсказка следующего слова (напр. в поисковой строке)
  • Распознование текста или речи
  • Установление авторства
  • Распознование позитивного или негативного тона отзывов
  • Определение рыночного настроения (например для финансовых рынков)
  • Поиск и коррекция ошибок
  • Анализ и извлечение информации из неструктурированных текстов

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

Пакеты R для извлечения н-грамм из текста

Следующие пакеты имеют функции для извлечения н-грамм из текста:

  • tm/RWeka
  • ngram
  • tau
  • stylo

Все пакеты имеют свои особенности, поэтому я последовательно рассмотрю каждый из 4-ёх, для того, чтобы показать:

  • пример практического использования функций по извлечению н-грамм в каждом из пакетов
  • особенности форматов получаемых результатов и способы просмотра получаемых н-грамм.

Для начала загрузим массив текстов, который мы будем разбивать на биграммы. В данном случае,
анализируемый массив (корпус), состоит из трех текстов text1, text2, text3, каждый из которых состоит из одного предложения (хотя каждый подтекст может быть и романом “Война и мир”).

text1 <- "I'm Sam."
text2 <- "Sam I am."
text3 <- "I do not like green eggs and ham."

1-ый способ: пакет “stylo”

Пакет stylo предоставляет простейший способ составления н-грамм. Единственная подготовительная операция, которую необходимо провести – объединение текстов в один с последующим разбиением на слова

library(stylo)
text 

После проведения этих простых подготовительных операций составление н-грамм сводится
к вызову одной простой функции:

n 
##  [1]"I'm Sam."   "Sam. Sam"   "Sam I"      "I am."      "am. I"     
##  [6]"I do"       "do not"     "not like"   "like green" "green eggs"
## [11]"eggs and"   "and ham."

2-ой способ: Пакет “tm”

Пакет tm является наиболее продвинутым инструментом машинной обработки текстов. Построение н-грамм в пакете tm предполагает сначала создание корпуса:

library(tm)
corp 

Затем создадим две функции для создания н-грамм:

  • функцию ngram_tm, которая создаст матрицу н-грамм для корпуса
  • функцию nTokenizer_Weka которая и будет непосредственно создавать н-граммы
    средствами пакета RWeka
library(RWeka)
library(RWekajars)
ngram_tm 

Как и в предыдущем случае с пакетом stylo, извлечение н-грамм сводится
к вызову функции, которую мы создали выше. Но, в отличие от пакета stylo, результат
будет представлен не в виде вектора полученных н-грамм, а в виде матрицы, строки которой будут соответствовать н-граммам, а столбцы – документам (в нашем случае у нас 3 документа в корпусе, соответственно, у нас будет 3 столбца). 0 на пересечении строки и столбца означает,
что данная н-грамма отсутствует в данном документе.

TM_ngram 
## <>
## Non-/sparse entries: 11/22
## Sparsity           : 67%
## Maximal term length: 10
## Weighting          : term frequency (tf)
## 
##             Docs
## Terms        1 2 3
##   and ham    0 0 1
##   do not     0 0 1
##   eggs and   0 0 1
##   green eggs 0 0 1
##   i am       0 1 0
##   i do       0 0 1
##   i m        1 0 0
##   like green 0 0 1
##   m sam      1 0 0
##   not like   0 0 1
##   sam i      0 1 0

Обратите внимание на две особенности:

  • Знаки препинания, включая апострофы пропали после разбиения на н-граммы! Вместо них мы получили пробелы, таким обзом “I’m” стало н-граммой “i m”
  • Разбиение идет внутри каждого из трех отдельных текстов. Иногда это полезно.

3-ий способ: пакет “ngram”

Пакет ngram так же как и пакет stylo весьма прост в применении и не требует создания дополнительных функций:

library(ngram)
NGRAM_ngram 
##  [1]"like green" "green eggs" "do not"     "eggs and"   "I am."     
##  [6]"and ham."   "Sam I"      "I'm Sam."   "not like"   "Sam. Sam"  
## [11]"I do"       "am. I"

4-ый способ: пакет “tau”

Как и в случае с пакетом tm, создадим сначала вспомогательную функцию a затем применим
эту функцию к тексту:

library(tau)
ngram_tau 
##  [1]"I am."      "I do"       "I'm Sam."   "Sam I"      "Sam. Sam"  
##  [6]"am. I"      "and ham."   "do not"     "eggs and"   "green eggs"
## [11]"like green" "not like"

Выводы

Для чего были представлены 4-е способа решения одной, сравнительно простой задачи?
Для того чтобы выбрать лучший способ, который наиболее подходит для решения
конкретной задачи.

Для начала попробуем сравнить быстродействие:

library(microbenchmark)
microbenchmark(
        make.ngrams(words, n),
        ngram_tm(corp),
        ngram(text, n),
        ngram_tau(text)
        )
Unit: microseconds
                  expr      min        lq       mean    median        uq       max neval cld
 make.ngrams(words, n)   20.604   25.6325   35.81343   33.8045   37.7850   103.227   100 a  
        ngram_tm(corp) 3448.203 3609.7810 4534.83859 3755.9235 4254.3810 32043.306   100   c
        ngram(text, n)  606.432  765.7050  907.13538  841.1335  921.6610  4505.460   100  b 
       ngram_tau(text)  394.953  469.1250  532.99159  502.3340  542.9815  1467.016   100 ab 

Результаты теста ожидаемы: простейшая операция из пакета stylo по разбиению текстового
вектора на н-граммы оказалась самой быстрой!

Важно понимать что сравнивалось быстродействие разных операций: исходные файлы были разные, и результат также представлялся в разных форматах. На приведение исходных данных и результатов к необходимому формату также требуется время!

Кроме быстродействия следует обратить внимание на следующие различия представленных способов:

  • Устойчивость при выполнении. Комбинация TM/RWeka является очень капризной (неустойчивой), ввиду использования Java. Соответственно, потери времени происходят не только на непосредственном исполнении команды, а также на отладке. Остальные пакеты (stylo, ngram, tau) не вызывают нареканий при поиске 2-3-4-грамм на текстах до 300Mb.
  • Простота использования/ малое количество дополнительных аргументов / простота доступа
    к полученным н-граммам. Пакет stylo здесь вне конкуренции, т.к. не только требует минимальнго количества аргументов – вектор слов и количество слов в н-грамме – но и представляет результат в форме, удобной для дальнейшей работы с полученными н-граммами.
Submit your review
1
2
3
4
5
Submit
     
Cancel

Create your own review

Average rating:  
 1 reviews
by Андрей Мукин on Построение n-грамм

Спасибо, просто и понятно! Как различные способы построения n-грамм сравнимы по скорости?

© 2014 In R we trust.
Top
Follow us: