Я написал функцию, которая возвращает сглаживание линейной интерполяции trigrams
def smoothed_trigram_probability(trigram):
"""
Returns the smoothed trigram probability (using linear interpolation).
"""
assert len(trigram)==3, "Input should be 3 words"
lambda1 = 1/3.0
lambda2 = 1/3.0
lambda3 = 1/3.0
u,v,w = trigram[0],trigram[1],trigram[2]
prob = (lambda1* raw_unigram_probability(w))+\
(lambda2* raw_bigram_probability((v,w)))+\
(lambda3* raw_trigram_probability((u,v,w)))
return prob
, где 3 метода uni,bi, raw_trigram_probability
возвращают необработанные вероятности следующим образом
def raw_trigram_probability(trigram):
"""
Returns the raw (unsmoothed) trigram probability
"""
assert len(trigram)==3, "Input should be 3 words"
return trigramcounts[trigram]/bigramcounts[trigram[:2]]
def raw_bigram_probability(bigram):
"""
Returns the raw (unsmoothed) bigram probability
"""
assert len(bigram)==2, "Input should be 2 words"
return bigramcounts[bigram]/unigramcounts[bigram[0]]
def raw_unigram_probability(unigram):
"""
Returns the raw (unsmoothed) unigram probability.
"""
uni = []
uni.append(unigram)
assert len(uni)==1, "Input should be only 1 word"
return unigramcounts[unigram]/total_words
В приведенном выше коде uni,bi,trigramcounts
- это диктонары, которые содержат информацию о количестве отдельных единиц, двух и трех граммов в документе
Я использовал total_words
вместо unique_words
для вычислить вероятность униграммы.
Может кто-нибудь подсказать, если это правильный подход, потому что когда я запускаю код с любым неизвестным словом, он выдает DivisionBYZeroError
. Это очевидно, потому что количество слов может быть 0, но это обычно?
Как я могу написать метод sentence_logprob(sentence)
, который возвращает логарифмическую вероятность всей последовательности, используя метод smoothed_trigram_probability