2012-04-07 17 views
10

我目前使用MATLAB版本的LIBSVM支持向量機來分類我的數據。 LIBSVM文檔提到在應用SVM之前進行縮放非常重要,我們必須使用相同的方法來調整訓練和測試數據。縮放LIBSVM的測試數據:MATLAB實現

「縮放的相同方法」解釋爲: 例如,假設我們將訓練數據的第一個屬性從[-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)) 

但我不知道如何正確擴展測試數據。

非常感謝您的幫助。

+0

我的問題是,如果訓練數據範圍[a,b]歸一化到範圍[0,1],測試數據範圍[c,d]歸一化到哪個範圍? – Lily 2012-04-07 17:39:31

回答

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 2012-04-08 12:26:26

+0

@Richante:你的回答非常有用。我只想澄清一下,「數據」這裏是訓練數據,「test_data」是測試數據? – Sid 2014-03-04 05:23:22

+0

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

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 

所以你必須檢查是否有列只有一個單一的值。但是如果整個訓練集中只有一個單值,但測試集中有多個值呢?我們在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的作者自己,以清除事情.....