计算词汇量不足的句子的概率

Compute probability of sentence with out of vocabulary words

我在英语语料库上训练了 Ngram 语言模型(unigram 和 bigram),我正在尝试从不相交的语料库中计算句子的概率。

例如,训练语料库由 3 个句子组成:

1:我,我,山姆

2:山姆,我是

3:我,做,不,喜欢,绿色,鸡蛋,和,火腿

N = 14(语料库的长度)

对于 unigram,我得到的概率是:

Pr("i") = #("i") / N = 3/14, Pr("am") = 2/14, Pr("like") = 1/14,依此类推...

对于二元组,我得到的概率是:

Pr("am"|"i") = 2/3,Pr("do"|"i") = 1/3,依此类推...

现在,我正在尝试计算以下句子中并非所有 ngram(uni 或 bi)都出现在训练语料库中的概率:

我吃了一个卷饼

对于 unigram,我需要以下概率估计:

Pr("i")、Pr("ate")、Pr("a") 和 Pr("burrito")

对于二元语法,我需要以下概率估计:

Pr("ate"|"i"), Pr("a"|"ate"), Pr("burrito"|"a")

显然并非所有一元字母 ("ate"、"burrito") 和双字母 (如 ("i"、"ate")) 都出现在训练语料库中。

我知道您可以进行平滑处理(如加一平滑处理)来处理这些情况:

比如训练语料的词汇是

i, am, sam, do, not, like, green, eggs, and, ham

并且您可以通过添加新句子中的新词来扩展词汇量:

吃、吃、吃墨西哥卷饼

所以扩展后的词汇量为 V = 13

所以对于一元组,原始概率估计 Pr(w_i) = #(w_i)/N 将变成 (#(w_i) + 1) / ( N+V)

因此 Pr("i") = 4/27,Pr("am") = 3/27,Pr("sam") = 3/27,Pr("do") = 2/27, Pr("not") = 2/27, Pr("like") = 2/27, Pr("green") = 2/27, Pr("eggs") = 2/27, Pr("and") = 2/27, Pr("ham") = 2/27

以及 3 个新词: Pr("ate") = 1/27,Pr("a") = 1/27,Pr("burrito") = 1/27

并且这些概率总和仍为 1.0

虽然这可以处理某些 ngram 不在原始训练集中的情况,但是当您使用 (#(w_i 估计概率时,您必须知道 "new" 个单词的集合) + 1) / (N + V) (V = 原始训练集(10)和测试语料库(3)的词汇量之和)。我认为这相当于假设测试语料库中所有新的一元组或二元组只出现一次,而不管它们实际出现了多少次。

我的问题是,在计算句子的概率时,通常会采用这种方式来处理词汇外标记?

NLTK 模块 nltk.module.NGramModel 由于错误 nltk ngram model 似乎已被删除,所以我必须自己实现。另一个问题:除了NLTK之外,还有python模块实现了Ngram训练和句子概率的计算吗?

提前致谢!

我的回答基于 "Speech and Language Processing" Jurafsky & Martin 中的一个解决方案,在您根据训练数据构建词汇表的场景中(您有一个空字典)。

在这种情况下,您将词汇表 (OOV) 中新词的任何第一个实例视为未知标记 <UNK>

这样一来,所有生僻字都将成为与未见字相似的标记。要理解原因,请考虑这样一个事实,即一个实例不足以让您的模型基于该实例做出决定。这样,未知标记也有助于您对已见标记的准确性。

我找到了这个 pdf 版本: https://lagunita.stanford.edu/c4x/Engineering/CS-224N/asset/slp4.pdf

关于你的第二个问题,我认为通过对你的文本进行调整和预处理,你可以在 scikit-learn 中使用 CountVectorizer: http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html