'''
Created on Nov 06, 2017
kNN: k Nearest Neighbors Input: inX: vector to compare to existing dataset (1xN)
dataSet: size m data set of known vectors (NxM)
labels: data set labels (1xM vector)
k: number of neighbors to use for comparison (should be an odd number) Output: the most popular class label @author: Liu Chuanfeng
'''
import operator
import numpy as np
import matplotlib.pyplot as plt
from os import listdir def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0]
diffMat = np.tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat ** 2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances ** 0.5
sortedDistIndicies = distances.argsort()
classCount = {}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)
return sortedClassCount[0][0] #数据预处理,将文件中数据转换为矩阵类型
def file2matrix(filename):
fr = open(filename)
arrayLines = fr.readlines()
numberOfLines = len(arrayLines)
returnMat = np.zeros((numberOfLines, 3))
classLabelVector = []
index = 0
for line in arrayLines:
line = line.strip()
listFromLine = line.split('\t')
returnMat[index,:] = listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat, classLabelVector #数据归一化处理:由于矩阵各列数据取值范围的巨大差异导致各列对计算结果的影响大小不一,需要归一化以保证相同的影响权重
def autoNorm(dataSet):
maxVals = dataSet.max(0)
minVals = dataSet.min(0)
ranges = maxVals - minVals
m = dataSet.shape[0]
normDataSet = (dataSet - np.tile(minVals, (m, 1))) / np.tile(ranges, (m, 1))
return normDataSet, ranges, minVals #约会网站测试代码
def datingClassTest():
hoRatio = 0.10
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m * hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
classifyResult = classify0(normMat[i,:], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
print('theclassifier came back with: %d, the real answer is: %d' % (classifyResult, datingLabels[i]))
if ( classifyResult != datingLabels[i]):
errorCount += 1.0
print ('the total error rate is: %.1f%%' % (errorCount/float(numTestVecs) * 100)) #约会网站预测函数
def classifyPerson():
resultList = ['not at all', 'in small doses', 'in large doses']
percentTats = float(input("percentage of time spent playing video games?"))
ffMiles = float(input("frequent flier miles earned per year?"))
iceCream = float(input("liters of ice cream consumed per year?"))
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
inArr = np.array([ffMiles, percentTats, iceCream])
classifyResult = classify0((inArr-minVals)/ranges, normMat, datingLabels, 3)
print ("You will probably like this persoon:", resultList[classifyResult - 1]) #手写识别系统#============================================================================================================
#数据预处理:输入图片为32*32的文本类型,将其形状转换为1*1024
def img2vector(filename):
returnVect = np.zeros((1, 1024))
fr = open(filename)
for i in range(32):
lineStr = fr.readline()
for j in range(32):
returnVect[0, 32*i+j] = int(lineStr[j])
return returnVect #手写数字识别系统测试代码
def handwritingClassTest():
hwLabels = []
trainingFileList = listdir('C:\\Private\\PycharmProjects\\Algorithm\\kNN\digits\\traingDigits')
m = len(trainingFileList)
trainingMat = np.zeros((m, 1024))
for i in range(m): #|
fileNameStr = trainingFileList[i] #|
fileName = fileNameStr.split('.')[0] #| 获取训练集路径下每一个文件,分割文件名,将第一个数字作为标签存储在hwLabels中
classNumber = int(fileName.split('_')[0]) #|
hwLabels.append(classNumber) #|
trainingMat[i,:] = img2vector('C:\\Private\\PycharmProjects\\Algorithm\\kNN\digits\\traingDigits\\%s' % fileNameStr) #变换矩阵形状: from 32*32 to 1*1024
testFileList = listdir('C:\\Private\\PycharmProjects\\Algorithm\\kNN\digits\\testDigits')
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest): #同训练集
fileNameStr = testFileList[i]
fileName = fileNameStr.split('.')[0]
classNumber = int(fileName.split('_')[0])
vectorUnderTest = img2vector('C:\\Private\\PycharmProjects\\Algorithm\\kNN\digits\\testDigits\\%s' % fileNameStr)
classifyResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3) #计算欧氏距离并分类,返回计算结果
print ('The classifier came back with: %d, the real answer is: %d' % (classifyResult, classNumber))
if (classifyResult != classNumber):
errorCount += 1.0
print ('The total number of errors is: %d' % (errorCount))
print ('The total error rate is: %.1f%%' % (errorCount/float(mTest) * 100)) # Simple unit test of func: file2matrix()
#datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
#print (datingDataMat)
#print (datingLabels) # Usage of figure construction of matplotlib
#fig=plt.figure()
#ax = fig.add_subplot(111)
#ax.scatter(datingDataMat[:,1], datingDataMat[:,2], 15.0*np.array(datingLabels), 15.0*np.array(datingLabels))
#plt.show() # Simple unit test of func: autoNorm()
#normMat, ranges, minVals = autoNorm(datingDataMat)
#print (normMat)
#print (ranges)
#print (minVals) # Simple unit test of func: img2vector
#testVect = img2vector('C:\\Private\\PycharmProjects\\Algorithm\\kNN\digits\\testDigits\\0_13.txt')
#print (testVect[0, 32:63] ) #约会网站测试
datingClassTest() #约会网站预测
classifyPerson() #手写数字识别系统预测
handwritingClassTest()
Output:
theclassifier came back with: 3, the real answer is: 3
the total error rate is: 0.0%
theclassifier came back with: 2, the real answer is: 2
the total error rate is: 0.0%
theclassifier came back with: 1, the real answer is: 1
the total error rate is: 0.0%
...
theclassifier came back with: 2, the real answer is: 2
the total error rate is: 4.0%
theclassifier came back with: 1, the real answer is: 1
the total error rate is: 4.0%
theclassifier came back with: 3, the real answer is: 1
the total error rate is: 5.0%
percentage of time spent playing video games?10
frequent flier miles earned per year?10000
liters of ice cream consumed per year?0.5
You will probably like this persoon: in small doses
...
The classifier came back with: 9, the real answer is: 9
The total number of errors is: 27
The total error rate is: 6.8%
Reference:
《机器学习实战》