机器学习:k近邻算法


k近邻算法

一、算法简介

1.算法概述

​ K近邻(K-Nearest Neighbor, KNN)是一种最经典和最简单的有监督学习方法之一。K-近邻算法是最简单的分类器,没有显式的学习过程或训练过程,是懒惰学习(Lazy Learning)。当对数据的分布只有很少或者没有任何先验知识时,K 近邻算法是一个不错的选择。

2.基本要素

(1)k值的选择

一般而言,从k = 1 开始,随着的逐渐增大,K近邻算法的分类效果会逐渐提升;在增大到某个值后,随着的进一步增大,K近邻算法的分类效果会逐渐下降。

(2)距离度量

特征空间中两个实例点之间的距离是二者相似程度的反应
欧氏距离:
在这里插入图片描述
曼哈顿距离:
在这里插入图片描述

3.工作原理

当对测试样本进行分类时,首先通过扫描训练样本集,找到与该测试样本最相似的个训练样本,根据这个样本的类别进行投票确定测试样本的类别。也可以通过个样本与测试样本的相似程度进行加权投票。如果需要以测试样本对应每类的概率的形式输出,可以通过个样本中不同类别的样本数量分布来进行估计。

4.示例

要确定绿圆属于哪个类别,如果k=3,在其最近的3个样本中红色三角形数量最多,绿圆属于红色三角形类别,如果k=5,在其最近的5个样本中蓝色矩形数量最多,绿圆属于蓝色矩形类别。
在这里插入图片描述

二、代码实现

1.问题描述

为了课堂上GPS签到方便,对学校的一些坐标进行了收集,对于在教学楼区的坐标定义了attendance标签,其他坐标定义了absence标签。(红色为attendance,绿色为absence)
在这里插入图片描述

2.代码

import numpy as np
import matplotlib.pyplot as plt
import math
#训练集
x_train = [[20, 25], [8, 32], [7, 52], [28,43], [8,65], [21,46], [38,35], [35,25], [45,31], [50,40], [53,55], [60,58], [52,15]]
y_train = ['attendance', 'attendance', 'attendance', 'attendance', 'attendance','attendance' ,'absence' ,'absence' ,'absence' ,'absence' ,'absence' ,'absence', 'absence'] 

# 测试集
x_test = [[35,17], [10,80], [29,49], [35,40]]
#y_test = ['absence','attendance','attendance','absence']

#便于绘图标签
raw_data_y=[1,1,1,1,1,1,0,0,0,0,0,0,0]
 
X = np.array(x_train)
Y = np.array(raw_data_y)

#利用matplotlib绘制图像
plt.scatter(X[Y==0,0],X[Y==0,1],color='g')
plt.scatter(X[Y==1,0],X[Y==1,1],color='r')
plt.show()

class KNN:
    def __init__(self, x_train, x_test, k):
        # 保留测试点与所以训练样本的距离
        self.distance =  np.zeros((len(x_test), len(x_train)))
        # 保留预测结果
        self.predicted = []
        # KNN中k的取值(不懂看上面基本知识点)
        self.k = k

    # 欧氏距离
    def knn_distance(self, x1, x2):
        dis = math.sqrt(math.pow((x1[0]-x2[0]),2) + math.pow((x1[1]-x2[1]),2))
        return dis

    # 计算待测点与样本点的距离
    def knn(self, x_test, x_train, y_train):
        print(y_train)
        for i in range(len(x_test)):
            for j in range(len(x_train)):
                self.distance[i][j] = self.knn_distance(x_test[i], x_train[j])
            self.predicted.append(self.knn_predicted(self.distance[i], y_train))
        return self.predicted

    

    def knn_predicted(self, distances, y_train):
        #利用numpy的argsort方法获取前K小样本的索引
        k_predicted_index = distances.argsort()[:self.k]
        #通过索引获得索引对应的y_train序列
        topK_y = [y_train[i] for i in k_predicted_index]
        from collections import Counter
        votes = Counter(topK_y)
        
        predict_y = votes.most_common(1)[0][0]
        print(predict_y)
	# 设置KNN中的k
k = 3
knn = KNN(x_train, x_test, k)

# 获得测试集的预测结果
pred = knn.knn(x_test, x_train, y_train)

3.结果分析

1.与测试集对照发现测试结果正确

在这里插入图片描述

2.k取值的影响

在这里插入图片描述

由以上结果可以得到从k = 1 开始,随着的逐渐增大,K近邻算法的分类效果会逐渐提升;在增大到某个值后,随着的进一步增大,K近邻算法的分类效果会逐渐下降。

若k值过小,如果这些数据恰巧是噪声数据,预测就会出错;也就是说,K值选得较小,就会使模型的复杂度增大,发生过拟合。(极端K=1)

若K值较大,这时与训练数据较远(不相似)的训练数据也会对预测产生影响(过拟合),可能时预测产生错误。(极端的K = N)

一般的,K值取一个较小的值,通常采用交叉验证法来求取最优的K值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值