kNN算法

拼搏现实的明天。 2021-09-11 05:52 465阅读 0赞
  1. from numpy import *
  2. import operator
  3. def createDataSet():
  4. group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
  5. labels=['A','A','B','B']
  6. return group,labels
  7. #k邻近算法 kNN算法 测试集、数据源(不含结果)、结果标签、邻近数量取值k
  8. def classify0(inX, dataSet, labels, k):
  9. #numpy函数shape[0]返回dataSet的行数
  10. dataSetSize = dataSet.shape[0]
  11. #在列向量方向上重复inX共1次(横向),行向量方向上重复inX共dataSetSize次(纵向)
  12. diffMat = tile(inX, (dataSetSize, 1)) - dataSet
  13. #二维特征相减后平方
  14. sqDiffMat = diffMat**2
  15. #sum()所有元素相加,sum(0)列相加,sum(1)行相加
  16. sqDistances = sqDiffMat.sum(axis=1)
  17. #开方,计算出距离
  18. distances = sqDistances**0.5
  19. #返回distances中元素从小到大排序后的索引值
  20. sortedDistIndices = distances.argsort()
  21. #定一个记录类别次数的字典
  22. classCount = {}
  23. for i in range(k):
  24. #取出前k个元素的类别
  25. voteIlabel = labels[sortedDistIndices[i]]
  26. #dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。
  27. #计算类别次数
  28. classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
  29. #python3中用items()替换python2中的iteritems()
  30. #key=operator.itemgetter(1)根据字典的值进行排序
  31. #key=operator.itemgetter(0)根据字典的键进行排序
  32. #reverse降序排序字典
  33. sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
  34. #返回次数最多的类别,即所要分类的类别
  35. return sortedClassCount[0][0]
  36. group,labels=createDataSet()
  37. print(classify0([0,0],group,labels,3))

海伦的约会数据。文本如下

  1. 40920 8.326976 0.953952 largeDoses
  2. 14488 7.153469 1.673904 smallDoses
  3. 26052 1.441871 0.805124 didntLike
  4. 75136 13.147394 0.428964 didntLike
  5. 38344 1.669788 0.134296 didntLike
  6. 72993 10.141740 1.032955 didntLike
  7. 35948 6.830792 1.213192 largeDoses
  8. 42666 13.276369 0.543880 largeDoses
  9. 67497 8.631577 0.749278 didntLike
  10. 35483 12.273169 1.508053 largeDoses
  11. 50242 3.723498 0.831917 didntLike
  12. 63275 8.385879 1.669485 didntLike
  13. 5569 4.875435 0.728658 smallDoses
  14. 51052 4.680098 0.625224 didntLike
  15. 77372 15.299570 0.331351 didntLike
  16. 43673 1.889461 0.191283 didntLike
  17. 61364 7.516754 1.269164 didntLike
  18. 69673 14.239195 0.261333 didntLike
  19. 15669 0.000000 1.250185 smallDoses

文本转换

  1. def file2matrix(filename):
  2. #打开文件
  3. fr = open(filename)
  4. #读取文件所有内容
  5. arrayOLines = fr.readlines()
  6. #得到文件行数
  7. numberOfLines = len(arrayOLines)
  8. #返回的NumPy矩阵,解析完成的数据:numberOfLines行,3列
  9. returnMat = zeros((numberOfLines,3))
  10. #返回的分类标签向量
  11. classLabelVector = []
  12. #行的索引值
  13. index = 0
  14. for line in arrayOLines:
  15. #s.strip(rm),当rm空时,默认删除空白符(包括'\n','\r','\t',' ')
  16. line = line.strip()
  17. #使用s.split(str="",num=string,cout(str))将字符串根据'\t'分隔符进行切片。
  18. listFromLine = line.split('\t')
  19. #将数据前三列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵
  20. #前面的Index代表第几行,因为这是一个二维的矩阵,后面:前后代表行开始和结束
  21. returnMat[index,:] = listFromLine[0:3]
  22. #根据文本中标记的喜欢的程度进行分类,1代表不喜欢,2代表魅力一般,3代表极具魅力
  23. if listFromLine[-1] == 'didntLike':
  24. classLabelVector.append(1)
  25. elif listFromLine[-1] == 'smallDoses':
  26. classLabelVector.append(2)
  27. elif listFromLine[-1] == 'largeDoses':
  28. classLabelVector.append(3)
  29. index += 1
  30. return returnMat, classLabelVector

