$newValue = http://www.netofthings.cn/JieJueFangAn/2017-01/(oldValue - min)/(max - min)$
其中,min和max分别为特征值中最大和最小值,虽然改变数值范围增加了分类器的复杂度,但是为了得到准确的结果,必须这样做,所以我们在kNN.py中新增一个函数autoNorm()
,用来将数字特征值转化为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
运行结果:
>>> import kNN>>> mat, vec = kNN.file2matrix('datingTestSet2.txt')>>> a, b, c = kNN.autoNorm(mat)>>> aarray([[ 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]])
这样一来,我们把值处理成了我们预期的范伟内的值。
- 测试算法
通常我们把数据集的90%的数据当做训练集,余下的10%作为测试集,着10%的数据是随机选择的。 下面,我们来书写测试程序,并通过datingTestSet.txt
来测试程序:
def datingClassTest() : hoRatio = 0.10 # 设置抽取多少数据进行测试集 datingDataMat, datingLabels = file2matrix('datingTestSet2.txt') # 读入数据集 normMat, ranges, minVals = autoNorm(datingDataMat) # 转化特征值至 0 - 1 区间内 m = normMat.shape[0] numTestVecs = int( m * hoRatio ) # 计算测试向量的数量 errorCount = 0.0 for i in range(numTestVecs) : classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs: m], 3) # 使用近邻算法得出结果 print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i])