我目前正在混淆使用Matlab实现带有交叉验证的SVM。 stackoverflow上有很多帖子提到了有关SVM及其交叉验证的信息;然而,即使使用最简单的'fisheriris'数据集也没有完整的例子。
我总结了这些帖子的问题如下:
一个。二进制和多类SVM: 回答者 support vector machines in matlab 但没有交叉验证的例子。
湾使用SVM进行交叉验证: Example of 10-fold SVM classification in MATLAB 但没有多类SVM的例子。
℃。一对一和一对一的SVM: 可以在1找到1对1 support vector machines in matlab 可以找到1-against-all Multi-class classification in libsvm Multi-Class SVM( one versus all) 没有交叉验证的例子
d。 libSVM和Matlab内置SVM(统计工具箱) 可以在以下位置找到使用libSVM的部分完整示例 10 fold cross-validation in one-against-all SVM (using LibSVM)
即参数优化 Retraining after Cross Validation with libsvm
但是,对于一个学习并最终为他们的真正问题部署SVM的事情来说,事情真的很复杂,而且仅通过查看这些以前的帖子就会出现问题和错误。至少我是愚蠢的解决拼图问题。为什么我们不能一起为具有以下功能的SVM构建易于理解的代码?
一个。只需使用'fisheriris'数据。
B中。可以用于二元和多类问题(fisheriris可以选择二进制)。
℃。实施交叉验证。
d。实施一对一和一对一。
电子。两个版本分别使用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)
在我们完成所有任务之前,请随时添加你的。有人也可以为我们创建一个谷歌代码项目来完成此任务。
非常感谢。