KNN算法

一、KNN算法介绍

KNN 算法,也称 k邻近算法,是 有监督学习 中的 分类算法 。它可以用于分类或回归问题,但它通常用作分类算法。

二、KNN算法流程

1.计算已知类别数据集中的点与当前点的距离

2.按照距离增次序排序

3.选取与当前点距离最小的k个点

4.确定前k个点所在类别的出现频率

5.返回前k个点出现频率最高的类别作为当前点的预测分类

三、K的取值

K取太小分类结果易被噪声影响,预测结果破碎

四、过拟合和欠拟合

过拟合:模型训练太好,将早点也归为一般性质,泛化性下降,不会举一反三

欠拟合:样本的一般性尚未完好

五、归一化

计算两个样本之间的距离时,数字查值最大的属性对计算结果的影响最大,为了处理不同取值范围的特征值,使各个属性的权重相等,我们将数值归一化,下列公式可以将数值归一化到0-1之间:

newValue = (oldValue - min)/min-max

六、基于K近邻算法的分类器的实现

1.问题引入

海伦一直使用在线约会网站寻找适合自己的约会对象。她曾交往过三种类型的人:

  • 不喜欢的人

  • 一般喜欢的人

  • 非常喜欢的人

这些人包含以下三种特征

  1. 每年获得的飞行常客里程数

  2. 玩视频游戏所耗时间百分比

  3. 每周消费的冰淇淋公升数

该网站现在需要尽可能向海伦推荐她喜欢的人,需要我们设计一个分类器,根据用户的以上三种特征,识别出是否该向海伦推荐。

2.需求概要分析

根据问题,我们可知,样本特征个数为3,样本标签为三类。现需要实现将一个待分类样本的三个特征值输入程序后,能够识别该样本的类别,并且将该类别输出。

3.程序结构设计说明

根据问题,可以知道程序大致流程如下。

其中输入数据应包含三个值,输出应为喜欢,一般,不喜欢,三个中的一个。

4、K近邻算法的一般流程

数据准备:这包括收集、清洗和预处理数据。预处理可能包括归一化或标准化特征,以确保所有特征在计算距离时具有相等的权重。

玩视频游戏所耗时间百分比    每年获得的飞行常客里程数    每周消费的冰淇淋的公升数    样本分类

我们很容易发现,当计算样本之间的距离时数字差值最大的属性对计算结果的影响最大,也就是说,每年获取的飞行常客里程数对于计算结果的影响将远远大于上表中其他两个特征-玩视频游戏所耗时间占比和每周消费冰淇淋公斤数的影响。而产生这种现象的唯一原因,仅仅是因为飞行常客里程数远大于其他特征值。但海伦认为这三种特征是同等重要的,因此作为三个等权重的特征之一,飞行常客里程数并不应该如此严重地影响到计算结果。

在处理这种不同取值范围的特征值时,我们通常采用的方法是将数值归一化,如将取值范围处理为0到1或者-1到1之间。下面的公式可以将任意取值范围的特征值转化为0到1区间内的值:

选择距离度量方法:确定用于比较样本之间相似性的度量方法,常见的如欧几里得距离、曼哈顿距离等。

确定K值:选择一个K值,即在分类或回归时应考虑的邻居数量。这是一个超参数,可以通过交叉验证等方法来选择最优的K值。

找到K个最近邻居:对于每一个需要预测的未标记的样本:

计算该样本与训练集中所有样本的距离。

根据距离对它们进行排序。

选择距离最近的K个样本

预测:

对于分类任务:查看K个最近邻居中最常见的类别,作为预测结果。例如,如果K=3,并且三个最近邻居的类别是[1, 2, 1],那么预测结果就是类别1。

对于回归任务:预测结果可以是K个最近邻居的平均值或加权平均值。

评估:使用适当的评价指标(如准确率、均方误差等)评估模型的性能。

优化:基于性能评估结果,可能需要返回并调整某些参数,如K值、距离度量方法等,以获得更好的性能。

5.算法实现

data_loader.py:加载数据,归一化处理

首先,从指定文件中读取数据,将前三列(特征)转换为浮点数并存储为 NumPy 数组,最后一列(标签)存储为字符串数组。

normalize_data 函数对特征数据进行归一化处理,将每列的值缩放到 [0, 1] 区间,以便后续计算。最终,代码返回归一化后的特征数据、每列的范围和最小值。

