k近邻算法简介及源代码(含图象打印)

来源:互联网 发布:淘宝智能版首页尺寸 编辑:程序博客网 时间:2024/06/06 07:39

一、什么是KNN算法

kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。


实例展示:如下图


     绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。


二、KNN算法的一般流程

1、确定好训练样本和未知样本

2、计算出每个训练样本(至少要有2类)到未知样本的距离

3、赋予K一个确定值

4、通过距离的比较得到离未知样本最近的K个样本

5、判断得到的K个样本中哪一类样本最多

6、未知样本的类别就是K个样本中最多的那类


三、python代码实例

1、导入所需模块

import numpy  from numpy import *  import random  import pylab as pl  import operator  pl.figure(1)  pl.figure(2)  
2、定义一个函数,计算样本的距离,预测类别
def classify(testdata,traindata,labels,k):       #testdate:待分类数集;traindate:分好类的数集;       #tile(a,(b,c)):将a的内容在行上复制b遍,列上复制c遍       trasize=traindata.shape[0]  #得到其维数       tradis1=tile(testdata,(trasize,1))-traindata                    tradis2=tradis1**2       tradis3=tradis2.sum(axis=1)       tradis=tradis3**0.5 #计算样本与训练数据的距离       sortdis=tradis.argsort()#排序       classcount={}#建立空字典       for i in range(k):#通过循环寻找k个近邻                    votelabel=labels[sortdis[i]]                    classcount[votelabel]=classcount.get(votelabel,0)+1       sortedclasscount=sorted(classcount.items(),key=operator.itemgetter(1),reverse=True)       return sortedclasscount[0][0]#返回占最大比例的类别  
3、确定两类正态分布的训练样本

x1 = numpy.round(numpy.random.normal(50, 100, 100),2)  y1 = numpy.round(numpy.random.normal(50, 100, 100),2)  x2 = numpy.round(numpy.random.normal(30,  80, 100),2)    y2 = numpy.round(numpy.random.normal(30,  80, 100),2)a=[]  b=[]  for i in range(100):                    a.append([x1[i],y1[i]])  for i in range(100):                    b.append([x2[i],y2[i]])                  c=a+b  dataset=array(c)   #将列表转化为矩阵  labels=[]for i in range(100):                    labels.append('*')  for i in range(100,200):                    labels.append('o')
4、确定未知样本的位置和K值

x = 85y = 95k=25label=classify([x,y],dataset,labels,k)  
5、打印图像
pl.figure(1)  pl.plot(x1,y1,'*')  pl.plot(x2,y2,'og')pl.plot(82,94,'.r')pl.figure(2)  pl.plot(x1,y1,'*')  pl.plot(x2,y2,'og')  pl.plot(85,95,label)           pl.show()  

四、完整源代码

import numpy  from numpy import *  import random  import pylab as pl  import operator  pl.figure(1)  pl.figure(2)    #计算样本的距离,预测类别  def classify(testdata,traindata,labels,k):       #testdate:待分类数集;traindate:分好类的数集;       #tile(a,(b,c)):将a的内容在行上复制b遍,列上复制c遍       trasize=traindata.shape[0]  #得到其维数       tradis1=tile(testdata,(trasize,1))-traindata                    tradis2=tradis1**2       tradis3=tradis2.sum(axis=1)       tradis=tradis3**0.5 #计算样本与训练数据的距离       sortdis=tradis.argsort()#排序       classcount={}#建立空字典       for i in range(k):#通过循环寻找k个近邻                    votelabel=labels[sortdis[i]]                    classcount[votelabel]=classcount.get(votelabel,0)+1       sortedclasscount=sorted(classcount.items(),key=operator.itemgetter(1),reverse=True)       return sortedclasscount[0][0]#返回占最大比例的类别                                        x1 = numpy.round(numpy.random.normal(50, 100, 100),2)  y1 = numpy.round(numpy.random.normal(50, 100, 100),2)  x2 = numpy.round(numpy.random.normal(30,  80, 100),2)    y2 = numpy.round(numpy.random.normal(30,  80, 100),2)a=[]  b=[]  for i in range(100):                    a.append([x1[i],y1[i]])  for i in range(100):                    b.append([x2[i],y2[i]])                  c=a+b  dataset=array(c)   #将列表转化为矩阵  labels=[]for i in range(100):                    labels.append('*')  for i in range(100,200):                    labels.append('o')x = 85y = 95k=25label=classify([x,y],dataset,labels,k)  pl.figure(1)  pl.plot(x1,y1,'*')  pl.plot(x2,y2,'og')pl.plot(82,94,'.r')pl.figure(2)  pl.plot(x1,y1,'*')  pl.plot(x2,y2,'og')  pl.plot(85,95,label)           pl.show()  



五、结果展示




图一的红色小点,是位置样本的位置。图二橙色的形状代表了是那种类型,图示为圆圈类


原创粉丝点击