ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

知乎推荐上万的,400集python,K-NN算法的简单实现精讲!

2020-12-24 16:02:11  阅读:281  来源: 互联网

标签:KNN 知乎 NN python 32 算法 answer 数据 classifier


##KNN使用场景

电影可以按照题材分类,那么如何区分 动作片 和 爱情片 呢?

动作片:打斗次数更多
爱情片:亲吻次数更多
基于电影中的亲吻、打斗出现的次数,使用 k-近邻算法构造程序,就可以自动划分电影的题材类型。

本期推送整理了初学者可能会用到的Python资料,含有书籍/视频/在线文档和编辑器/源
代码,关于Python的安装qun:850973621

image

现在根据上面我们得到的样本集中所有电影与未知电影的距离,按照距离递增排序,可以找到 k 个距离最近的电影。
假定 k=3,则三个最靠近的电影依次是, He’s Not Really into Dudes 、 Beautiful Woman 和 California Man。
knn 算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。

KNN开发流程

收集数据:任何方法
准备数据:距离计算所需要的数值,最好是结构化的数据格式
分析数据:任何方法
训练算法:此步骤不适用于KNN
测试算法:计算错误率
使用算法:输入样本数据和结构化的输出结果,然后运行KNN算法判断输入数据分类属于哪个分类,最后对计算出的分类执行后续处理

KNN算法特点

优点:精度高、对异常值不敏感、无数据输入假定
缺点:计算复杂度高、空间复杂度高
适用数据范围:数值型和标称型

KNN是最简单的机器学习算法,没有之一

KNN算法伪代码:

"""
对于每一个在数据集中的数据点:
    计算目标的数据点(需要分类的数据点)与该数据点的距离
    将距离排序:从小到大
    选取前K个最短距离
    选取这K个中最多的分类类别
    返回该类别来作为目标数据点的预测值
"""

def classify0(inX, dataSet, labels, k):
    """
    距离度量 度量公式为欧氏距离
    inX                                  图像文本转化的向量
    dataSet  <class 'numpy.ndarray'>     矩阵的长度
    labels                               存储0~9对应的index位置
    k                                       
    """
    # >>print(type(dataSet))
    #   <class 'numpy.ndarray'>
    # shape函数是numpy.core.fromnumeric中的函数,它的功能是读取矩阵的长度,比如shape[0]就是读取矩阵第一维度的长度。
    dataSetSize = dataSet.shape[0]

    # 原型:numpy.tile(A,reps)
    # tile共有2个参数,A指待输入数组,reps则决定A重复的次数。整个函数用于重复数组A来构建新的数组。
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat ** 2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances ** 0.5

    # 将距离排序:从小到大
    sortedDistIndicies = distances.argsort()
    # 选取前K个最短距离, 选取这K个中最多的分类类别
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1

    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

KNN项目案例:手写数字识别系统

项目概述

构造一个能识别数字 0 到 9 的基于 KNN 分类器的手写数字识别系统。

需要识别的数字是存储在文本文件中的具有相同的色彩和大小:宽高是 32 像素 * 32 像素的黑白图像。

开发流程

收集数据:提供文本文件
准备数据:编写函数 img2vector,将图像格式转换为分类器使用的向量格式
分析数据:在python命令提示符中检查数据,确保它符合要求
训练算法:此步骤不适用于KNN
测试算法:编写函数使用提供的部分数据集作为测试样本,测试样本与非测试样本的区别在于测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误

第一步:收集数据:提供文本文件

第二步:准备数据,导入依赖包

#将图像文本数据转为向量
from numpy import zeros
from os import listdir
from numpy import zeros, tile
import operator

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

在python命令行中输入下列命令测试img2vector函数,然后与文本编辑器打开的文件进行比较:

testVector = img2vector('/Users/xiehao/Desktop/MachineLearning-master/input/2.KNN/testDigits/0_0.txt')
>>print(testVector[0,0:32])
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  1.  0.  0.  0.
 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]

>>print(testVector[0,32:64])
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  1.  1.  1.  1.  1.
 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]

文本原件

image

训练算法:此步骤不适用于KNN

因为测试数据每一次都要与全量的训练数据进行比较,所以这个过程是没有必要的。

测试算法:编写函数使用提供的部分数据集作为测试样本,如果预测分类与实际类别不同,则标记为一个错误

def handwritingClassTest():
    # 1\. 导入训练数据
    hwLabels = []
    trainingFileList = listdir(
        '/Users/xiehao/Desktop/MachineLearning-master/input/2.KNN/trainingDigits/')  # load the training set
    m = len(trainingFileList)
    print(m)
    trainingMat = zeros((m, 1024))
    # hwLabels存储0~9对应的index位置, trainingMat存放的每个位置对应的图片向量
    for i in range(m):
        fileNameStr = trainingFileList[i]
        fileStr = fileNameStr.split('.')[0]  # take off .txt
        classNumStr = int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        # 将 32*32的矩阵->1*1024的矩阵
        trainingMat[i, :] = img2vector(
            '/Users/xiehao/Desktop/MachineLearning-master/input/2.KNN/trainingDigits/%s' % fileNameStr)

    # 2\. 导入测试数据
    testFileList = listdir(
        '/Users/xiehao/Desktop/MachineLearning-master/input/2.KNN/testDigits/')  # iterate through the test set
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        fileStr = fileNameStr.split('.')[0]  # take off .txt
        classNumStr = int(fileStr.split('_')[0])
        vectorUnderTest = img2vector(
            '/Users/xiehao/Desktop/MachineLearning-master/input/2.KNN/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)))

执行handwritingClassTest()

the classifier came back with: 4, the real answer is: 4
the classifier came back with: 4, the real answer is: 4
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 0, the real answer is: 0
                              ........
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 3, the real answer is: 3

the total number of errors is: 11

the total error rate is: 0.011628

可以看到1934个样本只有11个错误,分类准确率99.43%,还是很可以的

作者:raphah
链接:https://www.jianshu.com/p/13d5cb16ef2e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:KNN,知乎,NN,python,32,算法,answer,数据,classifier
来源: https://blog.csdn.net/Ugyfyv/article/details/111634976

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有