读了张乐的源代码,总结如下几点
1,EventSpace对象是一个Event集合,可以是训练集也可以是测试集或者验证集。
2,Event对象就是一个样例具体形式为<outcome,vector<observation>>,每个observation是一个pair<predicate,weight>,总得来说Event对象用来标示训练数据文件中的一行。
3,Maxent对象至少有一个训练集EventSpace对象和一个可选验证集Eventspace对象,一个参数集合集合lamda。为了查找方便,Maxent对象存储了两个map用来将用字符串表示的predicate和output映射为整数,并用param字典来影射一个给定的<predicate,outcome>对应的参数,param的结构为predicateId->pair<outputId,lamda_index>。
4,关于param的构造有两个方法build_params,算法相同数据结构不同而已。需要说明的是对每一个predicate它并非为每一个output都配置一个参数,而是只为那些曾经在training data里面出现过的<predict,output>对配置参数。说一下这两种情况的区别。
设想有一个predicate集合<p1,p2...pn>还有一个output集合<o1,o2...om>。
1)
对一个具体的predicate为每一个output配置参数,形成的feature集合如下
f<p1,o1>=w1,f<p1,o2>=w1...f<p1,om>=w1
f<p2,o1>=w2,f<p2,o2>=w2...f<p2,om>=w2
...
f<pn,o1>=wn,f<pn,o2>=wn...f<pn,om>=wn
总共有m*n个feature,也就需要有m*n个参数,如果给定一个Event表示为<?,{p1:w1,p2:w2,p3:w3}>,欲求其output。<o1,{p1:w1,p2:w2,p3:w3}>...<om,{p1:w1,p2:w2,p3:w3}>用这m个完整的Event代入模型计算得到m个概率,选择概率最大的那个作为最终的预测结果即可。发现为不完整的Event指定一个具体的output之后,feature集合中只有一列会被选中,其的feature在计算过程中都不会被激活。
2)
由于训练数据覆盖范围有限,如果有一些<pi,oj>组合没有出现,则相应的f<pi,oj>不会出现在1)中所列的feature集合里面,从而不会为之准备对应的参数。