K-近邻(KNN)算法及实践(2)

上一次做到KNN简单的示例,训练集只有4个数据。这一次使用digits数据集,把1600个数据作为训练集输入,200个数据作为测试集输入,使用KNN预测并尝试调整k值使结果更精确。得到的训练结果如下:

K值 正确数 错误数 准确率
1 191 9 95.500000%
2~3 190 10 95.000000%
4 191 9 95.500000%
5 189 11 94.500000%
6 191 9 95.500000%
7 188 12 94.000000%
8 187 13 93.500000%
9 186 14 93.000000%
10 187 13 93.500000%
11 186 14 93.000000%
12 187 13 93.500000%
13~16 186 14 93.000000%
17~18 187 13 93.500000%
19~20 186 14 93.000000%
30 186 14 93.000000%
50 183 17 91.500000%
100 180 20 90.000000%

K取值2~6时,准确率达到95以上,超过20以后准确率明显下降。网上对K取值问题讨论不一,这个问题留给之后有大样本输入再思考吧。

测试代码:
KNN.py

#coding:utf-8

from numpy import *
import operator

#训练数据以及对应的类别
def createDataSet():
    group = array([[1.0,1.1],[1.0,1.0],[0.0,0.0],[0.0,0.1]])
    labels = ['A','A','B','B']
    return group,labels

#KNN分类算法
def classify0(inX,dataSet,label,k):
    dataSize = dataSet.shape[0]#数据集的样本数量
    result=[]#结果list
    ###计算欧式距离
    for ineachX in inX:#对每个测试元素计算
   
        diffMat = tile(ineachX,(dataSize,1)) - dataSet#每个训练样本与测试样本坐标相减
        sqDiffMat = diffMat ** 2#相减结果求平方
        squareDist = sum(sqDiffMat,axis = 1)#平方相加
        dist = squareDist ** 0.5#对平方和开根号
       
        ###对距离进行排序
        sortedDistIndex = argsort(dist)#argsort()根据元素的值从小到大对元素进行排序,返回下标
        classCount={}#统计近距离的该类别个数
        for i in range(k):#统计各类别的次数
            voteLabel = label[sortedDistIndex[i]]
            classCount[voteLabel] = classCount.get(voteLabel,0) + 1
        sortedClassCount=sorted(classCount.iteritems(),
            key=operator.itemgetter(1),reverse=True)
        result.append(sortedClassCount[0][0])#返回标签
    return result

testKNN.py

#coding=utf-8   含有中文必须规定编码格式
import KNN
from sklearn import datasets
import numpy as np
def count(a1,a2,yes,no):#统计正确数与错误数
    i=0
    while i<a1.size:
        if a1[i]!=a2[i]:
            no+=1
        else :
            yes+=1
        i+=1
    return yes,no

if __name__ == "__main__":
    digits = datasets.load_digits()#读取digits数据集
    n=200#后n项为测试集,其他为训练集
    test=digits.data[-n:]#测试集
    train=digits.data[:-n]#训练集
    np.set_printoptions(threshold='nan')#完全打印
    origin=digits.target[-n:]#正确结果
    predict=np.array(KNN.classify0(test, train, digits.target[:-n], 200))#预测结果
    print "origin array:\n%s"%(origin)
    print "predict array:\n%s"%(predict)
    yes,no=0,0
    yes,no=count(origin,predict,yes,no)
    rate=float(100*yes)/float(yes+no)#正确率
    print "\nyes:%d no:%d \naccuracy rate:%f%%\n"%(yes,no,rate)

运行结果:

发布者

VC-Robot

游戏爱好者,动漫迷,C++修炼中,编程菜鸟,随性

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据