鱼C论坛

 找回密码
 立即注册
查看: 2009|回复: 2

[技术交流] Python实现kNN

[复制链接]
发表于 2020-11-3 21:40:46 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 糖逗 于 2020-11-4 12:54 编辑

参考书籍《机器学习实战》
本地测试环境:python3.7

  1. import numpy as np
  2. import operator

  3. class kNN():
  4.     def __init__(self, inX, dataSet, labels, k):
  5.         self.inX = inX
  6.         self.dataSet = dataSet
  7.         self.labels = labels
  8.         self.k = k
  9.         
  10.     def classify0(self):
  11.         dataSetSize = self.dataSet.shape[0]
  12.         #https://blog.csdn.net/laobai1015/article/details/85719724
  13.         diffMat = np.tile(self.inX, (dataSetSize, 1)) - dataSet
  14.         sqDiffMat = diffMat ** 2
  15.         sqDistances = sqDiffMat.sum(axis = 1)
  16.         distances = sqDistances ** 0.5
  17.         sortedDistIndicies = distances.argsort()
  18.         classCount = {}
  19.         for i in range(self.k):
  20.             voteIlabel = self.labels[sortedDistIndicies[i]]
  21.             #https://blog.csdn.net/weixin_45683963/article/details/103898093
  22.             classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
  23.         #https://www.runoob.com/python3/python3-func-sorted.html
  24.         sortedClassCount = sorted(classCount.items(),
  25.                                   ##https://www.cnblogs.com/zhoufankui/p/6274172.html
  26.                                   key = operator.itemgetter(1),
  27.                                   reverse = True)#reverse = True为降序
  28.         print(sortedClassCount[0][0])
  29.    
  30. if __name__ == '__main__':
  31.     group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]]) #特征
  32.     labels = ['A', 'A', 'B', 'B']#分类
  33.     kNN([0, 0], group, labels, 3).classify0()#[0,0]是待分了的特征
复制代码



  1. import numpy as np
  2. import operator

  3. class kNN():
  4.     def __init__(self, filename, k):
  5.         self.filename = filename
  6.         self.k = k
  7.    
  8.     #读取数据
  9.     def file2matrix(filename):
  10.         fr = open(filename)
  11.         arrayOLines = fr.readlines()
  12.         numberOfLines = len(arrayOLines)
  13.         returnMat = np.zeros((numberOfLines, 3))
  14.         classLabelVector = []
  15.         index = 0
  16.         for line in arrayOLines:
  17.             line = line.strip()
  18.             listFromLine = line.split('\t')
  19.             returnMat[index, :] = listFromLine[0:3]
  20.             classLabelVector.append(int(listFromLine[-1]))
  21.             index += 1
  22.         return returnMat, classLabelVector
  23.    
  24.     #归一化
  25.     def autoNorm(dataSet):
  26.         minVals = dataSet.min(0)
  27.         maxVals = dataSet.max(0)
  28.         ranges = maxVals - minVals
  29.         normDataSet = np.zeros(np.shape(dataSet))
  30.         m = dataSet.shape[0]
  31.         normDataSet = dataSet - np.tile(minVals, (m, 1))
  32.         normDataSet = normDataSet / np.tile(ranges, (m, 1))
  33.         return normDataSet, ranges, minVals
  34.    
  35.     #kNN
  36.     def classify0(self, inX, dataSet, labels):
  37.             dataSetSize = dataSet.shape[0]
  38.             diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
  39.             sqDiffMat = diffMat ** 2
  40.             sqDistances = sqDiffMat.sum(axis = 1)
  41.             distances = sqDistances ** 0.5
  42.             sortedDistIndicies = distances.argsort()
  43.             classCount = {}
  44.             for i in range(self.k):
  45.                 voteIlabel = labels[sortedDistIndicies[i]]
  46.                 classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
  47.             sortedClassCount = sorted(classCount.items(),
  48.                                       key = operator.itemgetter(1),
  49.                                       reverse = True)#reverse = True为降序
  50.             return sortedClassCount[0][0]
  51.    
  52.     #测试准确率
  53.     def datingClassTest(self, hoRatio):
  54.         #只取了数据量的10%作为样本
  55.         #hoRatio = 0.10
  56.         datingDataMat, datingLabels = kNN.file2matrix(self.filename)
  57.         normMat, ranges, minVals = kNN.autoNorm(datingDataMat)
  58.         m = normMat.shape[0]
  59.         numTestVecs = int(m * hoRatio)
  60.         errorCount = 0.0
  61.         for i in range(numTestVecs):
  62.             classifierResult = kNN.classify0(self, normMat[i, :], normMat[numTestVecs:m, :],
  63.                                          datingLabels[numTestVecs:m])
  64.             print("the classifier came back with: %d, the real answer is %d"
  65.                   %(classifierResult, datingLabels[i]))
  66.             if(classifierResult != datingLabels[i]):
  67.                 errorCount += 1
  68.         print("the total error rate is: %f" %(errorCount / float(numTestVecs)))
  69.         
  70.     #预测   
  71.     def classifyPerson(self):
  72.         resultList = ["not at all", "in small doses", "in large doses"]
  73.         percentTats = float(input("percentage of time spent playing video games?"))#用来获取控制台的输入
  74.         ffMiles = float(input("frequent filer miles earned per year?"))
  75.         iceCream = float(input("liters of ice cream consumed per year?"))
  76.         datingDataMat, datingLabels = kNN.file2matrix(self.filename)
  77.         normMat, ranges, minVals = kNN.autoNorm(datingDataMat)
  78.         inArr = np.array([ffMiles, percentTats, iceCream])
  79.         classifierResult = kNN.classify0(self, (inArr - minVals)/ranges, normMat, datingLabels)
  80.         print("You will probably like this person:", resultList[classifierResult - 1])#因为实际类别是1,2,3,下标识从0开始的,所以要-1

  81. if __name__ == '__main__':
  82.     path = 'datingTestSet2.txt'
  83.     test1 = kNN(path, 3)
  84.     test1.datingClassTest(0.1)
  85.     test1.classifyPerson()
