24

我目前对使用 Matlab 实现带有交叉验证的 SVM 感到困惑。stackoverflow 上有很多帖子提到了有关 SVM 及其交叉验证的信息;然而,即使使用最简单的“fisheriris”数据集,也没有完整的例子。

我将这些帖子的问题总结如下:

一个。二元和多类 SVM:由 matlab 中的支持向量机回答, 但没有交叉验证的示例。

湾。使用 SVM 进行交叉验证: MATLAB 中 10 倍 SVM 分类的 示例,但没有多类 SVM 的示例。

C。One-against-one 和 one-against-all SVM:1-against-1 可以 在 matlab 的支持向量机中找到 1-against-all 可以在 Multi-class classification in libsvm Multi-Class SVM(one vs all ) 没有交叉验证的例子

d。libSVM 和 Matlab 内置 SVM(统计工具箱) 使用 libSVM 的部分完整示例可以 在一对一 SVM 中的 10 倍交叉验证中找到(使用 LibSVM)

e. 使用 libsvm 进行交叉验证后的参数优化 再训练

但是对于一个人来说,学习并最终为他们的实际问题部署 SVM 确实很复杂,而且仅查看这些以前的帖子就存在问题且容易出错。至少我很愚蠢地解决了拼图问题。

为什么我们不一起为具有以下功能的 SVM 构建易于理解的代码?

A. 只需使用“fisheriris”数据。

B. 可用于二元和多类问题(fisheriris 可以选择为二元)。

C. 实施交叉验证。

D. 实施一对一和一对一。

E. 分别使用 libSVM 和 Matlab 内置 SVM 的两个版本。由于两个包的 svmtrain 名称相同,我建议我们在使用前将其更改为 libsvmtrain 和 MEX。然后我们也可以比较这两种方法。

F. 目前,由于训练/测试数据分离,结果并不总是可重复的。我们能解决这个问题吗?

F.(可选)添加参数优化。

G.(可选)添加 ROC 分析。

我的开始是一些代码,例如:

#
% libSVM version_1
clc; clear all;

load fisheriris
[~,~,labels]            = unique(species);              % Labels: 1/2/3
data                    = zscore(meas);                 % Scale features
numInst                 = size(data,1);
numLabels               = max(labels);

%# Split training/testing
idx                     = randperm(numInst);
numTrain                = 100; 
numTest                 = numInst - numTrain;

trainData               = data(idx(1:numTrain),:);  
testData                = data(idx(numTrain+1:end),:);

trainLabel              = labels(idx(1:numTrain)); 
testLabel               = labels(idx(numTrain+1:end));

%# Train one-against-all models
model                   = cell(numLabels,1);
for k=1:numLabels
    model{k}                = libsvmtrain(double(trainLabel==k), trainData, '-c 1 -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
#
% Matlab build-in SVM version_1
clc; clear all;

load fisheriris
[g, gn]                 = grp2idx(species);     % Nominal class to numeric

% Split training and testing sets
[trainIdx, testIdx]     = crossvalind('HoldOut', species, 1/3);

pairwise                = nchoosek(1:length(gn),2);            % 1-vs-1 pairwise models
svmModel                = cell(size(pairwise,1),1);            % Store binary-classifers
predTest                = zeros(sum(testIdx),numel(svmModel)); % Store binary predictions

%# classify using one-against-one approach, SVM with 3rd degree poly kernel
for k=1:numel(svmModel)
    %# get only training instances belonging to this pair
    idx                     = trainIdx & any( bsxfun(@eq, g, pairwise(k,:)) , 2 );

    %# train
    svmModel{k}             = svmtrain(meas(idx,:), g(idx), ...
        'BoxConstraint',2e-1, 'Kernel_Function','polynomial', 'Polyorder',3);

    %# test
    predTest(:,k)           = svmclassify(svmModel{k}, meas(testIdx,:));
end
pred = mode(predTest,2);   % Voting: clasify as the class receiving most votes

%# performance
cmat                        = confusionmat(g(testIdx),pred);
acc                         = 100*sum(diag(cmat))./sum(cmat(:));
fprintf('SVM (1-against-1):\naccuracy = %.2f%%\n', acc);
fprintf('Confusion Matrix:\n'), disp(cmat)

在我们完成所有任务之前,请随时添加您的。有人也可以为我们创建一个谷歌代码项目来完成这个。

非常感谢。

4

0 回答 0