2012-06-11 77 views
10

我正在使用libsvm與預先計算的內核。我爲示例數據集heart_scale生成了預先計算的內核文件並執行了svm-train。它工作正常,支持向量被正確識別,即類似於非預計算版本。Libsvm預先計算的內核

然而,當我試圖運行SVM-預測,它給了預先計算的模型文件不同的結果。在深入瞭解代碼之後,我注意到svm_predict_values()函數需要支持向量的實際特性,這在預計算模式下是不可用的。在預計算模式下,我們只有每個支持向量的係數和索引,這被svm-predict誤解爲它的特徵。

這是一個錯誤或我的理解有問題。如果這是我的錯誤,請告訴我如何在預計算模式下運行svm-predict。

+1

據我所知,如果您使用預先計算的內核來訓練SVM,您必須手動預測值。 – George

回答

4

每個訓練組矢量測試集矢量x之間的內核的評價,和的值應被用作測試集特徵向量。

下面是從LIBSVM自述相關線:
<標籤> 0:I 1:K(XI,X1)... L:K(XI

對於XI

新訓練實例,xL)

任何x的新測試實例:
< label> 0:? 1:K(x,x1)... L:K(x,xL)

libsvm自述文件說如果您有L個訓練集向量,其中xi是訓練集向量, 1..L]和測試集向量x,那麼x的特徵向量應該是

< x> 0的標籤:<任意數> 1:K(x^{test},x1^{其中K(u,v)和K(x,k)分別表示K(u,v)用來表示以向量u和v爲參數的核函數的輸出。

我已經包括下面一些示例Python代碼。

原始特徵向量表示和預先計算(線性)內核的結果不完全相同,但這可能是由於優化算法的差異。

from svmutil import * 
import numpy as np 

#original example 
y, x = svm_read_problem('.../heart_scale') 
m = svm_train(y[:200], x[:200], '-c 4') 
p_label, p_acc, p_val = svm_predict(y[200:], x[200:], m) 

############## 
#train the SVM using a precomputed linear kernel 

#create dense data 
max_key=np.max([np.max(v.keys()) for v in x]) 
arr=np.zeros((len(x),max_key)) 

for row,vec in enumerate(x): 
    for k,v in vec.iteritems(): 
     arr[row][k-1]=v 
x=arr 

#create a linear kernel matrix with the training data 
K_train=np.zeros((200,201)) 
K_train[:,1:]=np.dot(x[:200],x[:200].T) 
K_train[:,:1]=np.arange(200)[:,np.newaxis]+1 

m = svm_train(y[:200], [list(row) for row in K_train], '-c 4 -t 4') 

#create a linear kernel matrix for the test data 
K_test=np.zeros((len(x)-200,201)) 
K_test[:,1:]=np.dot(x[200:],x[:200].T) 
K_test[:,:1]=np.arange(len(x)-200)[:,np.newaxis]+1 

p_label, p_acc, p_val = svm_predict(y[200:],[list(row) for row in K_test], m) 
相關問題