使用预先计算的内核函数与LibSVM

22

我目前正在使用不同的图像描述符对图像进行分类。由于它们具有自己的度量标准,因此我正在使用预先计算的核函数。因此,给定这些NxN核矩阵(共N个图像),我想训练和测试支持向量机(SVM)。虽然我对使用SVM并不是很有经验,但是令我困惑的是如何输入训练的数据。

使用核MxM(M为训练图像数)的子集,将用M个特征来训练SVM。然而,如果我理解正确的话,这会限制我使用具有类似数量特征的测试数据。尝试使用大小为MxN的子核在训练期间导致无限循环,因此,在测试时使用更多的特征会产生较差的结果。

这导致使用相等大小的训练和测试集得到合理的结果。但是,如果我只想对一个图像进行分类,或者对每个类别都使用一定数量的图像进行训练并使用其余图像进行测试,这根本行不通。

如何消除训练图像和特征数量之间的依赖性,以便我可以使用任意数量的图像进行测试?我正在使用MATLAB的libsvm,核是在[0,1]之间的距离矩阵。


1
已解决:给定一个Mx(M+1)的训练核(+1是强制索引),测试核应该(当然)是大小为Kx(M+1),其中K是测试图像的数量。 - Henrik
1个回答

42

你似乎已经找出了问题……根据MATLAB软件包中包含的README文件:

要使用预先计算的内核,必须将样本序列号作为训练和测试数据的第一列。

我来举个例子说明:

%# read dataset
[dataClass, data] = libsvmread('./heart_scale');

%# split into train/test datasets
trainData = data(1:150,:);
testData = data(151:270,:);
trainClass = dataClass(1:150,:);
testClass = dataClass(151:270,:);
numTrain = size(trainData,1);
numTest = size(testData,1);

%# radial basis function: exp(-gamma*|u-v|^2)
sigma = 2e-3;
rbfKernel = @(X,Y) exp(-sigma .* pdist2(X,Y,'euclidean').^2);

%# compute kernel matrices between every pairs of (train,train) and
%# (test,train) instances and include sample serial number as first column
K =  [ (1:numTrain)' , rbfKernel(trainData,trainData) ];
KK = [ (1:numTest)'  , rbfKernel(testData,trainData)  ];

%# train and test
model = svmtrain(trainClass, K, '-t 4');
[predClass, acc, decVals] = svmpredict(testClass, KK, model);

%# confusion matrix
C = confusionmat(testClass,predClass)

输出结果:
*
optimization finished, #iter = 70
nu = 0.933333
obj = -117.027620, rho = 0.183062
nSV = 140, nBSV = 140
Total nSV = 140
Accuracy = 85.8333% (103/120) (classification)

C =
    65     5
    12    38

是的,这就是我解决问题的方法。对于要使用哪些内核部分有点困惑。不过样例代码很好。 - Henrik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接