Как я могу вычислить растерянность, используя NLTK - PullRequest
0 голосов
/ 01 марта 2019

Я пытаюсь сделать какой-нибудь процесс над текстом.Это часть моего кода:

fp = open(train_file)
raw = fp.read()
sents = fp.readlines()
words = nltk.tokenize.word_tokenize(raw)
bigrams = ngrams(words,2, left_pad_symbol='<s>', right_pad_symbol=</s>)
fdist = nltk.FreqDist(words)

В старых версиях nltk я нашел этот код в StackOverflow для perplexity

estimator = lambda fdist, bins: LidstoneProbDist(fdist, 0.2) 
lm = NgramModel(5, train, estimator=estimator)
print("len(corpus) = %s, len(vocabulary) = %s, len(train) = %s, len(test) = %s" % ( len(corpus), len(vocabulary), len(train), len(test) ))
print("perplexity(test) =", lm.perplexity(test))   

Однако,этот код больше не действителен, и я не нашел другого пакета или функции в nltk для этой цели.Должен ли я реализовать это?

1 Ответ

0 голосов
/ 07 марта 2019

Недоумение

Предположим, у нас есть модель, которая принимает в качестве ввода английское предложение и выдает оценку вероятности, соответствующую вероятности того, что это правильное английское предложение.Мы хотим определить, насколько хороша эта модель.Хорошая модель должна давать высокую оценку действительным английским предложениям и низкую оценку недействительным английским предложениям.Недоумение - популярная мера для определения того, насколько «хороша» такая модель.Если предложение s содержит n слов, то недоумение

pic

Моделирование распределения вероятности p (построение модели)

pic можно расширить, используя цепочечное правило вероятности

pic

Итак, учитывая некоторые данные (называется поезд данных) мы можем рассчитать вышеуказанные условные вероятности.Однако практически это невозможно, так как требует огромного количества данных для обучения.Затем мы делаем предположение для вычисления

pic

Допущение: все слова независимы (униграмм)

pic

Предположение: марковское предположение первого порядка (биграмма)

Следующие слова зависят только от предыдущего слова

pic

Предположение: n порядок предположения Маркова (ngram)

Следующие слова зависят только от предыдущих n слов

MLE для оценки вероятностей

Оценка максимального правдоподобия(MLE) является одним из способов оценки индивидуальных вероятностей

Unigram

pic, где

  • count (w)количество раз, когда слово w появляется в данных поезда

  • count (vocab) - количество уникальных слов (называемых словарем) в данных поезда.

Биграм

pic где

  • count (w_ {i-1}, w_i) - это количество раз, когда слова w_ {i-1} w_i появляются вместе вта же самая последовательность (биграмма) в данных поезда

  • count (w_ {i-1}) - количество раз, когда слово w_ {i-1} появляется в данных поезда.w_ {i-1} называется контекстом.

Расчет недоумения

Как мы видели выше, $ p (s) $ рассчитывается путем умножения множества маленьких чисел ипоэтому он не является численно стабильным из-за ограниченной точности чисел с плавающей запятой на компьютере.Позволяет использовать приятные свойства журнала просто.Мы знаем pic

pic

Пример: модель Unigram

Данные поезда ["яблоко","апельсин"] Словарь: [an, apple, orange, UNK]

оценки MLE

pic

для тестового предложения "anяблоко "

l =  (np.log2(0.5) + np.log2(0.25))/2 = -1.5
np.power(2, -l) = 2.8284271247461903

Для тестового предложения" муравей "

l =  (np.log2(0.5) + np.log2(0))/2 = inf
Код
import nltk
from nltk.lm.preprocessing import padded_everygram_pipeline
from nltk.lm import MLE

train_sentences = ['an apple', 'an orange']
tokenized_text = [list(map(str.lower, nltk.tokenize.word_tokenize(sent))) 
                for sent in train_sentences]
n = 1
train_data, padded_vocab = padded_everygram_pipeline(n, tokenized_text)
model = MLE(n)
model.fit(train_data, padded_vocab)

test_sentences = ['an apple', 'an ant']
tokenized_text = [list(map(str.lower, nltk.tokenize.word_tokenize(sent))) 
                for sent in test_sentences]

test_data, _ = padded_everygram_pipeline(n, tokenized_text)
for test in test_data:
    print ("MLE Estimates:", [((ngram[-1], ngram[:-1]),model.score(ngram[-1], ngram[:-1])) for ngram in test])

test_data, _ = padded_everygram_pipeline(n, tokenized_text)

for i, test in enumerate(test_data):
  print("PP({0}):{1}".format(test_sentences[i], model.perplexity(test)))

Пример: модель Bigram

Данные поезда:" яблоко ","апельсин "Данные поезда с набивкой:" (s) яблоко (с) "," (s) апельсин (с) "Словарь: (s), (/ s) an, яблоко, апельсин, UNK

оценки MLE

pic

Для тестового предложения "яблоко" дополнено: "(s) яблоко (я)"

l =  (np.log2(p(an|<s> ) + np.log2(p(apple|an) + np.log2(p(</s>|apple))/3 = 
(np.log2(1) + np.log2(0.5) + np.log2(1))/3 = -0.3333
np.power(2, -l) = 1.

Для тестового предложения "Муравей" Подбитый: "(s) Муравей (ы)"

l =  (np.log2(p(an|<s> ) + np.log2(p(ant|an) + np.log2(p(</s>|ant))/3 = inf
Код
import nltk
from nltk.lm.preprocessing import padded_everygram_pipeline
from nltk.lm import MLE
from nltk.lm import Vocabulary

train_sentences = ['an apple', 'an orange']
tokenized_text = [list(map(str.lower, nltk.tokenize.word_tokenize(sent))) for sent in train_sentences]

n = 2
train_data = [nltk.bigrams(t,  pad_right=True, pad_left=True, left_pad_symbol="<s>", right_pad_symbol="</s>") for t in tokenized_text]
words = [word for sent in tokenized_text for word in sent]
words.extend(["<s>", "</s>"])
padded_vocab = Vocabulary(words)
model = MLE(n)
model.fit(train_data, padded_vocab)

test_sentences = ['an apple', 'an ant']
tokenized_text = [list(map(str.lower, nltk.tokenize.word_tokenize(sent))) for sent in test_sentences]

test_data = [nltk.bigrams(t,  pad_right=True, pad_left=True, left_pad_symbol="<s>", right_pad_symbol="</s>") for t in tokenized_text]
for test in test_data:
    print ("MLE Estimates:", [((ngram[-1], ngram[:-1]),model.score(ngram[-1], ngram[:-1])) for ngram in test])

test_data = [nltk.bigrams(t,  pad_right=True, pad_left=True, left_pad_symbol="<s>", right_pad_symbol="</s>") for t in tokenized_text]
for i, test in enumerate(test_data):
  print("PP({0}):{1}".format(test_sentences[i], model.perplexity(test)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...