输入法中统计语言模型的建立以及平滑java版
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
输入法中统计语言模型的建立以及平滑 java版输入法中统计语言模型的建立以及平滑
java版
输入法中统计语言模型的建立以及平滑(java版)西安电子科技大学目前正在编写手机平台上的输入法,在输入法中要向实现句子级别的智能输入,必须借助统计语言模型,依靠统计语言模型中的词概率值,输出最可能的句子。
下面将介绍统计语言模型的建立以及平滑。
目前输入法中常用的语言模型有trigram(三元)和bigram(二元),其中微软拼音、智能狂拼使用的是trigram,谷歌拼音、搜狗拼音和紫光则是bigram。
本文以二元模型为例来说明模型的建立和平滑。
下面分三个
方面来介绍:语料库的预处理模型的建立模型的平滑一.语料库的预处理原始语料库来源于北京大学语言研究所提供的98年1月人民日报标注语料。
下载的已切分的语料都是形如"19980131-04-012-001/m现实/n的/u顿悟/vn却/d被/p描/v出/v
形/Ng来/v。
/w",有的前面还保留了日期编号,因为这些切分语料的来源是人民
日报。
预处理主要是按标点符号分句,句子简单定义为(。
?~:;)这五种标点符号结尾的词串,句子首尾分别添加BOS和EOS这两个表示句子开始和结束的标记,这在2-gram建模时要用的,后面会提到。
处理过程中,忽略词类信息和前面的日期信息,因为我这个切分系统不考虑词类标注。
如前面这句预处理后应该为下面形式"BOS现实的顿悟却被描出形来。
EOS",当然切分词之间你可以用你想用的符号标记,而不必是空格。
因为考虑到所有的英文字符和数字的ASCII,我用了下面方法实现之(至于为什么切分成这样,请参照马尔科夫模型的概率归一性)FileReader fi=new FileReader(f);BufferedReader bf=new BufferedReader(fi);FileWriter fo=new FileWriter(ff);StringBuffer s1=new StringBuffer();String
s;while((s=bf.readLine())~=null){for(int i=0;i s.length();i++){char
a=s.charAt(i);if((a=='。
'||a=='?'||a=='~'||a==':'||a==';'))//一句结束{String s2=new String(s1);fo.write("BOS");//在句子前加BOS
fo.write(s2);fo.write("EOS");//在句子末尾加EOS
fo.write("\r\n");fo.flush();s1=new StringBuffer();}else
if(a=='/')s1=s1.append((char)32);//分词位置空格else if(a
256)s1=s1.append(a);}}二:模型的建立在这里首先简单介绍一下n-gram模型和2-gram模型。
根据语言样本估计出的概率分布P就称为语言L的语言模型。
对给定的句子s=w1w2…wn,(数字,n,i都为下标,wi为句子s的一个词)。
由链式规则(Chain rule),P(s)=p(w1)p(w2|w1)p(w3|w1w2)…p(wn|w1w2w3…w(n-1)),对p(wi|w1w2…w(i-1))而言,(w1w2…w(i-1))即为wi的历史。
考虑前面n-1个词构成历史的模型即为n-gram模型。
n越大,提供的语境信息也越多,但代价就越大,且需训练语料多;n较小时,提供的信息比较少,但计算代价小,且无需太多训练语料。
令c(w1,…,wi)表示词串w1,w2…wi在训练语料中出现的次数,则由最大似然估计,P(wn|w1,…,w(n-1))=c(w1,…,wn)/c(w1,…,w(n-1)).同理,则2-gram为P(wn|w(n-1))=c(w(n-1),wn)/c(w(n-1)).回归项目:)训练语料一共有5万多个不同的词。
建立2-gram统计模型时不断要把每个词在训练语料中出现频率统计出来,还要把每个词及其后面的那个词组成的
-2-gram在训练语料中出现频率统计出来。
因为在切分时会频繁的在建立的
2gram模型中查找相关的数据,所有,存储这个2-gram模型数据的数据结构一定要能提供高效的查找。
故选择hash表,它能提供常数时间的查找。
Java类库里提供了HashMap类,基于数据两还不是非常大,故可直接拿来用。
在存储时,每一个key值对应一个在训练语料中出现过的词语,而每一个key值对应的value值又是一个HashMap。
暂且称为子hashmap.这个结构有点类似文件结构里的二级索引。
其相关代码如下:怎么在预处理文件里把词分别读出来就不罗嗦了,方法:每读入一
行,按空格分成String数组,用个正则表达式匹配下即能得到。
下面这个方法传入的两个词组成一个2-gram,prewd为前一个词,currwd为紧随其后的词public void add(String prewd,String
currwd){String key=prewd;String curr=currwd;
if(mainhm.containsKey(key)==false){//若主map中无,则添加HashMap
hm=new HashMap();//首先,新构造一个子MAP hm.put(key,new
Double(1.0));mainhm.put(key,hm);//将主KEY和对应的子MAP放入主MAP
中}else//若主map中含有该词{HashMap temp=(HashMap)mainhm.get(key);Double count=((Double)temp.get(key)).doubleValue()+1.0;
temp.put(key,new Double(count));if(temp.containsKey(curr))//判断子map中是否含有该词{Double
value=((Double)temp.get(curr)).doubleValue()+1.0;temp.put(curr,new Double(value));}else temp.put(curr,new Double(1.0));//若无,则将其存入子map mainhm.put(key,temp);}}三.模型的平滑因为语言中的大部分词属于低频词,所以稀疏问题肯定存在。
而MLE(最大似然估计)给在训练语料中
没有出现的2-gram的赋给0概率。
所以还得对2-gram模型进行数据平滑,以期得到更好的参数。
目前平滑技术比较多,如Add-one,Add-delta,Witten- Bell,held-out留存平滑等。
本文采用Katz方法进行平滑:Katz算法的平滑
公式是:其中在我们实现算法的时候,先遍历n-gram中的数据,先将C(Wi,Wi-1)0时候的Pkz都算出来(即分子上面的),然后再从unigram中,将分母中所有的Pml 都算出来,然后代入上式,计算并将保存到n-gram的数据结构中。
部分代码如下:Iterator it=mainhm.keySet().iterator();while(it.hasNext()){String
key=(String)it.next();HashMap sonhm=(HashMap)mainhm.get(key);//子Map Double n=(Double)sonhm.get(key);Iterator
itr=sonhm.keySet().iterator();itr.next();while(itr.hasNext()){//套平滑公式String
Double s=(String)itr.next();Double
value=(Double)sonhm.get(s);newvalue=(value-
0.3)/n;sonhm.put(s,newvalue);}}以上讲述了统计语言模型的建立以及平滑算法,输入法正在制作当中,按上面讲述的方法,目前准备率还不得而知,仅仅是个人的一些理解。