[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模型。
以上归一化问题是见仁见智的,您可以保留自己的意见,以上是我个人的见解,事实证明将训练集和测试集放在一起归一化的效果绝对要比分别归一化的效果要好很多。您可以自行验证测试,用事实说话。
博客来源于:http://www.ilovematlab.cn/thread-63766-1-1.html
评论
1.关于归一化,我觉得应该是按列来进行归一化,因为这是一个特征的所有数据,而按照行来进行归一化,实质上是不符合我们原本的设计想法的;另外就是应该把测试集和训练集集中在一起一起进行归一化。
举个例子来说,你提取的特征有面积,直径,和周长,测试集50,训练集50个。当你归一化的时候,应该是面积这一个特征进行归一化,直径和周长分别进行归一化。面积,直径和周长是不同的三种数据,拿单位来说也同样可以理解,面积的单位是平方厘米,直径是厘米,能把平方厘米和厘米一起进行归一化么?自然不能。
对于测试集和训练集,应该是一起要进行归一化的,对面积来说,如果分别归一化,其实测试集和训练集最大最小值是不同的,那放在一起作比较就没有价值了。
最后关于新的测试集,我觉得同样道理,应该是重新进行归一化。
2.对第一个问题,我赞同,但对是否把训练集和测试集一起我不完全赞同。
把训练集和测试集一起归一化的确如上所说,会提高分类效果。但是前提是,我们在做实验室的时候,训练集和测试集都是我们自己选定的。或者说是已经有了所有特征,只不过分成训练集和测试集而已。因此,把它们一起归一化没问题。但实际的问题中这样往往是不可能的。
第一,就以我做的方向来说,目的是提取图像的特征,然后把它们分为两类或者多类(提取什么特征等细节略)。首先是找很多的图像库(原始图像必须是未压缩,未经过任何处理的),然后提取特征,进行训练,得到模型。在检测阶段(首先并不知道会对图像又什么样的操作),对待检测的图像,提取同样的特征,然后进行分类。试问,这个时候如何再把它们一起归一化?(由于图像源的非稳态特性,同一个图像源的图像都有较大差别,往往训练集会非常庞大,以尽可能考虑更多的可能性)
第二,在利用分类器开发产品的时候,往往都是先把模型训练好,然后来一个待检测的内容,直接输入模型进行检测。不可能再重新训练模型,而且实时性也是很大的问题。例如,我有个同学做异常声音的识别问题,主要目的是要能区分正常的声音和异常声音,例如枪声等,而且是开发产品,前期就必须训练大量的实例,有时候后一次训练就要几天。训练好模型后再对未知声音进行分类。此时又如何能实现同时归一化?
个人认为,为了折中,还是分开归一化。
3.我以下的理解是针对BP网络而言的。
我目前是做BP网络非线性拟合,因为数据量庞大,样本等问题,一直收敛不到我的要求,我之前也考虑按维数归一化,因为我的样本第一个数据是300左右,最后的数据是0.1左右,这样的话由于一个样本的数据之间差异太大所以如果一起归一,再反归一的话肯定会造成误差增大。
第二个问题就是输出输出一起归一的问题,不看数据,如果一起归一的话,可能因为是做的同等变换,有可能是要效果好一点,但是也有个问题就是你的输入和输出的要是有数量级上的差别的话,一起归一我觉得就不好。
另外2楼说到量纲的问题,之前我和导师说想数据归一化,她说数据是有物理意义存在的,要是归一化了这个物理意义就没有了。但是,我觉得,这个BP网络吧,说白点就是扔进去一组数据,它给你输出一组数据,它不管你这个数据的量纲啊,物理意义啊,反正输入A,输出就是B。所以我觉得在对数据进行某些处理的时候,就不用考虑其他问题的。
4.我觉得肯定是按维归一化,因为不同维之间的量纲、数量级是不同的。而本维则是一种在统计学上的,当数量达到一定程度随机变化后的正态分布,具有可比性、延续性。不同维之间归一化我觉得差距会很大。另外对于测试集是否归一化,就用涉及的SVM模型,有的是这样的,有的则不是。但是似乎都可以有较好的结果。核函数都是一样的,估计与算法有关。