10

私は現在、MATLABバージョンのLIBSVMサポートベクターマシンを使用してデータを分類しています。LIBSVMのドキュメントには、SVMを適用する前のスケーリングが非常に重要であり、トレーニングデータとテストデータの両方をスケーリングするために同じ方法を使用する必要があると記載されています。

「同じスケーリング方法」は次のように説明されます。たとえば、トレーニングデータの最初の属性をからにスケーリングしたと[-10, +10][-1, +1]ます。テストデータの最初の属性が範囲内にある場合[-11, +8]、テストデータを次のようにスケーリングする必要があります[-1.1, +0.8]

の範囲でトレーニングデータをスケーリングするには[0,1]、次のMATLABコードを使用します。

(data - repmat(min(data,[],1),size(data,1),1))*spdiags(1./(max(data,[],1)-min(data,[],1))',0,size(data,2),size(data,2))

しかし、テストデータを正しくスケーリングする方法がわかりません。

ご助力ありがとうございます。

4

2 に答える 2

16

提供するコードは、基本的に最小値を減算してから範囲で除算することです。トレーニングデータ機能の最小範囲と範囲を保存する必要があります。

minimums = min(data, [], 1);
ranges = max(data, [], 1) - minimums;

data = (data - repmat(minimums, size(data, 1), 1)) ./ repmat(ranges, size(data, 1), 1);

test_data = (test_data - repmat(minimums, size(test_data, 1), 1)) ./ repmat(ranges, size(test_data, 1), 1);
于 2012-04-07T14:50:07.117 に答える
0

残念ながら、すべての観測値が同じ値を持つ列がある場合、Richanteのコードは正しくありません(データがスパースの場合に発生する可能性があります)。例:

>> data = [1 2 3; 5 2 8; 7 2 100]

data =

     1     2     3
     5     2     8
     7     2   100

>> test_data = [1 2 3; 4 5 6; 7 8 9];
>> minimums = min(data,[],1);
>> ranges = max(data, [], 1) - minimums;
>> data = (data - repmat(minimums, size(data, 1), 1)) ./ repmat(ranges, size(data, 1), 1);
>> data

data =

         0       NaN         0
    0.6667       NaN    0.0515
    1.0000       NaN    1.0000

したがって、単一の値のみを持つ列があるかどうかを確認する必要があります。しかし、トレーニングセット全体に単一の値しかなく、テストセットに複数の値がある場合はどうなるでしょうか。そして、テストセットに観測値が1つしかない、Leave-one-outシナリオで何をしますか。トレーニングセットの列のすべての値が0で、テストセットの対応する値が100?これらは実際には退化したケースですが、発生する可能性があります。ただし、Libsvmライブラリのファイルsvm_scale.cを確認すると、次の部分に気づきました。

 void output(int index, double value)
{
    /* skip single-valued attribute */
    if(feature_max[index] == feature_min[index])
        return;

    if(value == feature_min[index])
        value = lower;
    else if(value == feature_max[index])
        value = upper;
    else
        value = lower + (upper-lower) * 
            (value-feature_min[index])/
            (feature_max[index]-feature_min[index]);

    if(value != 0)
    {
        printf("%d:%g ",index, value);
        new_num_nonzeros++;
    }
}

では、これらのケースを無視する必要がありますか?よくわかりません。私が言ったように、私はこの問題の権威ではないので、できればLibsvmの作者自身からの別の回答を待って、問題を解決するつもりです。

于 2018-01-27T10:48:34.173 に答える