一、前言:
机器学习算法的数据预处理阶段,归一化是非常重要的一个步骤。例如在应用SVM之前,缩放是非常重要的。Sarle的神经网络FAQ的第二部分(1997)阐述了缩放的重要性,大多数注意事项也适用于SVM。缩放的最主要优点是能够避免大数值区间的属性过分支配了小数值区间的属性。另一个优点能避免计算过程中数值复杂度。因为关键值通常依赖特征向量的内积(inner products),例如,线性核和多项式核,属性的大数值可能会导致数值问题。我们推荐将每个属性线性缩放到区间[-1,+1]或者[0, 1]。
OpenCV中虽然有normalize这个函数,但是却没有Matlab中normc这样只对Matlab中各列向量的归一化函数。博客shaoxiaohu的专栏使用运算函数实现了对列向量的归一化,但是不够简洁。(链接如下,他使用了另一种归一化公式。)
http://blog.csdn.net/shaoxiaohu1/article/details/8287528
本文提出了结合Mat的成员方法colRange,对每一个特征(列向量)进行归一化。本方法简洁明了,不必自己造轮子。normalize函数的说明与归一化公式见链接:
http://blog.csdn.net/solomon1558/article/details/44689611
二、代码
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/contrib/contrib.hpp"
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
float Tval = 0.0;
float rawData[3][3] = {{16.0,2.0,3.0},{8.0,6.0,1.0},{5.0,12.0,9.0}};
Mat rawDataMat(3,3,CV_32FC1,rawData); //用三维数组初始化矩阵
double minv = 0.0, maxv = 0.0;
double* minp = &minv;
double* maxp = &maxv;
//寻找矩阵的最大值、最小值
minMaxIdx(rawDataMat,minp,maxp);
cout << "Mat minv = " << minv << endl;
cout << "Mat maxv = " << maxv << endl;
cout<<endl<<rawDataMat<<endl;
//整个矩阵归一化
//normalize(rawDataMat,rawDataMat,1.0,0.0,NORM_MINMAX);
//cout<<"整体归一化"<<endl<<rawDataMat<<endl;
//dataCol:对矩阵rawDataMat第一列的浅拷贝
Mat dataCol = rawDataMat.colRange(0,1);
//仅对第1列数据归一化
normalize(dataCol,dataCol,1.0,0.0,NORM_MINMAX);
cout<<"第一列归一化"<<endl<<rawDataMat<<endl;
for(int i =0;i < rawDataMat.rows;i++){
float* ptrData = (float*) rawDataMat.ptr<float>(i);
for(int j=0;j<rawDataMat.cols;j++){
if(ptrData[j] < 0){
ptrData[j]*= -1;
}
}
}
cout<<"第1列归一化、取绝对值"<<endl<<rawDataMat<<endl;
return 0;
}
三、测试结果
(1)对整个矩阵归一化
(2)仅对第一列归一化
四.注意事项
(1)在归一化的过程中,可能会出现非常接近0的负数,注意对其去绝对值。
(2)使用minMaxIdx函数对训练数据集的列向量求最大值、最小值,有助于在测试阶段利用下列公式归一化测试样本的列向量,从而解决“训练集与测试集数据的一致性的归一”。
dst(i,j)= (src(i,j) - min(src)) * (b' - a') / (max(src) - min(src)) + a'
其中b'= MAX(alpha,beta ) , a' = MIN(alpha,beta );