最近在尝试支持向量机的建模。但是从decision value到probability这一节没有搞明白。
试了R里面的kernlab和e1071两个包,有一些细节上的差异,但是对probability的计算似乎应该都是通过一个函数的转化实现的,p=1/(1+exp(a*x+b))。理论上这里面的参数a应该是个负数,这样才能够让decision value和probability维持单调的关系。但是当我调整模型核函数参数gamma(在kernlab里面应该是sigma)时,会出现a是正数的情形,结果导致预测概率相反。
例如下面这样:
<br />
require(kernlab)</p>
<p>data(promotergene)<br />
set.seed(100)<br />
tindex=sample(1:dim(promotergene)[1],50)<br />
genetrain=promotergene[tindex,]<br />
genetrain$Class[1:5]<br />
[1] + + - + +<br />
Levels: + -</p>
<p>gene=ksvm(Class~.,data=genetrain,kernel="rbfdot",kpar="automatic",C=60,cross=3,prob.model=TRUE)<br />
predict(gene,genetrain)[1:5]<br />
[1] + + - + +<br />
Levels: + -<br />
predict(gene,genetrain,type='decision')[1:5]<br />
[1] -1.0000457 -1.0632764 1.0005555 -0.9999197 -1.0001126<br />
gene@prob.model[[1]]$A<br />
[1] -4.185813<br />
1/(1+exp(gene@prob.model[[1]]$A*predict(gene,genetrain,type='decision')[1:5]+gene@prob.model[[1]]$B))<br />
[1] 0.01862322 0.01435469 0.98798598 0.01863286 0.01861810<br />
predict(gene,genetrain,type='probabilities')[1:5,]<br />
+ -<br />
[1,] 0.98137678 0.01862322<br />
[2,] 0.98564531 0.01435469<br />
[3,] 0.01201402 0.98798598<br />
[4,] 0.98136714 0.01863286<br />
[5,] 0.98138190 0.01861810<br />
</p>
从默认参数的结果看,似乎跟我的理解是一致的:负数的decision对应第一类,正数的decision对应第二类。decision通过一个函数映射到probability,前面的系数是负数使得这两个指标正相关,计算得到的probability是第二类的probability,于是仍然是有probability越大越属于第二类,跟‘正数的decision对应第二类’一致,跟预测结果也一致。
但是当调整核函数的参数以后,结果就会这样:
<br />
gene2=ksvm(Class~.,data=genetrain,kernel="rbfdot",kpar=list(sigma=5),C=60,cross=3,prob.model=TRUE)<br />
predict(gene2,genetrain)[1:5]<br />
[1] + + - + +<br />
Levels: + -<br />
predict(gene2,genetrain,type='decision')[1:5]<br />
[1] -0.9999609 -0.9999609 1.0000391 -1.0009375 -1.0009375<br />
gene2@prob.model[[1]]$A<br />
[1] 3.731806<br />
1/(1+exp(gene2@prob.model[[1]]$A*predict(gene2,genetrain,type='decision')[1:5]+gene2@prob.model[[1]]$B))<br />
[1] 0.97062935 0.97062935 0.01860285 0.97073307 0.97073307<br />
predict(gene2,genetrain,type='probabilities')[1:5,]<br />
+ -<br />
[1,] 0.02937065 0.97062935<br />
[2,] 0.02937065 0.97062935<br />
[3,] 0.98139715 0.01860285<br />
[4,] 0.02926693 0.97073307<br />
[5,] 0.02926693 0.97073307<br />
可以看到,预测结果仍然是正确的。decision也仍然是负数对应第一类,正数对应第二类。decision仍然通过映射得到第二类的probability。但是由于这时的系数变成正数,使得decision跟probability是负相关,于是最终结果变成了:被预测为'-'的(也就是decision较大的)样本的p(+)较大,而被预测为'+'的(也就是decision较小的)样本反而p(-)较大。</p>
这里面是什么机制呢?核函数参数是通过什么途径影响到估计出来的系数a呢?我看教程里面似乎是说计算出decision后通过一个sigmoid函数用'minimizing the negative log-likelihood function'估计出的系数a、b。难道说是通过影响decision而影响了这个估计?但是decision似乎是正确的呀~~~[s:15]
e1071包对libsvm的调用似乎更麻烦,因为他会默认把训练样本中第一个出现的类别定义为类别一,这样就破坏了原本对预测目标的类别的定义,而且他的decision与最终类别的关系跟kernlab里面的相反(kernlab的编码是(-1,1),e1071的编码是(1,-1)),虽然只是个小细节。