原址:http://www.matlabsky.com/forum.php?mod=viewthread&tid=9468
Yaksa版主对MATLAB中的归一化问题进行了详细的讲解和分析,下面我们对这议题进一步深入。再议归一化问题
[train_scale,test_scale,ps] = scaleForSVM(train_data,test_data,ymin,ymax)
输入:
train_data:训练集
test_data:测试集
ymin:归一化范围下限(可不输入,默认为0)
ymax:归一化范围上限(可不输入,默认为1)
输出:
train_scale:归一化后的训练集
test_scale:归一化后的测试集
ps:归一化映射
测试代码:
train_data = [1 12;3 4;7 8]
test_data = [9 10;6 2]
[train_scale,test_scale,ps] = scaleForSVM(train_data,test_data,0,1)
运行结果:
- train_data =
- 1 12
- 3 4
- 7 8
- test_data =
- 9 10
- 6 2
- train_scale =
- 0 1.0000
- 0.2500 0.2000
- 0.7500 0.6000
- test_scale =
- 1.0000 0.8000
- 0.6250 0
- ps =
- name: 'mapminmax'
- xrows: 2
- xmax: [2x1 double]
- xmin: [2x1 double]
- xrange: [2x1 double]
- yrows: 2
- ymax: 1
- ymin: 0
- yrange: 1
复制代码
说明:归一化并不是必须采用的预处理方法。
但一旦采用了,这个步骤就十分重要,因为这是使用SVM的第一步骤,原始数据从这里将会被变化,若处理不当会使后面的分类或回归效果不佳。
原始数据到底该怎么进行归一化,我想到的是以下的几个问题:
(1)是对每一个样本进行进行归一化(按行归一化)还是对每一个维度进行归一化(按列归一化)?
(2)是将训练集和测试集分别归一化还是放在一起形成一个大矩阵一起进行归一化?
对于上面的我个人的理解和给出的解决办法是:
(1)对每一个维度进行归一化
理由:对于每个样本,由于它的每一个维度的量纲不同,若对每一个样本进行归一化且在量纲数量级差别悬殊时会使样本中较低数量级的属性变为0,会使原始信息过多丧失。比如:
- sample =
- 1 2 0.5 100000
- 5 7 0.4 200000
复制代码
若按行对每一个样本进行[0,1]归一化(按行归一化),则结果为:
- sample_scale =
- 0.0000 0.0000 0 1.0000
- 0.0000 0.0000 0 1.0000
复制代码
你会看到由于数量级的差别,对于每一样本的前三维的数据都被归一化为0,这样其实是不合理,会使原始数据的信息过多丢失。但若采用对每一维度进行归一化,就不会大范围发生这种情况,因为对于同一维度,量纲级别是相同的。对每一维度进行[0,1]归一化(按列归一化),结果为:
- sample_scale =
- 0 0 1 0
- 1 1 0 1
复制代码
(2)将训练集和测试集放在一起,一起进行归一化。
用测试代码中的例子
- train_data =
- 1 12
- 3 4
- 7 8
- test_data =
- 9 10
- 6 2
复制代码
若先将训练集进行归一化(按每一维度进行),然后把这个归一化映射记录下来,当有测试集时再用这个归一化映射对测试集进行归一化,对训练集进行归一化时对于第一维度归一化映射记录的最大值是7,这就接受一个假设是所有数据的第一维度的最大值不能超过7,但我们看到新的测试集拿来的时候它的第一维度的值不一定非得小于7,测试数据中的测试集的第一维度的最大值为9>7。即若分别归一化会产生这种不合理的现象。将训练集和测试集放在一起归一化就可以避免这种情况,统一归一化时每一维度的最大值和最小值是从训练集和测试集中寻找。
关于这个问题,我和论坛的一些朋友曾一起详细讨论过,有的朋友说这样做不合理,因为这样做的话测试集间接参与的SVM模型的建立,他们的意思是SVM的整体思路是用训练集建立SVM模型,然后用这个模型来预测测试集;或者说得更明白一点就是用训练集建立一个固定的SVM模型,然后每来一个测试集,就可以用这个固定SVM模型来进行预测。对此,我个人的给出的解释和理解是,我们处理的问题是面向数据的,当有新的测试集来的时候,若我们能建立一个更加适合这个测试集的SVM模型来预测,这样岂不是更好,即将原始训练集和新来的测试集放在一起统一归一化,这样得到的SVM模型更加适合当前的测试集,当又有新的测试集来的时候,我们再将这个新的测试集和原始的训练集放在重新归一化,再进行后续的SVM步骤,建立SVM模型。
以上归一化问题是见仁见智的,您可以保留自己的意见,以上是我个人的见解,事实证明将训练集和测试集放在一起归一化的效果绝对要比分别归一化的效果要好很多。您可以自行验证测试,用事实说话。