复制代码

  1. import numpy as np
  2. import operator
  3. import os

  4. class kNN():
  5.     def __init__(self, path):
  6.         self.path = path
  7.         
  8.     #将矩阵打平,编程一维向量
  9.     def img2vector(filname):
  10.         returnVect = np.zeros((1, 1024))
  11.         fr = open(filname)
  12.         for i in range(32):
  13.             lineStr = fr.readline()
  14.             for j in range(32):
  15.                 returnVect[0, 32 * i + j] = int(lineStr[j])
  16.         return returnVect


  17.     def classify0(inX, dataSet, labels, k):
  18.             dataSetSize = dataSet.shape[0]
  19.             diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
  20.             sqDiffMat = diffMat ** 2
  21.             sqDistances = sqDiffMat.sum(axis = 1)
  22.             distances = sqDistances ** 0.5
  23.             sortedDistIndicies = distances.argsort()
  24.             classCount = {}
  25.             for i in range(k):
  26.                 voteIlabel = labels[sortedDistIndicies[i]]
  27.                 classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
  28.             sortedClassCount = sorted(classCount.items(),
  29.                                       key = operator.itemgetter(1),
  30.                                       reverse = True)#reverse = True为降序
  31.             return sortedClassCount[0][0]

  32.     #在全部的数据上训练,然后在全部的数据上进行检验
  33.     def handwritingClassTest(self):
  34.         hwLabels = []
  35.         #返回文件下的所有文件名
  36.         trainingFileList = os.listdir(self.path + "testDigits")
  37.         m = len(trainingFileList)
  38.         trainingMat = np.zeros((m, 1024))
  39.         for i in range(m):
  40.             fileNameStr = trainingFileList[i]
  41.             fileStr = fileNameStr.split('.')[0]
  42.             classNumStr = int(fileStr.split('_')[0])
  43.             hwLabels.append(classNumStr)
  44.             trainingMat[i, :] = kNN.img2vector(self.path + "testDigits/%s" % fileNameStr)
  45.         testFileList = os.listdir(self.path + "testDigits")
  46.         errorCount = 0
  47.         mTest = len(testFileList)
  48.         for i in range(mTest):
  49.             fileNameStr = testFileList[i]
  50.             fileStr = fileNameStr.split('.')[0]
  51.             classNumStr = int(fileStr.split('_')[0])
  52.             vectorUnderTest = kNN.img2vector(self.path + "testDigits\%s" % fileNameStr)
  53.             classifierResult = kNN.classify0(vectorUnderTest, trainingMat, hwLabels, 3)
  54.             print("the classifier came back with:%d, the real answer if :%d" %(classifierResult, classNumStr))
  55.             if(classifierResult != classNumStr) :
  56.                 errorCount += 1
  57.         print("\nthe total numner of errors is: %d" % errorCount)
  58.         print("\nthe total error rate is %f" %(errorCount / float(mTest)))

  59. if __name__ == '__main__':
  60.     path = "C:/.../machinelearninginaction/Ch02/digits/"
  61.     kNN(path).handwritingClassTest()
复制代码

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-11-4 10:55:46 | 显示全部楼层
每个框都是独立的个体,可以独立运行
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-4 12:55:50 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-20 06:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表