数据归一化

5057999-74f88e51031cbf3c.png

  1. def autoNorm(dataSet):
  2. #获得数据的最小值
  3. minVals = dataSet.min(0)
  4. maxVals = dataSet.max(0)
  5. #最大值和最小值的范围
  6. ranges = maxVals - minVals
  7. #shape(dataSet)返回dataSet的矩阵行列数
  8. normDataSet = zeros(shape(dataSet))
  9. #返回dataSet的行数
  10. m = dataSet.shape[0]
  11. #原始值减去最小值
  12. normDataSet = dataSet - tile(minVals, (m, 1))
  13. #除以最大和最小值的差,得到归一化数据
  14. normDataSet = normDataSet / tile(ranges, (m, 1))
  15. #返回归一化数据结果,数据范围,最小值
  16. return normDataSet, ranges, minVals

分类器针对约会网站的测试代码

  1. def datingClassTest():
  2. #打开的文件名
  3. filename = "datingTestSet.txt"
  4. #将返回的特征矩阵和分类向量分别存储到datingDataMat和datingLabels中
  5. datingDataMat, datingLabels = file2matrix(filename)
  6. #取所有数据的百分之十
  7. hoRatio = 0.10
  8. #数据归一化,返回归一化后的矩阵,数据范围,数据最小值
  9. normMat, ranges, minVals = autoNorm(datingDataMat)
  10. #获得normMat的行数
  11. m = normMat.shape[0]
  12. #百分之十的测试数据的个数
  13. numTestVecs = int(m * hoRatio)
  14. #分类错误计数
  15. errorCount = 0.0
  16. for i in range(numTestVecs):
  17. #前numTestVecs个数据作为测试集,后m-numTestVecs个数据作为训练集
  18. classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m,:],
  19. datingLabels[numTestVecs:m], 4)
  20. print("分类结果:%d\t真实类别:%d" % (classifierResult, datingLabels[i]))
  21. if classifierResult != datingLabels[i]:
  22. errorCount += 1.0
  23. print("错误率:%f%%" %(errorCount/float(numTestVecs)*100))
  24. def classifyPerson():
  25. #输出结果
  26. resultList = ['讨厌','有些喜欢','非常喜欢']
  27. #三维特征用户输入
  28. precentTats = float(input("玩视频游戏所耗时间百分比:"))
  29. ffMiles = float(input("每年获得的飞行常客里程数:"))
  30. iceCream = float(input("每周消费的冰激淋公升数:"))
  31. #打开的文件名
  32. filename = "datingTestSet.txt"
  33. #打开并处理数据
  34. datingDataMat, datingLabels = file2matrix(filename)
  35. #训练集归一化
  36. normMat, ranges, minVals = autoNorm(datingDataMat)
  37. #生成NumPy数组,测试集
  38. inArr = array([ffMiles, precentTats, iceCream])
  39. #测试集归一化
  40. norminArr = (inArr - minVals) / ranges
  41. #返回分类结果
  42. classifierResult = classify0(norminArr, normMat, datingLabels, 3)
  43. #打印结果
  44. print("你可能%s这个人" % (resultList[classifierResult-1]))

