经典knn算法的小测试

学习笔记——knn

首先,第一次写博客这样的东西着实还蛮不知道怎么写的。
所以本文章只是自己的一点代码编写,过程以及一些问题的总结。比较private
此次程序仅是knn分类的一个完成,以及小测试

代码首先是生成一个对应的数据

from numpy import *
import operator

def creatdataset():
    group = array([[1,1.1],[1,1],[0,0],[0,1]])
    labels = ['a','a','b','b']
    return group, labels

其中用到的第三方库为numpy ,是在python中比较常用的科学计算包,用于一般的矩阵计算,线性代数问题以及傅里叶变换

其中array用于给group定义一个4行,三列的矩阵。labels用于存放标签,ps:也就是用来分类说明的。

creatdataset函数,其实也就是对训练集进行的生成,以及保存。

knn算法演示

def classify0(inX, dataset, labels,k):
    datasetsize = dataset.shape[0]
    diffmat = tile(inX, (datasetsize, 1)) - dataset
    sq_diffmat = diffmat**2
    sq_distances = sq_diffmat.sum(axis=1)
    distances = sq_distances ** 0.5
    sortedistindicis = distances.argsort()
    classcount={}
    for i in range(k):
        votelabel = labels[sortedistindicis[i]]
        classcount[votelabel] = classcount.get(votelabel, 0) + 1
    sortedclasscount = sorted(classcount.items(),
                                  key=operator.itemgetter(1), reverse=True)
    return sortedclasscount[0][0]

knn 的分类其实就是对 输入的2维值或者3维(这个看训练集中定义的数组类型)进行一个欧氏距离的计算

计算输入的inX的 xA,xB之间的距离,通过距离最小,对输入的位置进行分类。

其中shape[0],是返回训练集中的行数进行,所以说datasetsize其实就是4,tile(inX, (datasetsize,1))的效果其实就是

tile([0,0], (4, 1))
array([[0,0],[0,0],[0,0],[0,0]])
 ###也就是 diffmat进行了一个4行1列矩阵的减法

diffmat**2 自然不用说是在平方,sqdistance.sum(axis =1)这里还是蛮有意思的,axis=0表示参数的列,axis = 1表示参数的行

所以正好完成了参数中 x,y的和计算。然而后面的argsort就很有意思了,下面来介绍一下argsort()函数的一个测试

argsort,从英文的角度上来说,arg其实是争议的,sort我们很熟悉了分类。也就是说函数进行了排序,而且还是比较特别的排序,可见下演示

import numpy as as
q=as.array([1,2,3,-1,4,8])
print(q.argsort())
([3,0,2,1,4,5])

这里 显示的 其实内核中argsort()进行了从小到大的一个排序,但是·为什么输出的结果却是(3,0,2,1,4,5),眼尖的话其实很容易就发现了,q[3]=-1 是的是最小的那个数,q[5]=8最大。所以说明argsort()其实排序了,不过输出为index值。很神奇,这也说明了python的严谨性,程序员不会得到它的值,而是拿到了它的index。这样也就不会轻易的在后面的处理中轻易改变一个重要的参数。

接下来就是对对比计算的 输入值进行遍历 应为训练集中的个数为4则,k的取值为3即可。

其中classcount是一个字典,其实就存入了a,b和其进行对比后重复出现的次数

classcount[votelabels]其实就等于classcount[a]和classcount[b],为了更清楚了看到整个过程,所以对主要的参数进行显示

def classify0(inX, dataset, labels,k):
    datasetsize = dataset.shape[0]
    diffmat = tile(inX, (datasetsize, 1)) - dataset
    sq_diffmat = diffmat**2
    sq_distances = sq_diffmat.sum(axis=1)
    distances = sq_distances ** 0.5
    sortedistindicis = distances.argsort()
    print(sortedistindicis)
    classcount={}
    for i in range(k):
        votelabel = labels[sortedistindicis[i]]
        classcount[votelabel] = classcount.get(votelabel, 0) + 1
        print(classcount)
    sortedclasscount = sorted(classcount.items(),
                                  key=operator.itemgetter(1), reverse=True)

    return sortedclasscount[0][0]
[2 3 1 0]
{'b': 1}
{'b': 2}
{'b': 2, 'a': 1}
b

以上为结果,在输入[0,0]时确认分类为b,对classcount中前3个进行了计数,着出现多的肯定只在前3个之内。

sortedclasscount = sorted(classcount.items(),
                                  key=operator.itemgetter(1), reverse=True)
之后就是从大到小的排列 并且items是对字典进行读入,并且key=itemgetter(1),第一个领域进行读取,确定排列后得到的[0][0]位置上的 标志就是分类后的标志 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值