KNN 近邻算法

k近邻算法 (k-Nearest Neighbors,kNN)

前置知识:无。

kNN算法步骤:

  1. 收集整理好的数据,测试用的
    比如,香蕉和苹果的数据。我们可以将 苹果 和 香蕉 按俩个维度划分,长度和宽度(也可以按照别的维度,也可以是 n 维不一定是 2 维)。

假设红色的点是苹果,绿色的点是香蕉;横坐标是长度,纵坐标是宽度。

现在新来了一个点(黑色的),机器会把这个点判断为苹果,还是判断为香蕉呢?
 


  1. 取一个 k 值
    我们先取一个 k 值,简单起见,k = 3 吧。

参数k的取值。这需要根据问题和数据的特点来确定。在实现时可以考虑样本的权重,即每个样本有不同的投票权重,这称方法称为为带权重的k近邻算法。

另外还其他改进措施,如模糊k近邻算法[^James M Keller, Michael R Gray, James Givens. A fuzzy K-nearest neighbor algorithm. systems man and cybernetics, 1985.]。
 


  1. 根据 k 值,k近邻算法的过程即:在所有这些点(红色+蓝色)中,寻找离这个新点(黑色)最近的 k 个点。

我们要做的计算距离,并排序

我们取了 k = 3,那就寻找离黑点最近的 3 个点即可。

计算距离,可用欧拉距离。

二维空间中的欧拉距离是:

三维空间中的欧拉距离是:

n维空间中的欧拉距离是:

 


  1. 让最近的 k 个点根据自己的属性来投票

比如,离黑点最近的 3 个点。其中俩个是苹果,一个是香蕉,那这个新点就是苹果。

根据算法步骤,k近邻算法实现挺简单的,但是当训练样本数大、特征向量维数很高时计算复杂度高。

因为每次预测时要计算待预测样本和每一个训练样本的距离,而且要对距离进行排序找到最近的k个样本。我们可以使用高效的部分排序算法,只找出最小的k个数;另外一种加速手段是k-d树实现快速的近邻样本查找。

#1.收集整理好的数据

#每一个样本的特征,用向量表示
raw_data_X = [
						# [  横坐标,      纵纵标    ],
							[3.393533211, 2.331273381],
              [3.110073483, 1.781539638],
              [1.343808831, 3.368360954],
              [3.582294042, 4.679179110],
              [2.280362439, 2.866990263],
              [7.423436942, 4.696522875],
              [5.745051997, 3.533989803],
              [9.172168622, 2.511101045],
              [7.792783481, 3.424088941],
              [7.939820817, 0.791637231]
             ]
             
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
#所属类别,0代表苹果,1代表香蕉

# numpy里面的数据类型适合计算,所以换成 numpy
X_train = np.array(raw_data_X)
y_train = np.array(raw_data_y)

x = np.array([8.093607318, 3.365731514])
# 新点的数据

kNN 算法实现:

import numpy as np
from math import sqrt
from collections import Counter

#X_train:训练数据    y_train:所属类别    x:新的待测试数据
def kNN(k, X_train, y_train, x):

	  # 列表生成式 计算二维欧拉距离
    distances = [sqrt(np.sum((x_train - x)**2)) for x_train in X_train]
    
    # argsort方法对一个列表排序,并返回列表的下标(我们要的不是距离,而是最近的点)
    nearest = np.argsort(distances)

		# 列表生成式 获取前 k 个元素的值(根据自己的属性来投票,就得知道自己的点是 0 还是 1)
    topK_y = [y_train[i] for i in nearest[:k]]
    
    # Counter函数统计不同类别的点有多少个
    votes = Counter(topK_y)

		# 返回最多的一个点
    return votes.most_common(1)[0][0]
发布了112 篇原创文章 · 获赞 344 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_41739364/article/details/104822007
今日推荐