KNN最近邻原理简介 +python代码实现

前言

​ KNN是机器学习的经典算法之一。其算法的设计符合人的感官知觉,并没有太多的数学理论。感觉完完全全是凭借直觉做出来的。笔者认为这个算法可能算是机器学习里面最简单的了。本文不做理论的严谨解释,仅作简单介绍和相应的代码实现。

原理

目标:

​ 我们的目标当燃是为了分类,当有一个新数据来之后,我们需要根据原始的训练数据,去计算出新数据属于哪一类的概率。

方案:

​ 所以?如何计算属于哪一类?当燃是把这个用距离!就直接计算这个新的数据点到原始数据各个点的距离。然后选择距离最近的前K个。最后看看这前K个里面哪个类别的数量多,我们就权当这个新数据点属于哪一类。就这么简单。

​ 因此,如何计算新数据点到各个数据点的距离?有三种比较常用的点之间的距离公式:

​ ①欧氏距离:
d = ( x o l d 1 − x n e w 1 ) 2 + ( x o l d 2 − x n e w 2 ) 2 + ⋯ d=\sqrt{(x_{old}^1-x_{new}^1)^2+(x_{old}^2-x_{new}^2)^2+\cdots} d=(xold1xnew1)2+(xold2xnew2)2+
​ 其中 x o l d 1 x_{old}^1 xold1的old代表旧的数据,1则代表旧数据的第一个维度。以此类推。

​ ②曼哈顿距离:
d = ∣ x o l d 1 − x n e w 1 ∣ + ∣ x o l d 2 − x n e w 2 ∣ + ⋯ d=|x_{old}^1-x_{new}^1|+|x_{old}^2-x_{new}^2|+\cdots d=xold1xnew1+xold2xnew2+
​ 就是相同维度相减然后取绝对值相加就可以啦!

​ ③余弦距离:


d = x o l d x n e w ∣ x o l d ∣ ∣ x n e w ∣ d=\frac{x_{old}x_{new}}{|x_{old}||x_{new}|} d=xold∣∣xnewxoldxnew
​ 分式上面是向量求内积,下面是向量取模

​ 还有什么马氏距离,兰氏距离、切比雪夫距离等等牛马距离。感兴趣的读者自行查阅,此处不做过多介绍。

​ 具体而言,使用哪一种算法,要依据所要解决的问题而定。实际情况具体分析。

代码实现

​ 以欧氏距离为例。先看一下原始数据:
在这里插入图片描述

​ 然后就是预测出来的结果:
在这里插入图片描述

​ 可以看到预测结果基本上和靠近的原始数据的类别基本一致。当燃了,这也是因为两类数据距离较远的缘故。

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import imageio
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.ion()
class KNN():
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def predict(self,pre_x,k=10):
        #建立一个空的用于存储结果的数组
        pre_result=np.array([])
        for i in pre_x:#循环每一个需要预测的数据
            #每一个数据对应维度都减去pre_x
            result=self.x-i
            #计算平方和然后开方,也就是L2范数
            distance=np.linalg.norm(result,ord=2,axis=1)
            #获取前k个最小值对应的索引
            min_distance_index=np.argsort(distance)[:k]
            #获取对应的y的标签
            y=self.y[min_distance_index]
            #计算等于0的标签量
            y0=np.sum(y==0)
            #计算等于1的标签数量
            y1=np.sum(y==1)
            #将结果储存起来
            if y1>y0:
                pre_result =np.insert(pre_result,obj=pre_result.size,values=1)
            else:
                pre_result=np.insert(pre_result,obj=pre_result.size,values=0)
        return pre_result
def plot_figure(x,y,pre_x,result):
    '''
    :param x: 原始数据x
    :param y: 原始数据对应的标签类别
    :param pre_x: 预测数据x
    :param result: 预测结果
    :return:
    '''
    images=[]
    map_color={0:"r",1:"g"}
    color_initial=[map_color[i] for i in y.squeeze()]
    pre_color=[map_color[i] for i in result]
    plt.scatter(x[:,0],x[:,1],c=color_initial)
    plt.title("进行预测数据的分类结果")
    for index,i in enumerate(pre_x):
        plt.scatter(i[0], i[1], c=pre_color[index])
        plt.savefig("1.png")
        images.append(imageio.v3.imread("1.png"))
        plt.pause(0.01)
    imageio.mimsave("pic.gif",images,duration=0.1)
def main():
    #生成第一类数据和对应的标签
    x1=stats.norm.rvs(1,2,(100,2))
    y1=np.zeros((x1.shape[0],1))
    #生成第二类数据和对应的标签
    x2=stats.norm.rvs(10,2,(100,2))
    y2=np.ones((x2.shape[0],1))
    #合并数据
    x=np.concatenate([x1,x2],axis=0)
    y=np.concatenate([y1,y2],axis=0)
    #生成用于预测的数据
    x3=stats.norm.rvs(1,2,(30,2))
    x4=stats.norm.rvs(10,2,(30,2))
    pre_x=np.concatenate([x3,x4],axis=0)
    np.random.shuffle(pre_x)
    model=KNN(x,y)
    result=model.predict(pre_x,10)
    plot_figure(x,y,pre_x,result)
if __name__ == '__main__':
    main()

结束语

​ 以上就是KNN的简单的原理介绍和代码实现啦。过程并不严谨,如有问题,还望读者能够指出。阿里嘎多!

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值