在matlab中测试libsvm时结果不佳

时间:2013-03-22 23:07:27

标签: matlab classification svm libsvm

有人可以帮我解决这个问题吗? 我想测试这种分类是否已经好。所以,我尝试进行数据测试=数据培训。如果分类良好,它将给出100%(acc)。 这是我在这个网站上找到的代码:

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%。你可以帮我纠正这段代码吗?

5 个答案:

答案 0 :(得分:2)

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

第二个是错的,不知道究竟为什么。但是,我可以告诉您,如果使用test_Data = training_Data,几乎总能获得100%的准确率。这个结果实际上没有任何意义,因为算法可能过度拟合而不会在结果中显示。根据新数据测试您的算法,这将为您提供真实的准确性。

答案 1 :(得分:1)

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

当我运行你的代码(Linux,R2011a)时,我在svmtrain调用时遇到错误。使用svmtrain(trainData, double(trainLabel==k))运行会给出有效输出(对于该行)。当然,您似乎没有使用纯matlab,因为您的svmpredict调用不是本机matlab,而是来自LIBSVM的matlab绑定......

答案 2 :(得分:1)

C = confusionmat(testLabel,pred)
交换他们的职位

C = confusionmat(pred,testLabel)

或使用此

[ConMat,order] = confusionmat(pred,testLabel)

显示混淆矩阵和类顺序

答案 3 :(得分: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绑定README:

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.

答案 4 :(得分: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]; 它会成功运作;)