2016-04-18 67 views
0

我想使用库LIBSVM对策略'one against all'对5个测试图像进​​行分类,以便获得每个策略的概率类。所使用的代码波纹管:libsvm matlab中的2个错误“模型不支持概率估计和下标分配维度不匹配”

load('D:\xapp.mat'); 
load('D:\xtest.mat'); 
load('D:\yapp.mat');%% matrix contains true class of images yapp=[641;645;1001;1010;1100] 
load('D:\ytest.mat');%% matrix contains unlabeled class of test set ytest=[1;2;3;4;5] 
numLabels=max(yapp); 
numTest=size(ytest,1); 
%# train one-against-all models 
model = cell(numLabels,1); 
for k=1:numLabels 
    model{k} = svmtrain(double(yapp==k),xapp, ['-c 1000 -g 10 -b 1 ']); 
end 
%# get probability estimates of test instances using each model 
prob = zeros(numTest,numLabels); 
for k=1:numLabels 
    [~,~,p] = svmpredict(double(ytest==k), xtest, model{k}, '-b 1'); 
    prob(:,k) = p(:,model{k}.Label==1); %# probability of class==k 
end 
%# predict the class with the highest probability 
[~,pred] = max(prob,[],2); 
acc = sum(pred == ytest) ./ numel(ytest) %# accuracy 

我得到这个错误:

型号不支持probabiliy估计
下标的转让尺寸不匹配。
错误排版(线98)
概率(:,K)= P(:,模型{K} .Label == 1);班%#概率==ķ

请帮我提前解决这个错误,并感谢

+0

我估计错误在行numLabels = MAX(YAPP);'。在这一行中,你基本上说有1100个标签,而这是不正确的,因为你有5个标签。如果'yapp = [641; 645; 1001; 1010; 1100]',那么类的数量是'length(yapp)',而不是'max(yapp)'。 – Alessiox

+0

感谢您的回复,澄清:xapp代表训练集,xtest包含测试集。我知道proplem来自这行numLabels = max(yapp);但是当我用长度替换max(yapp)时,我得到相同的错误。感谢您的任何建议 – aya

+0

你还应该注意'double(yapp == k)'这一行。使用'k'从1到'numLabels'和'yapp',它的范围是[[641; 645; 1001; 1010; 1100]],这个相等性将永远不会被验证。我不认为这会消除这个错误,但是你会得到所有类的全零标签,并且这永远不会导致正确的结果。 – Alessiox

回答

0

什么你正在试图做的是使用一个代码段,用于评估SVM分类演出而你的目标是正确估计你的测试集的标签。

我假设你的五个标签[641;645;1001;1010;1100](如yapp)。首先你必须删除ytest,因为你不知道测试集的任何标签。用ytest填充一些虚拟值是毫无意义的:SVM将返回我们的预测标签。

第一个错误,因为在评论中已经指出的是

numLabels=max(yapp); 

你必须按顺序收集类的数量变化max()length()

训练阶段几乎是正确的。
考虑到k从1变为5而yapp的范围在上面,您应该考虑将double(yapp==k)更改为double(yapp==yapp(k)):以这种方式,我们将yapp中的第k个值标记为正值。鉴于k从1变为5,那么yapp(k)将从641变为1100.

而现在是预测阶段。
svmpredict()的第一个输入应该是测试标签,但现在我们不知道它们,所以我们可以用零矢量填充它(测试集中将有尽可能多的零)。这是因为如果测试标签已知,svmpredict()会自动返回精度,但情况并非如此。所以,你必须在第二个for循环改为

for k=1:numLabels 
    [~,~,p] = svmpredict(zeros(size(xtest,1),1), xtest, model{k}, '-b 1'); 
    prob(:,k) = p(:,model{k}.Label==1); %# probability of class==k 
end 

,最后用

[~,pred] = max(prob,[],2); 

pred包含预测标签预测标签。

注1然而,在这种方法中,您不能测量准确度和/或其他参数,因为我们称为测试集实际上不是测试集。一个测试集是一个标签集,我们假装我们不知道它的标签,以便让SVM预测它们,然后将预测标签与实际标签进行匹配,以便测量它的准确性。

注2:由于第二个for-loop,pred中的预测标签很可能具有范围1到5的值。但是,由于您的标签具有不同的值,因此您可以将映射回考虑到1是641,2是645,3是1001,4是1010,5是1100.

+0

我试过这个,但是我得到了一个矩阵pred作为同伴pred = [5; 5; 5; 5; 5],但实际上类标签是在[641; 645; 1001; 1010; 1100]。究竟是什么问题? – aya

+0

@aya,阅读*注2 * – Alessiox