归一化的公式:
newValue = (oldValue - min) / (max - min)
就是把数据归一化到[0, 1]区间上。
好处:
防止某一维度的数据的数值大小对距离就算产生影响。多个维度的特征是等权重的,所以不能被数值大小影响。
下面是归一化特征值的代码:
#归一化特征值
def autoNorm(dataSet):
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
ranges = maxVals - minVals
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - tile(minVals, (m, 1))
normDataSet = normDataSet / tile(ranges, (m, 1))
return normDataSet, ranges, minVals
然后在Python shell中:
>>> reload(kNN)
>>> normMat, ranges, minVals = kNN.autoNorm(datingDataMat)
>>> normMat
array([[ 0.44832535, 0.39805139, 0.56233353],
[ 0.15873259, 0.34195467, 0.98724416],
[ 0.28542943, 0.06892523, 0.47449629],
...,
[ 0.29115949, 0.50910294, 0.51079493],
[ 0.52711097, 0.43665451, 0.4290048 ],
[ 0.47940793, 0.3768091 , 0.78571804]])
>>> ranges
array([ 9.12730000e+04, 2.09193490e+01, 1.69436100e+00])
>>> minVals
array([ 0. , 0. , 0.001156])
其中datingDataMat是调用前面的函数得到的:
>>> import kNN
>>> reload(kNN)
>>> datingDataMat, datingLabels = kNN.file2matrix('datingTestSet2.txt', 3)
下面解释一下归一化的函数:
(1)tile函数是把第一个参数复制成一个m*1的矩阵中去。
(2)这里的 / 是每个元素相除,如果是矩阵的除法,需要用到linalg.solve(matA, matB)