我在英语语料库中训练了Ngram语言模型(unigram和bigram),并且我试图从不相交的语料库中计算句子的概率。
例如,训练语料库由3个句子组成:
1:我,是,Sam
2:山姆,我,是
3:我,不,像绿色,鸡蛋和火腿
N = 14(语料库的长度)
对于unigram,我最终得出概率:
Pr(“i”)=#(“i”)/ N = 3/14,Pr(“am”)= 2/14,Pr(“like”)= 1/14,依此类推..
对于bigram,我最终得出概率:
Pr(“am”|“i”)= 2/3,Pr(“do”|“i”)= 1/3,等等......
现在,我正在尝试计算以下句子的概率,其中并非所有ngrams(uni或bi)都出现在训练语料库中:
我,吃,a,卷饼
对于unigram,我需要以下概率估计:
Pr(“i”),Pr(“ate”),Pr(“a”)和Pr(“burrito”)
对于bigram,我需要以下概率估算:
Pr(“ate”|“i”),Pr(“a”|“ate”),Pr(“burrito”|“a”)
显然并非所有的unigrams(“吃”,“墨西哥卷饼”)和双字母(如(“我”,“吃”))都出现在训练语料库中。
我知道您可以进行平滑处理(例如添加一个平滑处理)来处理这些情况:
例如,训练语料库的词汇是
我,我,山姆,做,不,像,绿色,鸡蛋和火腿
您可以通过在新句子中添加新单词来扩展词汇量:
ate,a,burrito
因此扩展词汇量的大小为V = 13
因此对于unigram,原始概率估计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
虽然这可以处理一些ngrams不在原始训练集中的情况,但是当使用(#(w_i)+ 1)/(N +)估计概率时,你必须知道“新”单词的集合。 V)(V =原始训练集(10)和测试语料库(3)的词汇总和)。我认为这相当于假设测试语料库中的全新unigram或bigram只出现一次,无论它们实际出现多少次。
我的问题是,在计算句子的概率时,通常会处理词汇外令牌的方式吗?
由于错误nltk ngram model,NLTK模块nltk.module.NGramModel似乎已被删除,所以我必须自己实现。另一个问题:是否有除NLTK以外的python模块实现Ngram训练和计算句子的概率?
提前致谢!
答案 0 :(得分:0)
我的回答是基于"言语和语言处理" Jurafsky&马丁,根据你的训练数据建立你的词汇的场景(你有一个空字典)。
在这种情况下,您将词汇(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