使用LIBSVM进行一对多休息多类分类。 MATLAB

时间:2014-04-29 06:49:22

标签: matlab classification libsvm

我正在尝试使用LIBSVM实现一个vs rest多类分类。

此链接很有用http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/ovr_multiclass/ 但我在函数'ovrpredict()'中得到一个错误。

功能如下:

function [pred, ac, decv] = ovrpredict(y, x, model)

labelSet = model.labelSet;
labelSetSize = length(labelSet);
models = model.models;
decv= zeros(size(y, 1), labelSetSize);

for i=1:labelSetSize
  [l,a,d] = svmpredict(double(y == labelSet(i)), x, models{i});
  decv(:, i) = d * (2 * models{i}.Label(1) - 1);             % ERROR IN THIS LINE
end
[tmp,pred] = max(decv, [], 2);
pred = labelSet(pred);
ac = sum(y==pred) / size(x, 1);

我得到的错误消息是Reference to non-existent field 'Label'

任何建议都会非常有用。


编辑1

用于调用函数的代码:\

[trainY trainX]=libsvmread('libfacecombine.train');
[testY testX]=libsvmread('libfacetest.train');
model=ovrtrain(trainY,trainX,'-c 8 -g 4');
[~,accuracy,~]=ovrpredict(testY,testX,model);

训练和测试数据即“libfacecombine.train”和“libfacetest.train”是从.csv文件中编写的:

f1=createdabase(f);     % where createdatabase is a function to read various images from a folder and arrange into 1D array
[sig1 mn1]=pcam(f1);    % where pcam is a function to find 'pca'(sig1) and 'mean'(mn1) of the data

%labelling is done this way:
%Positive class
        label=[];
        for i=1:length(sig1)
            for j=1:1
                label(i,j)=+1;
            end
        end
    csvwrite('face1.csv',[label sig1]);

%Negative class
        label1=[];
            for i=1:length(sig2)             % sig2 obtained in same way as sig1
                for j=1:1
                    label1(i,j)=-1;
                end
            end
        csvwrite('face2.csv',[label sig2]);

使用“追加”模式,这两个文件将被连接并转换为.train文件。 测试数据也是如此。

编辑2

我有5节课。标签如下: 等级1:+1包含来自面部1的4个图像的特征,-1包含来自4个不是面部1的图像(面部2,3,4和5)的特征。第2类:+2包含面部2的4个图像的特征,-2包含4个非面部2的图像(面部1,3,4和5)的特征....类别5:+5包含4个图像的特征面5和-5包含来自4个非面5(面1,2,3和4)的图像的特征。所有这些功能以及标签都按照上面给出的顺序写入.csv文件,然后转换为.train格式。因此我获得了培训文件。

对于测试图像,我拍摄一张脸1的图像并给出其真实标签,即+1,并写入.csv文件,然后转换为.train。因此我获得了测试文件。当我运行程序时,我获得了以下结果:

Accuracy=92%(12/13)classification; 
Accuracy=61%(8/13)classification;
Accuracy=100%(13/13)classification;
Accuracy=100‌​%(13/13)classification;
Accuracy=100%(13/13)classification;
Accuracy=100%(13/13)cla‌​ssification; 

为什么我只有5个班级才能获得6个准确度值?

2 个答案:

答案 0 :(得分:2)

通过互联网找到类似这样的解决方案很棘手,但让我们试一试。这篇文章由问题而不是答案组成。但是,我相信如果你回答所有这些问题,你会发现你的错误而没有进一步的帮助 - 或者至少是那里的90%。

所有这些步骤都适用于调试任何类型的MATLAB程序。


确保工作空间清晰

工作区中闲置的旧版本变量可能会使调试变得困难。变量名中的拼写错误可能导致意外使用旧版本。在调试开始时使用clear清除工作区。


运行更简单的程序

我编译了libsvm,添加了ovr_multiclass个插件,我可以成功运行我编写的以下示例脚本:

clear

% random train and test data
trainX = rand(10, 4);
trainY = randi(4, 10, 1);
testX = rand(10, 4);
testY = randi(4, 10, 1);

model=ovrtrain(trainY,trainX,'-c 8 -g 4'); 
[~,accuracy,~]=ovrpredict(testY,testX,model);

你可以运行它,或者你得到和以前一样的错误? 这种 最小工作示例 对于调试非常有用。 使用用户生成的小数据可确保错误不会来自意外来源,并有助于缩小原因。


检查models单元格数组

您声明错误发生在此:

decv(:, i) = d * (2 * models{i}.Label(1) - 1);             % ERROR IN THIS LINE

该行的关键部分是models{i}.Label(1)。这是一个单元格数组models,并提取i项。这个i项应该是一个结构,名为LabelLabel应该是一个非空数组,从中可以提取第一个元素。 models单元格数组是结构model中的一个字段,它作为第三个参数传递给ovrpredict

运行上面非常简单的测试脚本后,我在MATLAB命令窗口中运行以下诊断程序:

>> models = model.models

models = 

    [1x1 struct]
    [1x1 struct]
    [1x1 struct]
    [1x1 struct]

>> models{1}

ans = 

    Parameters: [5x1 double]
      nr_class: 2
       totalSV: 6
           rho: -1.2122
         Label: [2x1 double]
    sv_indices: [6x1 double]
         ProbA: []
         ProbB: []
           nSV: [2x1 double]
       sv_coef: [6x1 double]
           SVs: [6x4 double]

>> models{1}.Label

ans =

     0
     1

如果你这样做,你会得到相同的结果吗?如果没有,请在编辑问题时将输出发布到这些命令。


在函数

中调试

如果模型看起来没问题,但仍然出现错误,请在命令窗口中键入错误调试器:

dbstop if error

当MATLAB在函数中遇到错误时,它将暂停并允许您检查所有变量。

再次运行您的程序(或者我的程序,如果您收到我发布的最小工作示例的错误)。发生错误时,程序应暂停。您的命令提示符应从>>更改为K>>

运行上述步骤以示例model cells数组。然后尝试复制,粘贴和运行在命令窗口中给出错误的代码行。尝试运行它的一小部分,例如models{i}.Label(1)然后2 * models{i}.Label(1) - 1

键入dbquit以退出调试器,并dbclear if error关闭错误时自动调试。

(另请参阅下面有关错误消息的问题 - 请确保错误实际发生在您认为的位置!)


编辑:一些额外的问题

  • 您使用的是哪个版本的MATLAB?例如R2013a

  • 如果在MATLAB命令行中输入which ovrpredict,您是否看到了预期文件的路径? (即保存在计算机上的正确路径为ovrpredict.m)

  • 您的ovrpredict.m文件(由which ovrpredict指出)是否包含您在问题中粘贴的内容?你得到的错误表明他们可能是一个微小的差异,例如额外的空间。

答案 1 :(得分:1)

虽然我不确定如何解决这个问题,但我的意见如下:

ovrtrain中,创建了一个模型,其唯一的附加字段为labelSet

稍后在overpredict代码中,代码会尝试读出label

所以,我看到三个选项:

  1. 模型的创建错误
  2. 中间的一步被遗忘了
  3. 使用模型错误
  4.   

    编辑:这部分可能不是解决方案,正如评论中所提到的那样

         

    我没有足够的信息知道哪些适用,但是如果   您可以尝试替换Label的代码未提供示例   到处都是labelSet

    请注意,如果它是第1点或第3点,则此代码应始终提供错误,并且永远不会正常运行。