KNN算法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

  1. 目录

    一、KNN算法是什么?

    二、代码编写

    1.引入库

    3.主要算法 KNN (教材)

    4.数据合理化

    5.可视化

    三、实验结果

    总结


一、KNN算法是什么?

读者本人的理解是这样的:在一个类别为X(未知)的样本点周围找N个点离它最近的点,并统计这些点的类别(A,B,C),哪种类别多,那么X就是这种类别。举个例子来说离类别为X的最近50个点中 A类有31个,B类有14个,C类有5个,那么X的类别就是A

二、代码编写

1.引入库

from numpy import *
import operator
import matplotlib
import matplotlib.pyplot as plt

2.读入数据

def creatdata() :
    random.seed(0)
    # 设置随机种子以获得可重复的结果
    # 生成特征矩阵 X,50个样本,每个样本2个特征
    group= random.rand(50, 2)*10
    labels= random.choice(['A', 'B','C'], 50)
    return group, labels

3.主要算法 KNN (教材)

欧式距离:\sum ((x_{1}-x_{2})^{2}+(y_{1}-y_{2})^{2})^{0.5} 

def classify0(inX, dataSet, labels, k):## kkn 最近几个样本来决定目标样本的类别
    #欧式距离计算
    dateSetSize = dataSet.shape[0]
    ##shape[0]:表示矩阵的行数 shape[1]:表示矩阵的列数
    diffMat = tile(inX, (1, 1)) - dataSet
    #先沿x轴复制1次,再沿y轴复制dataSetSize次
    # 二维特征相减 X1-X2 OR Y1-Y2
    # tile函数的功能是重复某个数组。比如tile(A, reps),它的作用就是把A重复reps次,
    sqDiffMat = diffMat ** 2
    sqDiffstances = sqDiffMat.sum(axis=1)
    ##axis= 0 对a的横轴(行)进行操作,在运算的过程中其运算的方向表现为纵向(列)运算
    #axis= 1 对a的纵轴(列)进行操作,在运算的过程中其运算的方向表现为横向(行)运算
    distances = sqDiffstances ** 0.5
    ##选择距离最小的k个点
    sortedDistances = distances.argsort()
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistances[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1),reverse=True)# 返回次数最多的类别,即所要分类的类别
    #python3中用items()替换python2中的iteritems() 课本中使用的iteritems 在这里要用items
    #key=operator.itemgetter(1)根据字典的值进行排序
    # key=operator.itemgetter(0)根据字典的键进行排序
    # reverse降序排序字典
    return sortedClassCount[0][0]

4.数据合理化

在我们日常生活中数据差值有时候会很大,为了避免数据差值过大带来的误差,因此我们会对数据进行处理在本文中我们就采取归一化操作,以此降低数据差距过大带来的影响

公式:newValue=(oldValue-minValue)/(maxValue-minValue)

代码如下

def Guiyihua(dataset,intx):  #归一化 dateset :数据集中数据  intx 样本数据
    x = [i[0] for i in dataset]# 用i来遍历dateset 中 二维[x,y]中x 存入x数组中
    y = [i[1] for i in dataset]#用i来遍历dateset 中 二维[x,y]中y 存入y数组中
    minx,miny = min(x),min(y)
    maxx,maxy = max(x),max(y)
    x.append(intx[0])#样本x 存入x
    y.append(intx[1])#样本y 存入y
   
    rangeminmax_x = maxx-minx
    rangeminmax_y = maxy-miny
    for i in range(len(dataset)):#更新二维数组
        dataset[i][0] = (dataset[i][0] - minx)/rangeminmax_x
        dataset[i][1] = (dataset[i][1] - miny)/rangeminmax_y
#重置样本数据
    intx[0] = (intx[0]-minx)/rangeminmax_x
    intx[1] = (intx[1]-miny)/rangeminmax_y
    return dataset,intx

5.可视化

为了让数据看得更加简单明了,我使用matplotlib让数据可视化

代码如下

def makematlab(intx,dataset,labels):  #散点图
    plt.rcParams['font.sans-serif']=['SimHei'] #设置字体
    plt.rcParams['axes.unicode_minus']=False #字符显示
    choosecolors = ['r', 'g', 'y', 'b', 'r', 'c', 'g', 'b', 'k', 'm']
    labelcolors = {}
    setlabels = set(labels)#将labels 变为一个集合
    count = 0
    for i in setlabels: #给集合每个元素上色
        labelcolors.update({i:choosecolors[count]})
        count+=1
    n = dataset.shape[0]#表示个数
    fig = plt.figure()
    x = [i[0] for i in dataset]
    y = [i[1] for i in dataset]
    for i in range(len(x)):
        plt.scatter(x[i],y[i],color = labelcolors[labels[i]],label = labels[i])
        plt.text(x[i], y[i], labels[i], fontsize=12)
    plt.scatter(intx[0],intx[1],color = 'gray')
    plt.xticks(arange(min(x)-1,max(x)+1,step=0.5)) #刻度
    plt.yticks(arange(min(y)-1,max(y)+1,step=0.5))
    plt.title("散点分布")
    print(x)
    plt.show()
    return

三、实验结果

归一化前:  数据较为分散 

归一化后:


总结

通过课本来学习了knn算法,了解knn用途,懂得如何对数据进行一个基本分类,由于本人能力有限,故随机生成数据集不具有现实含义。实验过程中查询课本与网上内容加深knn的理解,并初步学习makematlab

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值