IIS算法数学理论
背景
IIS算法主要用来计算参数估计的maximum-likelihood。 这篇文章主要是解读Adam Berger的算法( IIS Algorithm)。首先这里采用的是概率模型。
参数解释:
Improved Iterative Scaling算法
Maximum-likelihood
首先我们构造基于对数的log-likelihood.
这里的表示<x,y> pair出现在dataset中的概率,一般都是
.。 然后具体的推导不在这里详细详述,推导可以看adam上的论文,我这里直接把结果给出来。因为要求最大的可能性,所以我们需要求这个公式的最大值,就是说对这个公式就导,求导的话,因为
有n个值,所以就要求n次偏导数。从而求到每一个的
.
因为这个式子优化还是比较麻烦,所以Adam文章中采用办法就是一点一点的迭代。原理就是如果我们能够找到一个使得下面的式子成立就可以了。
而且又有![]()
所以只需要上式右边的式子大于0即可,可以看到现在要求的变量变成了。 然后论文最后,再继续优化上式,得到一个式子可以单独的求取
,如下:
其实就是表示在<x,y>这个pair中的所有的feature,在文本分类模型中,就是总共有多少种feature(注意不是多少个.)
因为这里可能每一个的都会不一样,所以可能需要用牛顿迭代求解的方法去求解
。但是,其实有两篇文章(忘了什么名字了)都证明只需要取最大的
来代替就可以了,就是说我们希望计算的方便。
所以我们这里选择:
针对所有的x 和y.
最后可以得到的表达式:
IIS算法流程
第二步,不断执行一下的操作收敛为止,一般很快。
算法的实现和模型训练测试
这里因为代码太长不可能完全放出来,所以打算讲解一部分的核心代码然后把完整代码和数据都放到出来大家下载好了。
首先是feature function的定义。/** * feature function * wordInLabel[c] is a map, to denote that if this word is also in this label. * Note: a word can belongs to many labels. * allFeature List has contained all the words in training dataset * @param i: denote the word[i] in document d * @param d: doc[d], the number of this document * @param c: the label of this document * @return */ private int featureFun(int i,int d,int c){ if(doc[d].getDoc().containsKey(allFeature.get(i)) && wordInLabel[c].containsKey(allFeature.get(i))) return 1; else return 0; }
doc 是我定义的一个document的结构,这个结构里面包含一个 map<word,value>容器的document, key是单词,value是这个单词在这个document中出现的次数。这个结构另外一个成员就是label. 就是这篇document的label.主要是用在训练过程中,测试过程不需要。
/** * Train the data. * getExponentialProb(x,y) function is used to calculate p(y|x) * lamda[] is the final weight coefficients we can get. * @param times: the iteration time, depends on your choice */ private void trainData(int times){ lambda = new double[allFeature.size()]; double[] delta = new double[allFeature.size()]; for(int t=0;t
,显然分子和
是没有关系的,所以我已经预处理在另外一个方法中计算存储起来,这个也是空间换时间的一个概念。
在测试阶段,我通过预测每个label的概率然后进行比较,得到概率最大的那个label. 先给出测试的代码,然后最后给出结果。/** * Get the error rate, remember run the startUp function first * Get the error rate of our model. */ public void testModel(){ int ein = 0; for(int d=0;d
测试数据采用的是 Reuter21578的数据,用了其中的4种类型,acq, coffee, fuel and housing.Best::就是这个算法中预测出来的最好的,就是概率最大的。True:就是真正测试中的结果。
coefficient vector size:1728
acq[0.3559] coffee[0.3012] fuel[0.2457] housing[0.0972] Best:acq True:acq
acq[0.2893] coffee[0.2815] fuel[0.2438] housing[0.1853] Best:acq True:acq
acq[0.2704] coffee[0.2562] fuel[0.2565] housing[0.2170] Best:acq True:acq
acq[0.3340] coffee[0.2252] fuel[0.2659] housing[0.1749] Best:acq True:acq
acq[0.2990] coffee[0.2590] fuel[0.2466] housing[0.1955] Best:acq True:acq
acq[0.2904] coffee[0.2416] fuel[0.2544] housing[0.2136] Best:acq True:acq
acq[0.2978] coffee[0.2767] fuel[0.2406] housing[0.1848] Best:acq True:acq
acq[0.3844] coffee[0.2638] fuel[0.2282] housing[0.1236] Best:acq True:acq
acq[0.2855] coffee[0.3156] fuel[0.2547] housing[0.1442] Best:coffee True:coffee
acq[0.2486] coffee[0.2780] fuel[0.2744] housing[0.1989] Best:coffee True:coffee
acq[0.2407] coffee[0.2871] fuel[0.2596] housing[0.2126] Best:coffee True:coffee
acq[0.2788] coffee[0.2859] fuel[0.2580] housing[0.1773] Best:coffee True:coffee
acq[0.2518] coffee[0.2501] fuel[0.2518] housing[0.2464] Best:acq True:coffee
acq[0.2850] coffee[0.2646] fuel[0.2532] housing[0.1972] Best:acq True:coffee
acq[0.2348] coffee[0.2692] fuel[0.2735] housing[0.2224] Best:fuel True:coffee
acq[0.2382] coffee[0.2678] fuel[0.2727] housing[0.2214] Best:fuel True:coffee
acq[0.2548] coffee[0.2632] fuel[0.2859] housing[0.1962] Best:fuel True:fuel
acq[0.2733] coffee[0.2613] fuel[0.2541] housing[0.2113] Best:acq True:fuel
acq[0.2844] coffee[0.2530] fuel[0.2727] housing[0.1899] Best:acq True:fuel
acq[0.2421] coffee[0.2345] fuel[0.3366] housing[0.1867] Best:fuel True:fuel
acq[0.2579] coffee[0.2519] fuel[0.3093] housing[0.1809] Best:fuel True:fuel
acq[0.2435] coffee[0.2466] fuel[0.3049] housing[0.2050] Best:fuel True:fuel
acq[0.2871] coffee[0.3343] fuel[0.2452] housing[0.1334] Best:coffee True:fuel
acq[0.2738] coffee[0.2191] fuel[0.3157] housing[0.1914] Best:fuel True:fuel
acq[0.2450] coffee[0.2397] fuel[0.2450] housing[0.2702] Best:housing True:housing
acq[0.2202] coffee[0.2054] fuel[0.2335] housing[0.3409] Best:housing True:housing
acq[0.2350] coffee[0.2372] fuel[0.2393] housing[0.2885] Best:housing True:housing
acq[0.2340] coffee[0.2361] fuel[0.2382] housing[0.2917] Best:housing True:housing
acq[0.3156] coffee[0.2897] fuel[0.2219] housing[0.1728] Best:acq True:housing
acq[0.2340] coffee[0.2238] fuel[0.2475] housing[0.2947] Best:housing True:housing
acq[0.2431] coffee[0.2383] fuel[0.2481] housing[0.2706] Best:housing True:housing
acq[0.2525] coffee[0.2460] fuel[0.2737] housing[0.2278] Best:fuel True:housing
error rate is:0.28125
accuracy: 71.75%
其实做了另外一个实验发现用binary classification 的结果更好,就是首先预测
acq- not acq
coffee - not coffee
fuel - not fuel
housing -not housing.
然后最后在combine 这四个结果,得到的准确率会更高。
最后其实我也把IIS模型和 maxent里面已经实现了的GIS模型对比了,发现GIS的收敛的确比IIS慢一点,但是GIS的迭代速度更快。我觉得可能是我的算法写的不好,比较慢。有兴趣的可以尝试用用OPENNLP 的maxent 包。
代码和数据下载
因为我貌似没有找到上传附件的地方,所以我放到百度云上让大家下载吧,下面是连接。
谢谢您的阅读,希望有问题可以一起讨论。