2013-03-22 73 views
0

有人可以帮我解决这个问题吗? 我想测试这种分类是否已经很好。所以,我尝试使用数据测试=数据培训。如果分类好,它会给100%(acc)。 这是我从这个网站上找到的代码:在matlab中测试libsvm时效果不佳

data= [170   66   ; 
160   50   ; 
170   63   ; 
173   61   ; 
168   58   ; 
184   88   ; 
189   94   ; 
185   88   ] 

labels=[-1;-1;-1;-1;-1;1;1;1]; 

numInst = size(data,1); 
numLabels = max(labels); 

testVal = [1 2 3 4 5 6 7 8]; 
    trainLabel = labels(testVal,:); 
    trainData = data(testVal,:); 
    testData=data(testVal,:); 
    testLabel=labels(testVal,:); 
numTrain = 8; numTest =8 

%# train one-against-all models 
model = cell(numLabels,1); 
for k=1:numLabels 
    model{k} = svmtrain(double(trainLabel==k), trainData, '-c 1 -t 2 -g 0.2 -b 1'); 
end 

%# get probability estimates of test instances using each model 
prob = zeros(numTest,numLabels); 
for k=1:numLabels 
    [~,~,p] = svmpredict(double(testLabel==k), testData, 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 == testLabel) ./ numel(testLabel) %# accuracy 
C = confusionmat(testLabel, pred)     %# confusion matrix 

,这是结果:

optimization finished, #iter = 16 
nu = 0.645259 obj = -2.799682, 
rho = -0.437644 nSV = 8, nBSV = 1 Total nSV = 8 
Accuracy = 100% (8/8) (classification) 

acc = 

    0.3750 


C = 

    0  5 
    0  3 

我不知道为什么有两大准确性,及其不同。第一个是100%,第二个是0.375。我的代码是否为假?它应该是100%而不是37.5%。你能帮我纠正这个代码吗?

回答

1

是你使用的代码吗?我不认为你的svmtrain调用是有效的。你应该有svmtrain(MAT, VECT, ...)其中MAT是一个数据矩阵,VECT是一个向量,每行的标签为MAT。其余参数是字符串值对,这意味着您将拥有一个字符串标识符及其相应的值。

当我运行你的代码(Linux,R2011a)时,我在svmtrain调用中出错。运行svmtrain(trainData, double(trainLabel==k))给出了有效的输出(对于该行)。当然,看起来你并没有使用纯matlab,因为你的svmpredict调用不是原生matlab,而是一个来自LIBSVM的matlab绑定...

+0

对不起呀亚姆不提,我用libsvm的。在这里我使用LIBSVM。 – user2157806 2013-03-23 01:51:41

2

如果你使用libsvm,那么你应该改变它的名字MEX文件,因为Matlab已经有一个名为svmtrain的svm工具箱。但是,代码正在运行,因此您似乎更改了名称,而不是您提供的代码。

第二个错了,不知道到底为什么。但是,我可以告诉你,如果使用test_Data = training_Data,几乎总能获得100%的准确性。这个结果实际上并不意味着什么,因为算法可能会过度使用,而不会显示在结果中。根据新数据测试你的算法,这会给你一个现实的准确性。

1

C = confusionmat(testLabel,PRED)
交换它们的位置

C = confusionmat(预解码值,testLabel)

或使用本

[ConMat,为了] = confusionmat(预解码值, testLabel)

示出了混淆矩阵和类顺序

0

的问题是在

[~,~,p] = svmpredict(double(testLabel==k), testData, model{k}, '-b 1'); 

p不包含预测标签,它具有标签的概率估计是正确的。 LIBSVM的svmpredict已经正确计算出准确度,这就是为什么它在调试输出中表示100%。 解决方法是简单的:

[p,~,~] = svmpredict(double(testLabel==k), testData, model{k}, '-b 1'); 

根据LIBSVM的Matlab的绑定自述:

The function 'svmpredict' has three outputs. The first one, 
predictd_label, is a vector of predicted labels. The second output, 
accuracy, is a vector including accuracy (for classification), mean 
squared error, and squared correlation coefficient (for regression). 
The third is a matrix containing decision values or probability 
estimates (if '-b 1' is specified). If k is the number of classes 
in training data, for decision values, each row includes results of 
predicting k(k-1)/2 binary-class SVMs. For classification, k = 1 is a 
special case. Decision value +1 is returned for each testing instance, 
instead of an empty vector. For probabilities, each row contains k values 
indicating the probability that the testing instance is in each class. 
Note that the order of classes here is the same as 'Label' field 
in the model structure. 
0

我很遗憾地告诉大家,所有的答案是完全错误的! 在代码完成的主要错误是:

numLabels = max(labels); 

,因为它返回(1),虽然它应该返回2,如果标签是正数,然后svmtrain去/ svmpredict将循环两次。

无论如何,变线labels=[-1;-1;-1;-1;-1;1;1;1];labels=[2;2;2;2;2;1;1;1]; ,它会成功运行;)