热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python实现KNN分类器——手写识别

1.1优劣优点:进度高,对异常值不敏感,无数据输入假定缺点:计算复杂度高,空间复杂度高应用:主要用于文本分类,相似推荐适用数据范围:数值型和标称型1.2算法伪代码(1)计算已知类别

1.1 优劣

优点:进度高,对异常值不敏感,无数据输入假定

缺点:计算复杂度高,空间复杂度高

应用:主要用于文本分类,相似推荐

适用数据范围:数值型和标称型

1.2 算法伪代码

(1)计算已知类别数据集中的点与当前点的距离

(2)按照距离递增次序排序,选取与当前点距离最小的 k 个点

(3)确定前 k 个点所在类别的出现频率

(4)返回前 k 个点出现频率最高的类别作为当前点的预测分类

2 手写识别

2.1 概念

     指在手写设备上书写时产生的轨迹信息转化为具体字码,本篇博客重点非搭建手写识别系统,而是帮助理解 KNN。

2.2 编程实现步骤

(1)将图片(txt 文本)转为一个向量,即32*32的数组转化为1*1024的数组(特征向量)

(2)将特征向量转化为矩阵

(3)计算每个测试集中的特征向量和训练集中的特征向量的距离,选取距离较小的前 k 个,该特征向量对应的图片数字为 k 个图片中出现次数最多的那个数字。

2.3 具体代码

(1)转化为1*1024特征向量

def img2vector(filename):
    returnVect = zeros((1,1024))
    fr = open(filename)
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            returnVect[0,32*i+j] = int(lineStr[j])
    return returnVect

(2)计算欧式距离,返回测试图片的类别

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]                  
    diffMat = tile(inX, (dataSetSize,1)) - dataSet   # shape[0]得出dataSet的行数,即样本个数   
    sqDiffMat = diffMat**2                           # tile(A,(m,n))将数组A作为元素构造m行n列的数组
    sqDistances = sqDiffMat.sum(axis=1)                  
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()         # array.argsort(),得到每个元素的排序序号   
    classCount={}                                    # sortedDistIndicies[0]表示排序后排在第一个的那个数在原来数组中的下标  
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 # 从字典中获取key对应的value,没有key的话返回0
    # sorted()函数,按照第二个元素即value的次序逆向(reverse=True)排序  
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

(3)将每个向量合成矩阵,并对测试集中的每个样本分类

def handwritingClassTest():
    hwLabels = []
    # os模块中的listdir('str')可以读取目录str下的所有文件名,返回一个字符串列表  
    trainingFileList = listdir('trainingDigits')          
    m = len(trainingFileList)
    trainingMat = zeros((m,1024))
    for i in range(m):
        fileNameStr = trainingFileList[i]                  
        fileStr = fileNameStr.split('.')[0]                
        classNumStr = int(fileStr.split('_')[0])          
        hwLabels.append(classNumStr)
        trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
    
    # 逐一读取测试图片,同时将其分类 
    testFileList = listdir('testDigits')       
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        fileStr = fileNameStr.split('.')[0]     
        classNumStr = int(fileStr.split('_')[0])
        vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)
        classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
        print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
        if (classifierResult != classNumStr): 
            errorCount += 1.0
    print("\nthe total number of errors is: %d" % errorCount)
    print("\nthe total error rate is: %f" % (errorCount/float(mTest)))
3 运行结果

    进入模块所在的文件夹,打开  Spyder,运行模块。然后在  Ipython 控制台输入以下代码:

import KNN
KNN.handwritingClassTest()

    得到以下结果:

python 实现 KNN 分类器——手写识别

    在 k = 3 的时候,错误率为1.2%。


参考资料:

《机器学习实战》




推荐阅读
  • 最近团队在部署DLP,作为一个技术人员对于黑盒看不到的地方还是充满了好奇心。多次咨询乙方人员DLP的算法原理是什么,他们都以商业秘密为由避而不谈,不得已只能自己查资料学习,于是有了下面的浅见。身为甲方,虽然不需要开发DLP产品,但是也有必要弄明白DLP基本的原理。俗话说工欲善其事必先利其器,只有在懂这个工具的原理之后才能更加灵活地使用这个工具,即使出现意外情况也能快速排错,越接近底层,越接近真相。根据DLP的实际用途,本文将DLP检测分为2部分,泄露关键字检测和近似重复文档检测。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 本文探讨了如何优化和正确配置Kafka Streams应用程序以确保准确的状态存储查询。通过调整配置参数和代码逻辑,可以有效解决数据不一致的问题。 ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
  • 尽管使用TensorFlow和PyTorch等成熟框架可以显著降低实现递归神经网络(RNN)的门槛,但对于初学者来说,理解其底层原理至关重要。本文将引导您使用NumPy从头构建一个用于自然语言处理(NLP)的RNN模型。 ... [详细]
  • 汇编语言等号伪指令解析:探究其陡峭的学习曲线
    汇编语言以其独特的特性和复杂的语法结构,一直被认为是编程领域中学习难度较高的语言之一。本文将探讨汇编语言中的等号伪指令及其对初学者带来的挑战,并结合社区反馈分析其学习曲线。 ... [详细]
author-avatar
玉龙惊云诱惑_786_286
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有