web-dev-qa-db-ja.com

1対すべてのSVMでの10倍の相互検証(LibSVMを使用)

MATLABのone-against-allサポートベクターマシン 分類で10分割交差検定を実行したいと思います。

私はどういうわけかこれらの2つの関連する答えを混ぜようとしました:

しかし、MATLABとその構文に慣れていないので、今までそれを機能させることができませんでした。

一方、 LibSVM READMEファイルでの相互検証に関する次の数行だけが表示され、関連する例は見つかりませんでした。

オプション-vは、データをランダムにn個の部分に分割し、それらの交差検定精度/平均二乗誤差を計算します。

出力の意味については、libsvm FAQ)を参照してください。

誰かが私に10分割交差検定と1対すべての分類の例を教えてもらえますか?

10
Zahra Ezati

主に2つの理由があります 相互検証

  • モデルの一般化力のほぼ偏りのない推定値を与えるテスト方法として(過剰適合を回避することにより)
  • モデル選択 の方法として(例:トレーニングデータに対して最適なCおよびgammaパラメーターを見つけます。 この投稿 を参照してください。例)

関心のある最初のケースでは、プロセスには、各フォールドに対してkモデルをトレーニングし、次にトレーニングセット全体にわたって1つの最終モデルをトレーニングすることが含まれます。 k倍の平均精度を報告します。

マルチクラス問題を処理するためにone-vs-allアプローチを使用しているため、各モデルはNサポートベクターマシン(クラスごとに1つ)で構成されます。


以下は、one-vs-allアプローチを実装するラッパー関数です。

function mdl = libsvmtrain_ova(y, X, opts)
    if nargin < 3, opts = ''; end

    %# classes
    labels = unique(y);
    numLabels = numel(labels);

    %# train one-against-all models
    models = cell(numLabels,1);
    for k=1:numLabels
        models{k} = libsvmtrain(double(y==labels(k)), X, strcat(opts,' -b 1 -q'));
    end
    mdl = struct('models',{models}, 'labels',labels);
end

function [pred,acc,prob] = libsvmpredict_ova(y, X, mdl)
    %# classes
    labels = mdl.labels;
    numLabels = numel(labels);

    %# get probability estimates of test instances using each 1-vs-all model
    prob = zeros(size(X,1), numLabels);
    for k=1:numLabels
        [~,~,p] = libsvmpredict(double(y==labels(k)), X, mdl.models{k}, '-b 1 -q');
        prob(:,k) = p(:, mdl.models{k}.Label==1);
    end

    %# predict the class with the highest probability
    [~,pred] = max(prob, [], 2);
    %# compute classification accuracy
    acc = mean(pred == y);
end

そして、相互検証をサポートする関数は次のとおりです。

function acc = libsvmcrossval_ova(y, X, opts, nfold, indices)
    if nargin < 3, opts = ''; end
    if nargin < 4, nfold = 10; end
    if nargin < 5, indices = crossvalidation(y, nfold); end

    %# N-fold cross-validation testing
    acc = zeros(nfold,1);
    for i=1:nfold
        testIdx = (indices == i); trainIdx = ~testIdx;
        mdl = libsvmtrain_ova(y(trainIdx), X(trainIdx,:), opts);
        [~,acc(i)] = libsvmpredict_ova(y(testIdx), X(testIdx,:), mdl);
    end
    acc = mean(acc);    %# average accuracy
end

function indices = crossvalidation(y, nfold)
    %# stratified n-fold cros-validation
    %#indices = crossvalind('Kfold', y, nfold);  %# Bioinformatics toolbox
    cv = cvpartition(y, 'kfold',nfold);          %# Statistics toolbox
    indices = zeros(size(y));
    for i=1:nfold
        indices(cv.test(i)) = i;
    end
end

最後に、使用法を説明する簡単なデモを次に示します。

%# laod dataset
S = load('fisheriris');
data = zscore(S.meas);
labels = grp2idx(S.species);

%# cross-validate using one-vs-all approach
opts = '-s 0 -t 2 -c 1 -g 0.25';    %# libsvm training options
nfold = 10;
acc = libsvmcrossval_ova(labels, data, opts, nfold);
fprintf('Cross Validation Accuracy = %.4f%%\n', 100*mean(acc));

%# compute final model over the entire dataset
mdl = libsvmtrain_ova(labels, data, opts);

これを、libsvmがデフォルトで使用する1対1のアプローチと比較してください。

acc = libsvmtrain(labels, data, sprintf('%s -v %d -q',opts,nfold));
model = libsvmtrain(labels, data, strcat(opts,' -q'));
15
Amro

2つの質問のうちの1つがLIBSVMに関するものではないことはあなたを混乱させるかもしれません。 この回答 を調整し、他を無視する必要があります。

折り目を選択し、残りはリンクされた質問とまったく同じように行う必要があります。データがdataにロードされ、ラベルがlabelsにロードされたと仮定します。

n = size(data,1);
ns = floor(n/10);
for fold=1:10,
    if fold==1,
        testindices= ((fold-1)*ns+1):fold*ns;
        trainindices = fold*ns+1:n;
    else
        if fold==10,
            testindices= ((fold-1)*ns+1):n;
            trainindices = 1:(fold-1)*ns;
        else
            testindices= ((fold-1)*ns+1):fold*ns;
            trainindices = [1:(fold-1)*ns,fold*ns+1:n];
         end
    end
    % use testindices only for testing and train indices only for testing
    trainLabel = label(trainindices);
    trainData = data(trainindices,:);
    testLabel = label(testindices);
    testData = data(testindices,:)
    %# train one-against-all models
    model = cell(numLabels,1);
    for k=1:numLabels
        model{k} = svmtrain(double(trainLabel==k), trainData, '-c 1 -g 0.2 -b 1');
    end

    %# get probability estimates of test instances using each model
    prob = zeros(size(testData,1),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
end
2
carlosdc