Что такое число ngram и как реализовать с помощью nltk?

Я прочитал статью, в которой для классификатора используется функция ngram counts, и мне было интересно, что именно это означает.

Пример текста: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam"

Я могу создавать униграммы, биграммы, триграммы и т.д. из этого текста, где мне нужно определить, на каком уровне вы создадите эти униграммы. "Уровень" может быть символом, слогом, словом,...

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

Создание битрамов приведет к тому, что пары слов объединят слова, которые следуют друг за другом?

Итак, если в статье говорится о подсчетах ngram, она просто создает из текста текстовые символы, биграммы, триграммы и т.д., и подсчитывает, как часто происходит эта ngram?

Есть ли существующий метод в пакете python nltk? Или мне нужно реализовать собственную версию?

Ответ 1

Я нашел свой старый код, возможно, он полезен.

import nltk
from nltk import bigrams
from nltk import trigrams

text="""Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ornare
tempor lacus, quis pellentesque diam tempus vitae. Morbi justo mauris,
congue sit amet imperdiet ipsum dolor sit amet, consectetur adipiscing elit. Nullam ornare
tempor lacus, quis pellentesque diam"""
# split the texts into tokens
tokens = nltk.word_tokenize(text)
tokens = [token.lower() for token in tokens if len(token) > 1] #same as unigrams
bi_tokens = bigrams(tokens)
tri_tokens = trigrams(tokens)

# print trigrams count

print [(item, tri_tokens.count(item)) for item in sorted(set(tri_tokens))]
>>> 
[(('adipiscing', 'elit.', 'nullam'), 2), (('amet', 'consectetur', 'adipiscing'), 2),(('amet', 'imperdiet', 'ipsum'), 1), (('congue', 'sit', 'amet'), 1), (('consectetur', 'adipiscing', 'elit.'), 2), (('diam', 'tempus', 'vitae.'), 1), (('dolor', 'sit', 'amet'), 2), (('elit.', 'nullam', 'ornare'), 2), (('imperdiet', 'ipsum', 'dolor'), 1), (('ipsum', 'dolor', 'sit'), 2), (('justo', 'mauris', 'congue'), 1), (('lacus', 'quis', 'pellentesque'), 2), (('lorem', 'ipsum', 'dolor'), 1), (('mauris', 'congue', 'sit'), 1), (('morbi', 'justo', 'mauris'), 1), (('nullam', 'ornare', 'tempor'), 2), (('ornare', 'tempor', 'lacus'), 2), (('pellentesque', 'diam', 'tempus'), 1), (('quis', 'pellentesque', 'diam'), 2), (('sit', 'amet', 'consectetur'), 2), (('sit', 'amet', 'imperdiet'), 1), (('tempor', 'lacus', 'quis'), 2), (('tempus', 'vitae.', 'morbi'), 1), (('vitae.', 'morbi', 'justo'), 1)]

Ответ 2

Когда вы подсчитываете n-граммы, лучше использовать хеш-таблицу (словарь), а не использовать счет. Для приведенного выше примера:

unigrams = {}
for token in tokens:
  if token not in unigrams:
    unigrams[token] = 1
  else:
    unigrams[token] += 1

это дает вам временную сложность O (n)

Ответ 3

Существует концепция, называемая Collocations в NLTK.

Вы можете найти это полезным.

Ответ 4

Я не думаю, что в nltk есть определенный метод, чтобы помочь с этим. Это не сложно. Если у вас есть предложение из n слов (при условии, что вы используете уровень слов), получите все ngrams длиной 1-n, проведите по каждой из этих ngrams и сделайте их ключами в ассоциативном массиве со значением, являющимся счетчиком. Не должно быть более 30 строк кода, вы можете создать свой собственный пакет для этого и импортировать его там, где это необходимо.