Python----机器学习(KNN:使用数学方法实现KNN)

news2025/7/16 8:29:57

一、原理

        以下是K最近邻(K-Nearest Neighbors,简称KNN)算法的基本流程,用于对给定点进行分类预测。

        1. 获得要预测的点 point_predict 。

        2. 计算训练点集 point_set_train 中各点到要预测的点 表 l ist_L2_distance 。

        3. 对 point_predict 的L2距离,得到距离列 list_L2_distance 进行排序,得到排序后的索引值列表 list_index_ascend 。

        4. 获取超参数 k,表示选择最近邻的个数。

        5. 从 list_index_ascend 中取出前 k 个距离最小的索引值,得到对应的训练点集中的点构成的列 表 l ist_k_th 。

        6. 从 list_k_th 中计算各点到要预测的点 point_predict 的L2距离列表,并找到最短距离对应 的训练点的标签 label_L2_distance_min ,即为要预测的点的标签。

        这个过程基于KNN算法,通过比较新点与训练集中点的距离来决定新点所属的类别。在这里,超参数 k 决定了用于预测的最近邻点的数量。整个过程的关键是计算距离并选择最近邻的点,然后通过这些最近 邻的点的标签来确定新点的分类。

 

 导入模块

import numpy as np
from matplotlib import pyplot as plt
from collections import  Counter

 1、定义数据集和测试点

# 定义三个点集
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(np.array((point1,point2,point3)))

# 生成对应的标签
np_train_label=np.array([0]*7+[1]*7+[2]*7)

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

 2、定义K的值

K=3

 3、求距离,获得最短距离、最短距离对应的点的坐标楚

distance=np.sqrt(np.sum((predict_point-np_train_data)**2,axis=1))

distance_index=np.argsort(distance)

nearest_index=distance_index[:K]

nearest_points=[]
nearest_distance=[]
nearest_label=[]
#拿到前K个点的对应的坐标和距离
for i in nearest_index:
    nearest_points.append(np_train_data[i])
    nearest_distance.append(distance[i])
    nearest_label.append(np_train_label[i])

counter=Counter(nearest_label)

 4、绘制

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='s')

plt.scatter(predict_point[0],predict_point[1],marker='o')

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_distance[i]:2.2f}',
                 xy = ((predict_point[0] + nearest_points[i][0]) / 2,(predict_point[1] + nearest_points[i][1]) / 2))

plt.show()

 完整代码

import numpy as np  # 导入 NumPy 库用于数值计算  
from matplotlib import pyplot as plt  # 导入 Matplotlib 库用于数据可视化  
from collections import Counter  # 导入 Counter 以便于统计标签出现频次  

# 1、定义数据集和测试点  
# 定义三个点集(表示不同类别的数据点)  
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]]  # 类别 0 的点  
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]]  # 类别 1 的点  
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]]  # 类别 2 的点  

# 合并数据集的特征  
np_train_data = np.concatenate(np.array((point1, point2, point3)))  # 将所有点集合并为一个 NumPy 数组  

# 生成对应的标签  
np_train_label = np.array([0] * 7 + [1] * 7 + [2] * 7)  # 创建标签数组,标识每个点所属的类别  

# 定义一个测试点坐标  
predict_point = np.array([4, 4])  # 定义需要预测的点坐标  

# 2、定义 K 的值  
K = 3  # 设置 KNN 中 K 的值为 3,表示考虑最近的 3 个邻居  

# 3、求距离,获得最短距离、最短距离对应的点的坐标  
distance = np.sqrt(np.sum((predict_point - np_train_data) ** 2, axis=1))  # 计算测试点与所有训练点的欧几里得距离  

distance_index = np.argsort(distance)  # 获取按距离升序排列的索引  

nearest_index = distance_index[:K]  # 取出最近的 K 个点的索引  

nearest_points = []  # 存储最近 K 个点的坐标  
nearest_distance = []  # 存储最近 K 个点的距离  
nearest_label = []  # 存储最近 K 个点的标签  

# 拿到前 K 个点的对应的坐标和距离  
for i in nearest_index:  
    nearest_points.append(np_train_data[i])  # 添加最近点的坐标  
    nearest_distance.append(distance[i])  # 添加最近点的距离  
    nearest_label.append(np_train_label[i])  # 添加最近点的标签  

# 统计最近 K 个邻居的标签出现频率  
counter = Counter(nearest_label)  # 计算标签的频率  
print(counter.most_common()[0][0])  # 输出出现频率最高的标签(预测结果)  

# 4、绘制  
plt.xlabel("x axis label")  # x 轴标签  
plt.ylabel("y axis label")  # y 轴标签  
# 绘制类别 0 的数据点(标记为三角形)  
plt.scatter(np_train_data[np_train_label == 0, 0], np_train_data[np_train_label == 0, 1], marker='^')  
# 绘制类别 1 的数据点(标记为星形)  
plt.scatter(np_train_data[np_train_label == 1, 0], np_train_data[np_train_label == 1, 1], marker='*')  
# 绘制类别 2 的数据点(标记为方形)  
plt.scatter(np_train_data[np_train_label == 2, 0], np_train_data[np_train_label == 2, 1], marker='s')  

