k-近邻算法采用测量不同特征值之间的距离方法(上面写的公式)进行分类。
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。
原理:1.存在一个训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。
2.输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相思数据(最近邻)的分类标签。
3.一般的,我们只选择样本数据集中前k个最相似的数据,通常k是不大于20的整数,最后选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
1 ‘‘‘ 2 1、计算已知类别数据集中的点与当前点之间的距离 3 2、按照距离递增次序排序 4 3、选取与当前点距离最小的k个点 5 4、确定前k个点所在类别的出现概率 6 5、返回前k个点出现频率最高的类别作为当前点的预测分类 7 ‘‘‘ 8 import numpy as np 9 import operator 10 11 #处理文本 12 def fileToMatrix(filename): 13 fr = open(filename) 14 arrayOLines = fr.readlines() 15 numberOfLines = len(arrayOLines) 16 returnMat = np.zeros((numberOfLines, 5)) 17 classLabelVector = [] 18 index = 0 19 for line in arrayOLines: 20 line = line.strip() 21 listFromLine = line.split(‘,‘) 22 returnMat[index,:] = listFromLine[0:5] 23 classLabelVector.append(listFromLine[-1]) 24 index += 1 25 return returnMat, classLabelVector 26 27 #功能:归一化数据,避免某些数据的特征值过大 28 def autoNorm(dataSet): 29 minVals = dataSet.min(0)#取列值的最小值 30 maxVals = dataSet.max(0) 31 ranges = maxVals - minVals 32 normDataSet = np.zeros(np.shape(dataSet)) 33 m = dataSet.shape[0] 34 normDataSet = dataSet - np.tile(minVals, (m,1)) 35 normDataSet = normDataSet/np.tile(ranges, (m, 1))#特征值相除 36 return normDataSet, ranges, minVals 37 38 #功能:kNN核心算法 39 #intX - 输入向量,dataSet - 输入训练样本集,labels - 标签向量 40 def classify(inX, dataSet, labels, k): 41 #欧式距离的计算 42 dataSize = dataSet.shape[0]#数据的行数 43 diffMat = np.tile(inX, (dataSize,1)) - dataSet#将输入向量inX纵向重复dataSet的行数次 44 sqDiffMat = diffMat ** 2 45 sqDistances = sqDiffMat.sum(axis = 1)# 每行数据相加 46 distances = sqDistances ** 0.5#得到训练样本集每一点与当前点的距离 47 sortedDistIndicies = distances.argsort() 48 #选择距离最小的k个点 49 classCount = {} 50 for i in range(k): 51 voteIlabel = labels[sortedDistIndicies[i]]#最近K个的距离对应的类别 52 classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#类别分别出现的概率 53 sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)#选择发生频率最高的元素标签 54 return sortedClassCount[0][0] 55 56 #功能:#功能:十折交叉验证 57 #思路:将数据集分成十份,轮流将其中9份做训练1份做测试,10次结果的均值作为对算法精度的估计 58 #一般还要进行多次10倍交叉验证 59 def dataClassTest(filename,k): 60 testRate = 0.1 61 datingDataMat, datingLabels = fileToMatrix(filename) 62 datingDataMat = datingDataMat[:,:k-1] 63 normMat, ranges, minVals = autoNorm(datingDataMat) 64 m = normMat.shape[0] 65 numTestVecs = int(m * testRate) 66 all = 0 67 for k in range(1,11): 68 t = normMat[0:numTestVecs] 69 p = datingLabels[0:numTestVecs] 70 for i in range(numTestVecs): 71 errorCount = 0 72 classifierResult = classify(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3) 73 if(classifierResult != datingLabels[i]): errorCount += 1.0 74 #----------将第几折的数据拿出来,放回到normMat的前面 75 b = normMat[numTestVecs*(k-1):numTestVecs*k] 76 normMat[0:numTestVecs] = b 77 normMat[numTestVecs*(k-1):numTestVecs*k] = t 78 errorRate = errorCount/float(numTestVecs) 79 #----------将第几折类别拿出来,放回到datingLabels的前面 80 c = datingLabels[numTestVecs*(k-1):numTestVecs*k] 81 datingLabels[0:numTestVecs] = c 82 datingLabels[numTestVecs*(k-1):numTestVecs*k] = p 83 errorRate = errorCount/float(numTestVecs) 84 all = all + errorRate 85 #------------------------------------------------------------------ 86 print("第%d折分类的错误率为%f" % (k,(errorCount/float(numTestVecs)))) 87 #获得平均错误率 88 print("平均错误率为%f" % (all/10))
欢迎加邮箱一起讨论机器学习[email protected]
原文地址:https://www.cnblogs.com/bigstrawberrywakaka/p/9038390.html
时间: 2024-10-29 01:03:03