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