2012-04-07 10 views
10

現在、MATLABバージョンのLIBSVMサポートベクターマシンを使用してデータを分類しています。 LIBSVMのマニュアルには、SVMを適用する前のスケーリングは非常に重要であり、トレーニングとテストの両方のデータをスケーリングするために同じ方法を使用しなければならないことに言及しています。LIBSVMのテストデータのスケーリング:MATLABの実装

「同じスケーリングの方法」は、 と説明されています。たとえば、トレーニングデータの最初の属性を[-10, +10]から[-1, +1]にスケーリングしたとします。

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

:試験データの最初の属性は範囲[-11, +8]にある場合は、以下のMATLABコードを使用して行うことができ[0,1]の範囲でトレーニングデータをスケーリング[-1.1, +0.8]

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

ありがとうございました。

+0

私の質問はif範囲[0,1]に正規化された[a、b]の範囲のデータを訓練し、[c、d] – Lily

答えて

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); 
+0

ありがとうございました! :) – Lily

+0

@リチャンテ:あなたの答えは非常に便利です。私はちょうど明確にしたい、ここで "データ"はトレーニングデータであり、 "test_data"はテストデータですか? – Sid

+0

http://stackoverflow.com/questions/43408031/scaling-for-single-instance-in-matlab-for-libsvm?noredirect=1&lq=1 –

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つしかない場合、テストセットにはいくつかの値がありますか?そして、テストセット内に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の著者自身から、物事をクリアするのを待つつもりです.....