import numpy as np
import osdef load_data(filename):if not os.path.exists(filename):raise FileNotFoundError(f"文件 {filename} 不存在!")# 读取文件内容with open(filename, 'r') as file:lines = file.readlines()# 初始化特征和标签列表features = []labels = []# 解析每一行for line in lines:parts = line.strip().split('\t')# 前三列是特征,转换为浮点数features.append([float(parts[0]), float(parts[1]), float(parts[2])])# 最后一列是标签,保留为字符串labels.append(parts[3])# 转换为 NumPy 数组features = np.array(features)labels = np.array(labels)return features, labelsdef normalize_data(features):min_vals = features.min(axis=0)max_vals = features.max(axis=0)ranges = max_vals - min_valsnorm_features = (features - min_vals) / rangesreturn norm_features, ranges, min_vals
knn_algorithm.py实现 KNN 算法

euclidean_distance 函数计算两个样本之间的欧几里得距离。

knn_classify 函数对测试样本进行分类:它计算测试样本与每个训练样本的距离,按距离排序后选择距离最近的 k 个邻居,统计这些邻居的标签,并返回出现次数最多的标签作为预测结果。

import numpy as np
from collections import Counter
import mathdef euclidean_distance(x1, x2):return math.sqrt(np.sum((x1 - x2) ** 2))def knn_classify(test_data, train_data, train_labels, k):distances = []for i in range(len(train_data)):distance = euclidean_distance(test_data, train_data[i])distances.append((distance, train_labels[i]))# 按距离排序distances.sort(key=lambda x: x[0])# 选择前k个最近邻居k_nearest_neighbors = distances[:k]# 统计k个邻居的类别k_nearest_labels = [neighbor[1] for neighbor in k_nearest_neighbors]most_common = Counter(k_nearest_labels).most_common(1)return most_common[0][0]
tester.py负责测试模型的性能

根据 test_ratio 划分测试集和训练集,然后对每个测试样本调用 knn_classify 函数进行分类,并比较预测结果与实际标签。如果预测错误,则增加错误计数。最后,计算并返回测试集的错误率,同时打印每个测试样本的预测结果和实际结果。

from knn_algorithm import knn_classifydef test_knn(norm_features, labels, k, test_ratio=0.1):num_test_samples = int(len(norm_features) * test_ratio)error_count = 0.0for i in range(num_test_samples):# 使用KNN进行分类predicted_label = knn_classify(norm_features[i], norm_features[num_test_samples:], labels[num_test_samples:], k)# 打印预测结果和实际结果print(f"测试样本 {i + 1}: 预测结果: {predicted_label}, 实际结果: {labels[i]}")if predicted_label != labels[i]:error_count += 1.0# 计算错误率error_rate = error_count / num_test_samplesprint(f"测试集错误率: {error_rate}")return error_rate
main.py主程序,负责调用其他模块的功能

首先加载数据并进行归一化处理,然后测试 KNN 模型的性能,计算测试集的错误率。接着,程序提示用户输入新样本的特征值,将其归一化后使用 KNN 算法进行分类,并输出预测结果。如果数据文件不存在,程序会捕获并提示文件未找到的错误。

import numpy as np  # 添加 numpy 导入
from data_loader import load_data, normalize_data
from knn_algorithm import knn_classify
from tester import test_knndef classify_new_sample(norm_features, labels, ranges, min_vals, k):# 输入新样本的特征值print("请输入待分类样本的三个特征值:")flight_miles = float(input("每年获得的飞行常客里程数:"))game_time = float(input("玩视频游戏所耗时间百分比:"))ice_cream = float(input("每周消费的冰淇淋公升数:"))# 将输入的特征值归一化new_sample = np.array([flight_miles, game_time, ice_cream])  # 使用 np.arraynew_sample_norm = (new_sample - min_vals) / ranges# 使用KNN进行分类predicted_label = knn_classify(new_sample_norm, norm_features, labels, k)# 输出分类结果print(f"新样本的分类结果: {predicted_label}")if __name__ == "__main__":# 文件路径filename = r'E:\University\2xia\MachineLearning\pythonProject1\datingTestSet.txt'try:# 加载数据features, labels = load_data(filename)# 归一化处理norm_features, ranges, min_vals = normalize_data(features)# 设置K值k = 3# 测试KNN模型print("开始测试KNN模型...")test_knn(norm_features, labels, k)# 分类新样本print("\n开始分类新样本...")classify_new_sample(norm_features, labels, ranges, min_vals, k)except FileNotFoundError as e:print(e)