# 绘制待预测点(标记为圆形)  
plt.scatter(predict_point[0], predict_point[1], marker='o', color='red')  

# 绘制预测点与最近邻居之间的连线  
for i in range(K):  
    plt.plot([predict_point[0], nearest_points[i][0]], [predict_point[1], nearest_points[i][1]], color='grey', linestyle='--')  # 画虚线  
    # 在中间位置添加距离的注释  
    plt.annotate(f'{nearest_distance[i]:2.2f}',   
                 xy=((predict_point[0] + nearest_points[i][0]) / 2, (predict_point[1] + nearest_points[i][1]) / 2))  

plt.show()  # 显示绘图结果  

二、库函数 

2.1、Counter

        该模块实现了专门的容器数据类型,提供了 Python 的通用内置容器

        from collections import Counter

        是用于计算可哈希对象的子类。 它是一个集合,其中元素存储为字典键 它们的计数存储为字典值。允许计数为 任何整数值,包括零或负计数。该类类似于其他语言中的 bags 或 multisets。

函数方法
namedtuple()factory 函数,用于创建具有命名字段的 Tuples 子类
deque类似列表的容器,两端都有快速的附加和弹出
ChainMap用于创建多个映射的单个视图的类
Counterdict 子类,用于对可哈希对象进行计数
OrderedDictdict 子类,该子类会记住已添加的顺序条目
defaultdictdict 子类,该子类调用工厂函数来提供缺失值
UserDictDictionary 对象的包装器,以便于字典子类化
UserList包装 list 对象,以便更轻松地进行 list 子类化
UserString

String 对象的包装器,以便更轻松地进行字符串子类化

most_common

        返回 n 个最常见元素的列表及其从 最常见到最不常见。如果省略 n 或 , 则返回计数器中的所有元素。 计数相等的元素按第一个en countered 的顺序排序:None 

Counter('abracadabra').most_common(3)
[('a', 5), ('b', 2), ('r', 2)]

2.2、annotate()

matplotlib.pyplot.annotate(text, xy, xytext=None, xycoords='data', textcoords=None, arrowprops=None, annotation_clip=None, **kwargs)
方法描述
text批注的文本。
xy要注释的点 (x, y)。坐标系已确定 由 xycoords 提供。
xytext放置文本的位置 (x, y)。坐标系 由 TextCoords 确定。
xycoords

给出 xy 的坐标系。

textcoords给出 xytext 的坐标系。
arrowprops

用于在 定位 xy 和 xytext 。默认为 None,即没有箭头是 平局。

由于历史原因,有两种不同的方法可以指定 箭头,“简单”和“花哨”:

annotation_clip

是否在标注 点 xy 位于 Axes 区域之外。

  • 如果为 True,则当 xy 在 xy 之外时,将裁剪注释 轴。

  • 如果为 False,则将始终绘制注释。

  • 如果为 None,则当 xy 位于 x 之外时,将剪切注释 轴和 xycoords 是 'data'。

**kwargs其他 kwargs 将传递给 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2326763.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络攻防快速入门笔记pwn | 02 栈溢出题型 | 2.2 ret2libc

