k-近邻算法通过测量距离,对物品进行分类。选取与目标物品最近的k个物品,出现最多的类别,即为目标的类别。
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。 适用数据范围:数值型和标称型。
采用了numpy库对矩阵进行处理:
from numpy import * #处理矩阵
import operator
from os import listdir
def handwritingClassTest():
hwLables=[]
trainingFileList=listdir('digits/trainingDigits')#训练集的位置
m=len(trainingFileList)
trainingMat=zeros((m,1024)) #m行,1024列的初值为0的矩阵
for i in range(m):
fileNameStr=trainingFileList[i]
fileStr=fileNameStr.split('.')[0]
classNumStr=int(fileStr.split('_')[0])
hwLables.append(classNumStr)
trainingMat[i,:]=img2vector('digits/trainingDigits/{}'.format(fileNameStr))
testFileList=listdir('digits/testDigits')#测试集的位置
errorCount=0.0
mTest=len(testFileList)
for i in range(mTest):
fileNameStr=testFileList[i]
fileStr=fileNameStr.split('.')[0]
classNumStr=int(fileStr.split('_')[0])
vectorUnderTest=img2vector('digits/testDigits/{}'.format(fileNameStr))
classifierResult=classify0(vectorUnderTest,trainingMat,hwLables,3)
print('the classifier came back with: {}, the real answer is:{}'.format(classifierResult,classNumStr))
if (classifierResult != classNumStr):
errorCount+=1.0
print('the total number of error is :{}'.format(errorCount))
print('the total rate of error is :{}'.format(errorCount/float(mTest)))
def img2vector(filename): #把图片转化成向量
returnVect=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 classify0(inX,dataSet,labels,k): #这部分的数组运算还挺风骚的
dataSetsize=dataSet.shape[0]
DiffMat=tile(inX,(dataSetsize,1))-dataSet #tile用来建立一个对第一个参数重复的数组,但是我总是记不住tile这个函数
sqDiff=DiffMat**2
sqDistances=sqDiff.sum(axis=1)
distance=sqDistances**0.5
sortedDistIndicies=distance.argsort()
classCount={}
for i in range(k):
label=labels[sortedDistIndicies[i]]
classCount[label]=classCount.get(label,0)+1
sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]