五、使用数学方法实现KNN

使用数学方法实现KNN

(一)KNN流程

1. 准备数据集与预测点

准备好包含特征和标签的数据集

准备好预测点的数据

2. 求距离

计算训练点集中各点到要预测的点 point_predict 的L2(欧式)距离

3. 对距离排序

进行排序,得到排序后的索引值列表

4. 获得 K 个最近的距离

取出前k个距离最小的索引值,得到对应的训练点集中的点构成的列表

5. 获得结果

列表中最短距离对应的训练点的标签

(二)代码

# 导入库
import numpy as np
import matplotlib.pyplot as plt
from collections import Counter # 用于统计标签出现的次数

# 1. 定义数据集和测试点

# 定义三个点集(21个)
point1 = [[7.7,6.1],[3.1,5.9],[8.6,8.8],[9.5,7.3],[3.9,7.4],[5.0,5.3],[1.0,7.3]]
point2 = [[0.2,2.2],[4.5,4.1],[0.5,1.1],[2.7,3.0],[4.7,0.2],[2.9,3.3],[7.3,7.9]]
point3 = [[9.2,0.7],[9.2,2.1],[7.3,4.5],[8.9,2.9],[9.5,3.7],[7.7,3.7],[9.4,2.4]]

# 合并数据集的特征
np_train_data = np.concatenate([point1,point2,point3])

# 生成对应标签
np_train_label = np.array([0]*len(point1)+[1]*len(point2)+[2]*len(point3))
# print(np_train_label)

# 定义一个测试点坐标
predict_point= np.array([3.5,6])

# 2. 定义K的值
k = 3

# 3. 求距离,获得最短距离,最短距离对应的点的坐标

# 使用 Numpy 的广播机制计算距离
distance = np.sqrt(np.sum((np_train_data - predict_point) ** 2, axis=1))
# print(distance)

# 距离排序,获得最短距离对应的索引
index = np.argsort(distance)

# 取出距离最近的k个索引
nearest_index = index[:k]

# 定义空列表存储最近的点、最近的距离、最近点的类型
nearest_points = []
nearest_distances = []
nearest_label = []

# 获取距离最近的前k个点的对应的坐标的距离
for i in nearest_index:
    nearest_points.append(np_train_data[i])
    nearest_distances.append(distance[i])
    nearest_label.append(np_train_label[i])

# 获取统计结果
counter = Counter(nearest_label)
print("测试数据点的label为:",counter.most_common()[0][0])

# 4. 绘制

# 定义x轴和y轴的标签
plt.xlabel("x axis label")
plt.ylabel("y axis label")

# 绘制训练数据集(已知的)
plt.scatter(np_train_data[np_train_label==0,0], np_train_data[np_train_label==0,1], marker="*")
plt.scatter(np_train_data[np_train_label==1,0], np_train_data[np_train_label==1,1], marker="^")
plt.scatter(np_train_data[np_train_label==2,0], np_train_data[np_train_label==2,1], marker="o")

# 绘制测试点(未知的)
plt.scatter(predict_point[0], predict_point[1], marker="x", color="r")

# 绘制最近的k个点 -- 画线,标距离
for i in range(k):
    plt.plot([predict_point[0],nearest_points[i][0]],[predict_point[1],nearest_points[i][1]])
    plt.annotate(f"{nearest_distances[i]:2.2f}",
                 xy=((predict_point[0]+nearest_points[i][0])/2, (predict_point[1]+nearest_points[i][1])/2)
                )

# 展示图片
plt.show()
posted @ 2026-11-04 10:16  桑年  阅读(3)  评论(0)    收藏  举报