上一篇:网络攻防快速入门笔记pwn | 02 栈溢出题型 | 2.1 ret2text和ret2shellcode 下一篇:网络攻防快速入门笔记pwn | 02 栈溢出题型 | 2.3 ret2syscall 欢迎关注~ ret2libc 一、 什么是ret2libc(一)ret2lib的概念(…

Edge浏览器快速开启IE模式

一些老旧的网站,仅支持Internet Explorer(IE)浏览器访问。 然而,出于安全性的考虑,可能会遇到限制IE浏览器使用的情况。 Microsoft Edge浏览器提供了兼容性配置,可以通过IE模式访问这些网站。 以下是两种…

LeetCode 解题思路 29(Hot 100)

解题思路: 映射关系建立:创建一个哈希表存储数字到字母的映射。递归参数: 给定字符串 digits、结果集 result、当前路径 path、当前位置 start。递归过程: 当当前位置 start 等于 digits 长度时,说明已经遍历完 digi…

LabVIEW永磁同步电机性能测试系统

开发了一种基于LabVIEW的永磁同步电机(PMSM)性能测试系统的设计及应用。该系统针对新能源汽车使用的电机进行稳态性能测试,解决了传统测试方法成本高、效率低的问题,实现了测试自动化,提高了数据的准确性和客观性。 ​…

MTK Camera 照片切视频Systrace拆解分析

和你一起终身学习,这里是程序员Android 经典好文推荐,通过阅读本文,您将收获以下知识点: 一、Systrace 拆解概览二、Systrace 阶段拆解详解 一、Systrace 拆解概览 MTK Camera 照片切换视频trace 拆解(非切换摄像头类) 照片切换视频模块trace…

某合约任意提取BNB漏洞

1背景描述 合约是一个在满足特定条件时在区块链上执行代码的程序,各方以数字签署合同的方式准许并维护它的其运行。这些代码可以是向朋友汇款、买卖 NFT 虚拟商品等一系列复杂的内容。 存在漏洞的目标合约是一个结合Meme文化病毒式传播与去中心化金融(D…

插件实现:分别通过winform和WPF界面输入操作CAD——CAD c#二次开发

效果如下图所示: 主程序 using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using System; using System.Windows…

白酒迈入3.0时代,珍酒李渡如何穿越周期高质增长?

当下,白酒行业仍处深度调整期,过往通过渠道拓展、硬广宣传等推动规模扩张、提升市场份额的模式,愈发难以为继。 行业迫切需要构建高质增长新模式,完成增长动能转换。中国酒业协会理事长宋书玉提出,白酒消费亟需进入品…

人工智能-LangGraph+ChatUI+DeepSeek API搭建本地智能助手

人工智能-LangGraphChatUIDeepSeek API搭建本地智能助手 0 环境说明1 LangGraph2 Agent Chat UI 0 环境说明 环境项环境说明操作系统Windows11 专业版硬件信息联想拯救者Y9000PcondaAnancondaPython版本3.12NodeJs18.20.0 # 使用conda创建python环境 conda create -n langgra…

虚幻5入门

常用操作 运行时,调试相机,按~键,输入ToggleDebugCamera 。进入自由视角 常用节点 gate节点:用于控制该流程通不通,执不执行。Flip Flop节点:反转执行,一次A,一次B。Set Timer by…

慧通测控:汽车RGB氛围灯功能测试介绍

在汽车内饰不断进化的当下,汽车 RGB 氛围灯已从曾经的小众配置,逐渐成为众多车主提升驾乘体验的热门选择。它宛如车内的 “魔法精灵”,凭借丰富的功能,为单调的车厢披上一层梦幻而温馨的色彩。今天,让我们深入探究汽车…

QML Book 学习基础6(定位/布局元素)

目录 定位元素 Column Row Grid Flow 布局元素 1.元素填充它的⽗元素。 2.对齐 定位元素 Column Column (列)元素将它的⼦对象通过顶部对⻬的列⽅式进⾏排列。 spacing 属性⽤来设置每个元素之间的间隔⼤⼩ Row Row (⾏)元…

【SpringCloud】LoadBalance-负载均衡

4. 负载均衡-LoadBalance 4.1 为什么需要负载均衡? 不知道各位心中有没有女神,通常来说一个女神就会有多个舔狗,那这些舔狗呢,就会心甘情愿的帮女神干活,假设女神小美现在有三个舔狗,小美喜欢让这三个舔狗…

自然语言处理(26:(终章Attention 2.)带Attention的seq2seq的实现)

系列文章目录 终章 1:Attention的结构 终章 2:带Attention的seq2seq的实现 终章 3:Attention的评价 终章 4:关于Attention的其他话题 终章 5:Attention的应用 目录 系列文章目录 前言 一、编码器的实现 二、解…

Sentinel实战(二)、流控规则之流控阈值类型、流控模式

spring cloud Alibaba-sentinel-流控 流控规则前置环境一、基于阈值类型(QPS/线程数)维度,设置流控规则demo1、流控规则:设置QPS流控规则设置含义测试,观察流控规则设定后的效果demo2、流控规则-设置线程数流控规则设置含义测试,观察流控规则设定后的效果二、基于流控模…

AI与.NET技术实操系列(四):使用 Semantic Kernel 和 DeepSeek 构建AI应用

1. 引言 在人工智能技术飞速发展的今天,大型语言模型(Large Language Models, LLMs)已成为智能应用开发的核心驱动力。从智能客服到自动化内容生成,LLMs的应用正在深刻改变我们的工作和生活方式。 对于.NET开发者而言,…

HarmonyOS:ComposeTitleBar 组件自学指南

在日常的鸿蒙应用开发工作中,我们常常会面临构建美观且功能实用的用户界面的挑战。而标题栏作为应用界面的重要组成部分,它不仅承载着展示页面关键信息的重任,还能为用户提供便捷的操作入口。最近在参与的一个项目里,我就深深体会…

25-智慧旅游系统(协同算法)三端

介绍 技术: 基于 B/S 架构 SpringBootMySQLLayuivue 环境: Idea mysql maven jdk1.8 node 管理端功能 首页展示图表:以数据可视化方式展示关键业务数据。 用户管理:管理系统用户,包括查看、编辑等操作。 供应商管…

数据结构实验1.2: 顺序表的基本运算

文章目录 一,问题描述二,基本要求三,算法分析(1)插入算法(2)删除算法 四,参考程序五,运行效果 一,问题描述 创建一个顺序表,编程实现顺序表的下列…

【QT】QT中的信号与槽

QT中的信号与槽 一、信号与槽函数的作用二、如何关联信号与槽函数1、借助集成开发环境,右键转到槽函数示例代码: 2、调用connect函数手动关联信号与槽函数 三、扩展四、总结信号与槽的特点1、一个类如果要使用信号以及槽函数,那么该类的定义中…