7.实验结果

8.分析K取不同值对模型错误率的影响

当K=1时

当K=3时

当K=15时

当K=100时

当K=200时当K=500时

总结

由此观之,K的取值对模型效果有着很大的影响,k取值过小模型容易被噪声影响,过拟合;K取值过大,模型容易欠拟合,尚未学习完好;

六、K的取值对KNN算法时间复杂度的影响

当k<n时 T(O) = O(nm)

当k=n时 T(O) = O(1) 只需要统计样本中数量最多的类别

(n为样本数,m为特征向量的维度)

七.问题

将数据转换为 NumPy 数组(np.array),numpy数组支持多维列表,有利于向量化操作,NumPy 支持对整个数组进行数学运算(如加减乘除、平方、求和等),需显式编写循环。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

星越L_可调悬挂使用讲解

目录 1.可变阻尼设置 1.可变阻尼设置

G-Star 校园开发者计划·黑科大|开源第一课之 Git 入门

万事开源先修 Git。Git 是当下主流的分布式版本控制工具&#xff0c;在软件开发、文档管理等方面用处极大。它能自动记录文件改动&#xff0c;简化合并流程&#xff0c;还特别适合多人协作开发。学会 Git&#xff0c;就相当于掌握了一把通往开源世界的钥匙&#xff0c;以后参与…

html5炫酷3D立体文字效果实现详解

炫酷3D立体文字效果实现详解 这里写目录标题 炫酷3D立体文字效果实现详解项目概述技术实现要点1. 基础布局设置2. 动态背景效果3. 文字渐变效果4. 立体阴影效果5. 悬浮动画效果 技术难点及解决方案1. 文字渐变动画2. 立体阴影效果3. 性能优化 浏览器兼容性总结 项目概述 在这个…

《白帽子讲 Web 安全》之开发语言安全深度解读

目录 引言 1.PHP 安全 1.1变量覆盖 1.2空字节问题 1.3弱类型 1.4反序列化 1.5安全配置 2Java 安全 2.1Security Manager 2.2反射 2.3反序列化 3Python 安全 3.1反序列化 3.2代码保护 4.JavaScript 安全 4.1第三方 JavaScript 资源 4.2JavaScript 框架 5.Node.…

django设置admin的排列顺序,耗3小时【躲坑指南】

django 项目中&#xff0c;这个数据栏目的显示排列顺序我希望更贴近业务 比如要让【商品货品信息】中的9个数据表根据人为规定来进行排序 结果&#xff1a;工程量很大。 能够实现人为的自定义排序 最简单的设置就是给模型添加号数标记 主应用中创建admin–设置了其中一个应用…

macOS使用brew切换Python版本【超详细图解】

目录 一、更新Homebrew仓库 二、安装pyenv 三、将pyenv添加到bash_profile文件中 四、使.bash_profile文件的更改生效 五、安装需要的Python版本 六、设置全局使用的Python版本 七、检查Python版本是否切换成功 pyenv常用命令 一、更新Homebrew仓库 brew update 这个…

【深度学习新浪潮】AI ISP技术与手机厂商演进历史

本文是关于AI ISP(人工智能图像信号处理器)的技术解析、与传统ISP(图像信号处理器)的区别、近三年研究进展,以及各大手机厂商在该领域演进历史的详细报告。本报告综合多个权威来源的信息,力求全面、深入地呈现相关技术发展脉络与行业动态。 第一部分:AI ISP的定义及与传…

如何让节卡机器人精准对点?

如何让节卡机器人精准对点&#xff1f; JAKA Zu 软件主界面主要由功能栏、开关栏、菜单栏构成。 菜单栏&#xff1a;控制柜管理&#xff0c;机器人管理与软件管理组成。主要功能为对控制柜关机、APP 设置、机器人本体设 置、控制柜设置、连接机器人和机器人显示等功能。 开关…

QAI AppBuilder 快速上手(7):目标检测应用实例

YOLOv8_det是YOLO 系列目标检测模型&#xff0c;专为高效、准确地检测图像中的物体而设计。该模型通过引入新的功能和改进点&#xff0c;如因式分解卷积&#xff08;factorized convolutions&#xff09;和批量归一化&#xff08;batch normalization&#xff09;&#xff0c;在…

c#难点整理

1.何为托管代码&#xff0c;何为非托管代码 托管代码就是.net框架下的代码 非托管代码&#xff0c;就是非.net框架下的代码 2.委托的关键知识点 将方法作为参数进行传递 3.多维数组 4.锯齿数组 5.多播委托的使用 6.is运算符 相当于逻辑运算符是 7.as 起到转换的作用 8.可…

