缩放 LIBSVM 的测试数据:MATLAB 实现

Posted

技术标签:

【中文标题】缩放 LIBSVM 的测试数据:MATLAB 实现【英文标题】:scaling the testing data for LIBSVM: MATLAB implementation 【发布时间】:2012-04-20 18:35:27 【问题描述】:

我目前使用 MATLAB 版本的 LIBSVM 支持向量机来分类我的数据。 LIBSVM 文档提到,在应用 SVM 之前进行缩放非常重要,我们必须使用相同的方法来缩放训练和测试数据。

“相同的缩放方法”解释为: 例如,假设我们将训练数据的第一个属性从[-10, +10] 缩放到[-1, +1]。如果测试数据的第一个属性在[-11, +8]范围内,我们必须将测试数据缩放到[-1.1, +0.8]

可以使用以下 MATLAB 代码在 [0,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))

但我不知道如何正确缩放测试数据。

非常感谢您的帮助。

【问题讨论】:

我的问题是,如果 [a,b] 范围内的训练数据归一化到 [0,1] 范围内,那么 [c,d] 范围内的测试数据归一化到哪个范围? 【参考方案1】:

您给出的代码本质上是减去最小值,然后除以范围。 您需要存储训练数据特征的最小值和范围。

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

【讨论】:

@Richante:您的回答非常有用。我只是想澄清一下,这里的“数据”是训练数据,“test_data”是测试数据?? ***.com/questions/43408031/… 很抱歉,您的代码将为所有观察值都具有相同值的列输出 NaN(如果您的数据稀疏,则可能会发生这种情况)。例如,数据 = [1 2 3; 5 2 8; 7 2 100]【参考方案2】:

不幸的是,如果存在所有观察值都具有相同值的列(如果数据稀疏,则可能会发生这种情况),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 的作者自己,以澄清事情......

【讨论】:

以上是关于缩放 LIBSVM 的测试数据:MATLAB 实现的主要内容,如果未能解决你的问题,请参考以下文章

在 matlab 中测试 libsvm 时结果不佳

如何通过 LIBSVM 使用 platt 缩放和交叉验证?

Libsvm 分类 MATLAB

Matlab-libsvm - 从原始权重向量、线性核再现决策值

为啥在 matlab 中使用带有 libsvm 的预计算内核

使用 LIBSVM 进行测试