Почему «добавить одно сглаживание» в языковой модели не учитывается в знаменателе </s> - PullRequest
0 голосов
/ 07 ноября 2018

Английский не мой родной язык, извините за любые грамматические ошибки.

Я видел много документов для добавления одного сглаживания в языковой модели, и я все еще очень озадачен переменной V в формуле:

P (wi |w_i-1 ) = c(w_i-1 ,wi )+1  / c(w_i-1 )+V

как в этом примере корпус, и я использую биграмм

<s> John read Moby Dick </s>
<s> Mary read a different book </s>
<s> She read a book by Cher </s>

если я хочу вычислить любой P (wi | w_i-1). V будет 11 потому что количество комбинаций [w_i-1, w] равно 11 , Но я обнаружил, что это не включает в себя регистр [w_i-1, "<" / s ">"] (или V будет 12) Почему нам не нужно включать этот случай? Разве это не тот случай, когда w_i-1 находится в конце статьи или предложения?

1 Ответ

0 голосов
/ 08 ноября 2018

Здесь есть хороший учебник: https://nlp.stanford.edu/~wcmac/papers/20050421-smoothing-tutorial.pdf

Рассмотрим модель языка ngram (без сглаживания):

p (w_i | w_i-1) = c (w_i-1 w_i) / c (w_i-1)

p (w_1, w_2 ... w_n) = product_i = 1_to_n (p (w_i | w_i-1))

В коде:

from collections import Counter
from functools import reduce, partial
from operator import mul

from nltk import ngrams

def prob_product(prob_list):
    return reduce(mul, prob_list, 1)

text = [['<s>', 'John', 'read', 'Moby', 'Dick', '</s>'], 
        ['<s>', 'Mary', 'read', 'a', 'different', 'book', '</s>'], 
        ['<s>', 'She', 'read', 'a', 'book', 'by', 'Cher', '</s>']]

bigram_counts = sum([Counter(ngrams(t, 2)) for t in text], Counter())
unigram_counts = sum([Counter(ngrams(t, 1)) for t in text], Counter())

count_S_John = bigram_counts[('<s>', 'John')]
count_S = unigram_counts[('<s>',)]

sentence = '<s> John read a book </s>'.split()
prob_S_John_read_a_book = prob_product([bigram_counts[bg]/unigram_counts[bg[:-1]]
                                        for bg in ngrams(sentence, 2)])

print(prob_S_John_read_a_book) # 0.555555

for bg in ngrams(sentence, 2):
    print(bg, bigram_counts[bg], unigram_counts[bg[:-1]])

[выход]:

0.55555
('<s>', 'John') 1 3
('John', 'read') 1 1
('read', 'a') 2 3
('a', 'book') 1 2
('book', '</s>') 1 2

С добавлением сглаживания, aka Сглаживание по Лапласу ,

p (w_i | w_i-1) = (1 + c (w_i-1 w_i)) / (| V | + c (w_i-1))

где |V| - количество токенов (обычно без <s> и </s>).

Так в коде:

laplace_prob_S_John_read_a_book = prob_product([(1+bigram_counts[bg]) / (len(unigram_counts)-2 + unigram_counts[bg[:-1]])
                                                for bg in ngrams(sentence, 2)])

print(laplace_prob_S_John_read_a_book)

for bg in ngrams(sentence, 2):
    print(bg, 1+bigram_counts[bg], len(unigram_counts)-2 + unigram_counts[bg[:-1]])

[выход]:

0.00012075836251660427
('<s>', 'John') 2 14
('John', 'read') 2 12
('read', 'a') 3 14
('a', 'book') 2 13
('book', '</s>') 2 13

Примечание: len(unigram_counts)-2 отвечает за удаление <s> и </s> из номера. слов в словаре.


Выше это как.

В: Почему |V| не учитывает <s> и </s>?

A: Одна из возможных причин заключается в том, что мы никогда не рассматриваем пустые предложения в языковых моделях, поэтому <s> и </s> не могут стоять самостоятельно, а словарь |V| исключает их.

Можно ли добавить их в |V|?

A: На самом деле, если |V| достаточно достаточно большой , то наличие +2 для <s> и </s> не будет иметь большого значения. До тех пор, пока |V| непротиворечиво и фиксировано непротиворечиво во всех вычислениях и достаточно велико , вероятности языковой модели любого предложения относительно другого предложения с той же языковой моделью не должны быть слишком разными.

...