机器学习算法与Python实践之(二)k近邻(KNN)

kNN进阶

       这里我们用kNN来分类一个大点的数据库,包括数据维度比较大和样本数比较多的数据库。这里我们用到一个手写数字的数据库,可以到这里下载。这个数据库包括数字0-9的手写体。每个数字大约有200个样本。每个样本保持在一个txt文件中。手写体图像本身的大小是32x32的二值图,转换到txt文件保存后,内容也是32x32个数字,0或者1,如下:

       数据库解压后有两个目录:目录trainingDigits存放的是大约2000个训练数据,testDigits存放大约900个测试数据。

        这里我们还是新建一个kNN.py脚本文件,文件里面包含四个函数,一个用来生成将每个样本的txt文件转换为对应的一个向量,一个用来加载整个数据库,一个实现kNN分类算法。最后就是实现这个加载,测试的函数。

  1. #########################################  
  2. # kNN: k Nearest Neighbors  
  3.   
  4. # Input:      inX: vector to compare to existing dataset (1xN)  
  5. #             dataSet: size m data set of known vectors (NxM)  
  6. #             labels: data set labels (1xM vector)  
  7. #             k: number of neighbors to use for comparison   
  8.               
  9. # Output:     the most popular class label  
  10. #########################################  
  11.   
  12. from numpy import *  
  13. import operator  
  14. import os  
  15.   
  16.   
  17. # classify using kNN  
  18. def kNNClassify(newInput, dataSet, labels, k):  
  19.     numSamples = dataSet.shape[0# shape[0] stands for the num of row  
  20.   
  21.     ## step 1: calculate Euclidean distance  
  22.     # tile(A, reps): Construct an array by repeating A reps times  
  23.     # the following copy numSamples rows for dataSet  
  24.     diff = tile(newInput, (numSamples, 1)) - dataSet # Subtract element-wise  
  25.     squaredDiff = diff ** 2 # squared for the subtract  
  26.     squaredDist = sum(squaredDiff, axis = 1# sum is performed by row  
  27.     distance = squaredDist ** 0.5  
  28.   
  29.     ## step 2: sort the distance  
  30.     # argsort() returns the indices that would sort an array in a ascending order  
  31.     sortedDistIndices = argsort(distance)  
  32.   
  33.     classCount = {} # define a dictionary (can be append element)  
  34.     for i in xrange(k):  
  35.         ## step 3: choose the min k distance  
  36.         voteLabel = labels[sortedDistIndices[i]]  
  37.   
  38.         ## step 4: count the times labels occur  
  39.         # when the key voteLabel is not in dictionary classCount, get()  
  40.         # will return 0  
  41.         classCount[voteLabel] = classCount.get(voteLabel, 0) + 1  
  42.   
  43.     ## step 5: the max voted class will return  
  44.     maxCount = 0  
  45.     for key, value in classCount.items():  
  46.         if value > maxCount:  
  47.             maxCount = value  
  48.             maxIndex = key  
  49.   
  50.     return maxIndex   
  51.   
  52. # convert image to vector  
  53. def  img2vector(filename):  
  54.     rows = 32  
  55.     cols = 32  
  56.     imgVector = zeros((1, rows * cols))   
  57.     fileIn = open(filename)  
  58.     for row in xrange(rows):  
  59.         lineStr = fileIn.readline()  
  60.         for col in xrange(cols):  
  61.             imgVector[0, row * 32 + col] = int(lineStr[col])  
  62.   
  63.     return imgVector  
  64.   
  65. # load dataSet  
  66. def loadDataSet():  
  67.     ## step 1: Getting training set  
  68.     print "---Getting training set..."  
  69.     dataSetDir = 'E:/Python/Machine Learning in Action/'  
  70.     trainingFileList = os.listdir(dataSetDir + 'trainingDigits'# load the training set  
  71.     numSamples = len(trainingFileList)  
  72.   
  73.     train_x = zeros((numSamples, 1024))  
  74.     train_y = []  
  75.     for i in xrange(numSamples):  
  76.         filename = trainingFileList[i]  
  77.   
  78.         # get train_x  
  79.         train_x[i, :] = img2vector(dataSetDir + 'trainingDigits/%s' % filename)   
  80.   
  81.         # get label from file name such as "1_18.txt"  
  82.         label = int(filename.split('_')[0]) # return 1  
  83.         train_y.append(label)  
  84.   
  85.     ## step 2: Getting testing set  
  86.     print "---Getting testing set..."  
  87.     testingFileList = os.listdir(dataSetDir + 'testDigits'# load the testing set  
  88.     numSamples = len(testingFileList)  
  89.     test_x = zeros((numSamples, 1024))  
  90.     test_y = []  
  91.     for i in xrange(numSamples):  
  92.         filename = testingFileList[i]  
  93.   
  94.         # get train_x  
  95.         test_x[i, :] = img2vector(dataSetDir + 'testDigits/%s' % filename)   
  96.   
  97.         # get label from file name such as "1_18.txt"  
  98.         label = int(filename.split('_')[0]) # return 1  
  99.         test_y.append(label)  
  100.   
  101.     return train_x, train_y, test_x, test_y  
  102.   
  103. # test hand writing class  
  104. def testHandWritingClass():  
  105.     ## step 1: load data  
  106.     print "step 1: load data..."  
  107.     train_x, train_y, test_x, test_y = loadDataSet()  
  108.   
  109.     ## step 2: training...  
  110.     print "step 2: training..."  
  111.     pass  
  112.   
  113.     ## step 3: testing  
  114.     print "step 3: testing..."  
  115.     numTestSamples = test_x.shape[0]  
  116.     matchCount = 0  
  117.     for i in xrange(numTestSamples):  
  118.         predict = kNNClassify(test_x[i], train_x, train_y, 3)  
  119.         if predict == test_y[i]:  
  120.             matchCount += 1  
  121.     accuracy = float(matchCount) / numTestSamples  
  122.   
  123.     ## step 4: show the result  
  124.     print "step 4: show the result..."  
  125.     print 'The classify accuracy is: %.2f%%' % (accuracy * 100)  

       测试非常简单,只需要在命令行中输入:

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import kNN  
  2. kNN.testHandWritingClass()  

       输出结果如下:

[python]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. step 1: load data...  
  2. ---Getting training set...  
  3. ---Getting testing set...  
  4. step 2: training...  
  5. step 3: testing...  
  6. step 4: show the result...  
  7. The classify accuracy is98.84
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值