Недоумение
Предположим, у нас есть модель, которая принимает в качестве ввода английское предложение и выдает оценку вероятности, соответствующую вероятности того, что это правильное английское предложение.Мы хотим определить, насколько хороша эта модель.Хорошая модель должна давать высокую оценку действительным английским предложениям и низкую оценку недействительным английским предложениям.Недоумение - популярная мера для определения того, насколько «хороша» такая модель.Если предложение s содержит n слов, то недоумение
Моделирование распределения вероятности p (построение модели)
можно расширить, используя цепочечное правило вероятности
Итак, учитывая некоторые данные (называется поезд данных) мы можем рассчитать вышеуказанные условные вероятности.Однако практически это невозможно, так как требует огромного количества данных для обучения.Затем мы делаем предположение для вычисления
Допущение: все слова независимы (униграмм)
Предположение: марковское предположение первого порядка (биграмма)
Следующие слова зависят только от предыдущего слова
Предположение: n порядок предположения Маркова (ngram)
Следующие слова зависят только от предыдущих n слов
MLE для оценки вероятностей
Оценка максимального правдоподобия(MLE) является одним из способов оценки индивидуальных вероятностей
Unigram
, где
count (w)количество раз, когда слово w появляется в данных поезда
count (vocab) - количество уникальных слов (называемых словарем) в данных поезда.
Биграм
где
count (w_ {i-1}, w_i) - это количество раз, когда слова w_ {i-1} w_i появляются вместе вта же самая последовательность (биграмма) в данных поезда
count (w_ {i-1}) - количество раз, когда слово w_ {i-1} появляется в данных поезда.w_ {i-1} называется контекстом.
Расчет недоумения
Как мы видели выше, $ p (s) $ рассчитывается путем умножения множества маленьких чисел ипоэтому он не является численно стабильным из-за ограниченной точности чисел с плавающей запятой на компьютере.Позволяет использовать приятные свойства журнала просто.Мы знаем
Пример: модель Unigram
Данные поезда ["яблоко","апельсин"] Словарь: [an, apple, orange, UNK]
оценки MLE
для тестового предложения "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
Для тестового предложения "яблоко" дополнено: "(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)))