二次向用户申请授权

HarmonyOS 5.0.3(15) 版本的配套文档&#xff0c;该版本API能力级别为API 15 Release 文章目录 当应用通过requestPermissionsFromUser()拉起弹框请求用户授权时&#xff0c;用户拒绝授权。应用将无法再次通过requestPermissionsFromUser()拉起弹框&#xff0c;需要用户在系统应…

JetsonNano —— 4、Windows下对JetsonNano板卡烧录刷机Ubuntu20.04版本(官方教程)

介绍 NVIDIA Jetson Nano™ 开发者套件是一款面向创客、学习者和开发人员的小型 AI 计算机。按照这个简短的指南&#xff0c;你就可以开始构建实用的 AI 应用程序、酷炫的 AI 机器人等了。 烧录刷机 1、下载 Jetson Nano开发者套件SD卡映像 解压出.img文件并记下它在计算机上的…

Chapter 8 Charge Pump

Chapter 8 Charge Pump 8.1 Introduction 电荷泵就是capacitive DC–DC converters, 一般把小功率bias generation叫做电荷泵, 传输大功率的称为switched-capacitor DC–DC converters. 但其实两者都是通过电容网络的charge redistribution, 来实现电压的倍增或者倍降. 8.1.…

计算机网络——通信基础和传输介质

物理层任务&#xff1a;实现相邻节点之间比特&#xff08;0或1&#xff09;的传输 到了数据链路层之后&#xff0c;它会以帧为单位&#xff0c;把若干个比特交给物理层&#xff0c;物理层需要把这些比特信息转化成信号&#xff0c;在物理传输媒体上进行传输 通信基础基本概念 信…

【架构】单体架构 vs 微服务架构:如何选择最适合你的技术方案?

文章目录 ⭐前言⭐一、架构设计的本质差异&#x1f31f;1、代码与数据结构的对比&#x1f31f;2、技术栈的灵活性 ⭐二、开发与维护的成本博弈&#x1f31f;1、开发效率的阶段性差异&#x1f31f;2、维护成本的隐形陷阱 ⭐三、部署与扩展的实战策略&#x1f31f;1、部署模式的本…

Java-SpringBootWeb入门、Spring官方脚手架连接不上解决方法

一. Spring 官网&#xff1a;Spring | Home Spring发展到今天已经形成了一种开发生态圈&#xff0c;Spring提供了若干个子项目&#xff0c;每个项目用于完成特定的功能(Spring全家桶) Spring Boot可以帮助我们非常快速的构建应用程序、简化开发、提高效率 。 二. Spring Boot入…

springboot整合redis

创建springboot整合redis工程&#xff1a; 一、springboot整合redis步骤 首先我们要知道什么是redis&#xff1a; 三步骤完成springboot对redis数据库的整合&#xff1a; 1、导入springboot整合redis坐标&#xff08;上面勾选的那个就是&#xff09; 2、在yml配置文件中配置re…

图解AUTOSAR_CP_EEPROM_Abstraction

AUTOSAR EEPROM抽象模块详细说明 基于AUTOSAR标准的EEPROM抽象层技术解析 目录 1. 概述 1.1 核心功能1.2 模块地位2. 架构概览 2.1 架构层次2.2 模块交互3. 配置结构 3.1 主要配置容器3.2 关键配置参数4. 状态管理 4.1 基本状态4.2 状态转换5. 接口设计 5.1 主要接口分类5.2 接…

【AI Infra】【RLHF框架】二、VeRL中colocate实现解析

​ colocate的作用是使多个Worker共享相同的资源池。当然&#xff0c;目前verl中所有模型的Worker都共享相同的资源池:global_pool。这篇博客主要通过例子和源代码理解verl中colocate的实现&#xff0c;需要一些前置知识。建议先阅读 【AI Infra】【RLHF框架】一、VeRL中基于R…

PostgreSQL_数据表结构设计并创建

目录 前置&#xff1a; 1 数据表设计思路 2 数据表格SQL 3 创建 3.1 创建数据库 db_stock 3.2 在 pgAdmin4 中创建表 前置&#xff1a; 本博文是一个系列。在本人“数据库专栏”-》“PostgreSQL_”开头的博文 1 数据表设计思路 1 日数据来自优矿&#xff0c;优矿的数据…