手写识别系统

  1. def img2vector(filename):
  2. # 创建1x1024零向量
  3. returnVect = np.zeros((1, 1024))
  4. # 打开文件
  5. fr = open(filename)
  6. # 按行读取
  7. for i in range(32):
  8. # 读一行数据
  9. lineStr = fr.readline()
  10. # 每一行的前32个元素依次添加到returnVect中
  11. for j in range(32):
  12. returnVect[0, 32 * i + j] = int(lineStr[j])
  13. # 返回转换后的1x1024向量
  14. return returnVect
  15. def handwritingClassTest():
  16. # 测试集的Labels
  17. hwLabels = []
  18. # 返回trainingDigits目录下的文件名
  19. # trainingFileList = listdir('trainingDigits')
  20. trainingFileList = listdir('trainingDigits')
  21. # 返回文件夹下文件的个数
  22. m = len(trainingFileList)
  23. # 初始化训练的Mat矩阵,测试集
  24. trainingMat = np.zeros((m, 1024))
  25. # 从文件名中解析出训练集的类别
  26. for i in range(m):
  27. # 获得文件的名字
  28. fileNameStr = trainingFileList[i]
  29. # 获得分类的数字
  30. classNumber = int(fileNameStr.split('_')[0])
  31. # 将获得的类别添加到hwLabels中
  32. hwLabels.append(classNumber)
  33. # 将每一个文件的1x1024数据存储到trainingMat矩阵中
  34. trainingMat[i, :] = img2vector('trainingDigits/%s' % (fileNameStr))
  35. # 构建kNN分类器
  36. neigh = kNN(n_neighbors=20, algorithm='auto')
  37. # 拟合模型, trainingMat为训练矩阵,hwLabels为对应的标签
  38. neigh.fit(trainingMat, hwLabels)
  39. # 返回testDigits目录下的文件列表
  40. testFileList = listdir('testDigits')
  41. # 错误检测计数
  42. errorCount = 0.0
  43. # 测试数据的数量
  44. mTest = len(testFileList)
  45. # 从文件中解析出测试集的类别并进行分类测试
  46. for i in range(mTest):
  47. # 获得文件的名字
  48. fileNameStr = testFileList[i]
  49. # 获得分类的数字
  50. classNumber = int(fileNameStr.split('_')[0])
  51. # 获得测试集的1x1024向量,用于训练
  52. vectorUnderTest = img2vector('testDigits/%s' % (fileNameStr))
  53. # 获得预测结果
  54. # classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
  55. classifierResult = neigh.predict(vectorUnderTest)
  56. print("分类返回结果为%d\t真实结果为%d" % (classifierResult, classNumber))
  57. if (classifierResult != classNumber):
  58. errorCount += 1.0
  59. print("总共错了%d个数据\n错误率为%f%%" % (errorCount, errorCount / mTest * 100))

发表评论

表情:
评论列表 (有 0 条评论,465人围观)

还没有评论,来说两句吧...

相关阅读

    相关 KNN算法

    记得读研那会,接触过这个算法,算法原理还是比较容易理解,类似机器学习中的预测,在给定的一堆数据,预测当前节点的分类。计算距离,然后排序,计算最相似的分类。 impor

    相关 knn算法概述

    数据挖掘算法原理与实践:k-近邻 knn算法概述 201228 > educoder 答案 任务描述 本关任务:使用python实现方法,找出目标样本最近的k个样

    相关 KNN分类算法

    KNN分类算法 最简单最初级的分类器,就是将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类 K近邻(k-nea

    相关 kNN算法总结

    一直接触KNN近邻算法,但是一直没有机会系统的总结一下,现在做一下总结,希望加深一下自己对近邻算法的理解。 定义:K-近邻算法采用测量不同特征值之间的距离方法进行分类 优缺

    相关 KNN算法思考

    学习机器学习时,我们可能接触到KNN算法,这是一中间的算法,是利用距离来表征两者之间的相似度。这一算法最经典的应用就是给相似人群做推荐系统。这里对算法内容不做详细解释,只是引发

    相关 KNN算法

    KNN算法即K-近邻算法,KNN的核心思想是通过你的“邻居”来推断出你的类别。 1 K-近邻算法(KNN)原理     k 值取得过小,容易受到异常点的影响   

    相关 KNN算法

    1、kNN算法又称为k近邻分类(k-nearest neighbor classification)算法。 最简单平凡的分类器也许是那种死记硬背式的分类器,记住所有的训练数