一、简介
https://blog.csdn.net/sinat_30353259/article/details/80901746#2-1-knn基本流程
KNN算法步骤:
1)对于未知类别的数据(对象,点),计算已知类别数据集中的点到该点的距离。
2)按照距离由小到大排序
3)选取与当前点距离最小的K个点
4)确定前K个点所在类别出现的概率
5)返回当前K个点出现频率最高的类别作为当前点预测分类
KNN算法复杂度:
KNN 分类的计算复杂度和训练集中的文档数目成正比,也就是说,如果训练集中文档总数为 n,那么 KNN 的分类时间复杂度为O(n)
很多东西你以为你懂了,然而并没有,考试时候手画需要KNN才能解决的数据的特征,并没有画好。
二、知识点补充
operator:高效率函数
对象的比较运算,逻辑运算,数学运算以及序列运算。
#模块提供了一套与Python的内置运算符对应的高效率函数 . 许多函数名与特殊方法名相同,只是没有双下划线。为了向后兼容性,也保留了许多包含双下划线的函数。函数包含的种类有:对象的比较运算、逻辑运算、数学运算以及序列运算。模块提供了很多和Python 一样的操作符, 这里 只是封装一个函数 进行调用
tile这个函数,我们知道inX是个向量,而dataset是个矩阵,两者之间要进行相减的运算,需要把这个向量也补成一个和dataset有相同行数列数的矩阵,怎么个补法呢。这就要看tile()的第二个参数了,也就是上面的(datasetsize,1),这个参数的意思就是把inX补成有datasetsize行数的矩阵。
假如inX是(1,2) datasetsize =3 那么经过tile()转换后产生了一个这样的矩阵([1,2],[1,2],[1,2])
#Python 字典(Dictionary) get() 函数返回指定键的值,如果值不在字典中返回默认值。
#python中items()和iteritems()函数的用法
https://www.cnblogs.com/life-need-high-power-laser-gun/p/7518803.html
三、代码
import numpy as np
import operator
#从结果倒推前面可能需要我写什么
#转换函数,输出训练样本矩阵和类标向量
def file2matrix(filename):
fr=open(filename)
arrayOflines=fr.readlines()
numOflines=len(arrayOflines)#这是默认是行了
returnMat=np.zeros((numOflines,3))#这个是生成矩阵
#数据的读取和存储
classLabelVector=[]
index=0
for line in arrayOflines:
line=line.strip()
listFromline=line.split('\t')
returnMat[index,:]=listFromline[0:3]
classLabelVector.append(int(listFromLine[-1]))#注意数据存储类型咯
index+=1
return returnMat,classLabelVector
#normalization数据
def autoNorm(dataSet):
minVals=dataSet.min(0)
maxVals=dataSet.max(0)
ranges=maxVals-minVals
m=dataSet.shape[0]
normDataSet=dataSet-np.tile(minVals,(m,1))
normDataSet=normDataSet/np.tile(ranges,(m,1))
return normDataSet,ranges,minVals
def classify(normData,dataSet,labels,k):
dataSetSize=dataSet.shape[0]
diffMat=np.tile(normData,(dataSetSize,1))-dataSet
sqDiffMat=diffMat**2
sqDistances=sqDiffMat.sum(axis=1)
distance=sqDistances**0.5
#argsort是返回下标
sortedDistIndices=distance.argsort()
#以上其实不就是求欧式距离,下面求最近的4个的距离
#下面就是循环,得到相应的类,累积加,然后逆序,最后取出最高的
classCount={}
for i in range(k):
voteLabel=labels[sortedDistIndices[i]]
#检测并生成新的元素,括号中的0是初始化,之后就没有作用,加1是因为label 是123这样的格式,没有零
classCount[voteLabel]=classCount.get(voteLabel,0)+1
sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
#从第二个开始排序,且从高到低排序
return sortedClassCount[0][0]
#最后关头啦,求错误率
def datingClassTest():
hoRatio=0.1
datingDataMat,datingLabels=file2Matrix('xxxx.txt')
normMat,ranges,minVals=autoNorm(datingDataMat)
m=normMat.shape[0]
numTextVecs=int(m*hoRatio)
errorCount=0.0
for i in range(numTextVecs):
#def classify(normData,dataSet,labels,k) 参数带入
classifierResult=classify(normMat[i,:],normMat[numTextVecs:m,:],datingLabels[numTextVecs:m,:],4)
#这里是取出多少作为训练集
print('模型预测值:%d,真实值:%d'%(classifierResult,datingLabels[i]))
if(classifierResult!=datingLabels[i]):
errorCount+=1.0
errorRate=errorCount/float(numTextVecs)
print('正确率:%f'%(1-errorRate))
return 1-errorRate
#完结,还是需要看笔记才能写完,需要多加努力呀亲爱的