zoukankan      html  css  js  c++  java
  • 基于Python的机器学习实战:KNN

    1.KNN原理:

    存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一个数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中最相似数据(最近邻)的分类标签。一般来说,只选择样本数据集中前 $k$ 个最相似的数据,这就是KNN算法 $k$ 的出处, 通常 $k$ 是不大于20的整数。最后,选择 $k$ 个最相似数据中出现次数最多的分类,作为新数据的分类。

    2.实验准备:

    • Python
    • scikit-learn(一个基于python的机器学习库)

    3.实验代码:

    代码有两个版本,一个是自己编写的简单的KNN算法实现,一个是基于scikit-learn库中KNN算法实现的,数据均采用scikit-learn中的手写体数据集。

    版本1(自己编写):

    # -*- coding: utf-8 -*-
    """
    This script is an exercise on KNN.
    
    Created on Tue Nov 03 21:21:39 2015
    
    @author: 90Zeng
    """
    
    import numpy as np
    from sklearn import datasets
    import operator
    
        
    #-----------------function classify--------------------------------------    
    def classify0(inX, dataSet, labels, k):
        dataSetSize = dataSet.shape[ 0 ]
        # 计算输入的向量inX与所有样本的距离
        diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
        sqDiffMat = diffMat ** 2
        sqDistances = sqDiffMat.sum(axis = 1)
        distances = sqDistances ** 0.5
        # 对距离大小进行排序
        sortedDistIndices = distances.argsort()
        classCount = {}
        # 选择距离最小的 K 个点
        for i in range(k):
            voteLabel = labels[ sortedDistIndices[i] ]
            classCount[ voteLabel ] = classCount.get(voteLabel, 0) + 1  
        # 按照类别的数量多少进行排序
        sortedClassCount = sorted(classCount.iteritems(),
                                     key=operator.itemgetter(1), reverse=True)                               
        return sortedClassCount[0][0]  # 返回类别数最多的类别名称
    #-------------------end of function classify--------------------------------
    
    
    def handwritingClassTest():
        # 导入数据
        digits = datasets.load_digits()
        totalNum = len(digits.data)
        # 选出90%样本作为训练样本,其余10%测试
        trainNum = int(0.8 * totalNum)
        trainX = digits.data[0 : trainNum]
        trainY = digits.target[0 : trainNum]
        
        testX = digits.data[trainNum:]
        testY = digits.target[trainNum:]
        
        errorCount = 0
        testExampleNum = len( testX )
        for i in range( testExampleNum ):
            # 测试样本在测试集中真实的类别
            trueLabel = testY[i]
            classifierResult = classify0( testX[ i, : ], trainX, trainY, 5 )
            print "
    The classifier came back with: %d, the real answer is: %d"
                % ( classifierResult, trueLabel )
            if trueLabel != classifierResult:
                errorCount += 1
            else:
                pass
        print "
    The total number of errors is: %d" % errorCount
        print "
    the total error rate is: %f" % ( 
            errorCount / float( testExampleNum) 
            )
        
        
    if __name__ == '__main__':
        print "start..."
        handwritingClassTest()
        

    运行结果:

    版本2(使用库函数):

    # -*- coding: utf-8 -*-
    """
    This script is an exercise on KNN.
    
    Created on Tue Nov 06 21:26:39 2015
    
    @author: ZengJiulin
    """
    print(__doc__)
    
    import numpy as np
    from sklearn import neighbors, datasets
    
    digits = datasets.load_digits()
    totalNum = len(digits.data)
    # 选出90%样本作为训练样本,其余10%测试
    trainNum = int(0.8 * totalNum)
    trainX = digits.data[0 : trainNum]
    trainY = digits.target[0 : trainNum]
    
    testX = digits.data[trainNum:]
    testY = digits.target[trainNum:]
    
    n_neighbors = 10
    
    
    clf = neighbors.KNeighborsClassifier(n_neighbors, weights='uniform')
    clf.fit(trainX, trainY)
    Z = clf.predict(testX)
    
    print "
    the total error rate is: %f" % ( 1 - np.sum(Z==testY) / float(len(testX)) )

    运行结果:

     

    4.总结

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

    缺点:计算复杂度高(要计算待分类样本与所有已知类别样本的距离),空间复杂度高(存储所有样本点和目标样本的距离)

     

     

  • 相关阅读:
    python-web 创建一个输入链接生成的网站
    查看端口有没被占用
    bs的过滤器功能例子
    爬图片的方法
    python 下载图片的方法
    request 里面参数设置 (有空瞄下)
    python 面向对象 初始化(类变量 和 函数内变量)
    访问https请求出现警告,去掉警告的方法
    find 和 find_all 用法
    D3的基本设计思路
  • 原文地址:https://www.cnblogs.com/90zeng/p/python_knn.html
Copyright © 2011-2022 走看看