当前位置: 首页 > news >正文

深入浅出学习 KNN 算法:从原理到数字识别实践

在机器学习的广阔领域中,KNN(K-Nearest Neighbors,K 近邻)算法以其简单直观的特点占据着重要地位。它无需复杂的模型训练过程,仅通过 “物以类聚” 的思想就能完成分类或回归任务,是很多人入门机器学习时接触的经典算法之一。而数字识别场景,更是能直观展现其工作流程与价值,助力我们深入理解算法。

一、KNN 算法的核心思想

KNN 算法的核心思想可以用 “近朱者赤,近墨者黑” 来概括。简单来说,当要对一个未知样本进行判断时,它会查看这个样本周围最近的 K 个已知样本(即 “邻居”),然后根据这 K 个邻居的情况来决定未知样本的类别(分类任务)或数值(回归任务) 。

比如在数字识别的分类场景中,对于一个未知数字的图像样本,算法会查找其周围最近的 K 个已知数字图像样本(邻居)。若未知样本周围最近的 5 个邻居里,4 个属于数字 “8” 类,1 个属于数字 “3” 类,按照 “少数服从多数” 原则,未知样本就会被判定为数字 “8” 类 。

二、KNN 算法的工作流程(结合数字识别实例)

1.数据准备与预处理

以手写数字识别为例,我们有如图所示的包含大量手写数字的图像(digits.png )。首先,使用 OpenCV 库进行操作:

import numpy as np
import cv2 
img = cv2.imread('digits.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度图
# 将原始图像分割成独立的数字,每个数字大小20*20,共5000个
cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]#按照顺序来看代码,python列表
# 装成array,形状(50,100,20,20),50行,100列,每个图像20*20大小
x = np.array(cells)

接着划分训练集和测试集,让二者比例各占一半:

train = x[:,:50]# 划分为训练集和测试集,比例各占一半
test = x[:,50:100]

为适配 KNN 输入,将每个数字的 2020 图像转为 1400(一行 400 个像素)的形式:

train_new = train.reshape(-1,400).astype(np.float32) # Size = (2500,400)
test_new = test.reshape(-1,400).astype(np.float32) # Size = (2500,400)

然后分配标签,为 0 - 9 每个数字重复 250 次(因共 5000 个样本,0 - 9 各 250 个 ):

k = np.arange(10)#0123456789
labels = np.repeat(k,250)#repeat重复数组中的元素,每个元素重复250次
train_labels = labels[:,np.newaxis]#np.newaxis是NumPy中的一个特殊对象,用于在数组中增加一个新的维度。
test_labels = np.repeat(k,250)[:,np.newaxis]

2.模型构建、训练与预测

利用 OpenCV 创建 KNN 模型并训练,这里 K 取 3:

knn = cv2.ml.KNearest_create()#通过cv2创建一个knn模型
knn.train(train_new, cv2.ml.ROW_SAMPLE, train_labels)#cv2.ml.ROW_SAMPLE:这是一个标志,告诉OpenCV训练数据是按行组织的,即每一行是一个样本。
ret,result,neighbours,dist = knn.findNearest(test_new,k=3) #Knn.predict()

其中,ret表示查找操作是否成功;result是浮点数组,为测试样本的预测标签;neighbours是整数数组,显示与测试样本最近的 3 个邻居索引,可辅助分析哪些训练样本影响预测;dist是浮点数组,呈现测试样本与最近邻居的距离,距离近则预测更可靠 。

3.结果评估

通过对比预测标签与真实标签,统计准确率:

matches = result==test_labels
correct = np.count_nonzero(matches)#
accuracy = correct*100.0/result.size
print("当前使用KNN识别手写数字的准确率为:%.2f%%"%(accuracy))

三、KNN 算法的关键参数

K 值的选择是 KNN 算法中最重要的参数,它直接影响着算法的性能。

当 K 值较小时,模型会更加敏感,更容易受到噪声数据的影响,可能会出现过拟合的情况。因为此时只关注极少数的邻居,一旦这些邻居中有异常值,就会对预测结果产生较大干扰。比如在数字识别中 K = 1 时,若最近邻居因图像噪声等成为异常值,就会错判数字类别。

当 K 值较大时,模型的鲁棒性会增强,对噪声的抵抗能力提升,但可能会出现欠拟合的情况。因为过多的邻居会包含一些距离较远的样本,这些样本可能与未知样本的关联性较弱,从而模糊了不同类别之间的界限。比如 K 值过大,在数字识别里会纳入一些与待识别数字特征差异大的样本,干扰正确判断。

一般来说,可以通过交叉验证的方式来选择合适的 K 值,先尝试一系列可能的 K 值,然后选择在验证集上表现最好的那个。

除了 K 值,距离度量方式也是一个重要参数。不同的距离度量方式适用于不同的数据类型和场景,需要根据实际数据的特点来选择。在数字识别中,常用欧氏距离计算像素点差异,它适用于这种连续型的像素特征数据,能衡量样本间的整体差异;此外还有曼哈顿距离、余弦距离等,若数字识别场景关注不同方向特征差异,余弦距离可能适用,不过欧氏距离在像素对比中更常见。

四、KNN 算法的优缺点(结合数字识别场景分析)

1.优点

KNN 算法的优点十分突出。它易于理解和实现,不需要复杂的数学推导和模型训练过程,对于初学者非常友好。像数字识别案例里,代码流程清晰,利用 OpenCV 或 sklearn 都能轻松搭建。同时,它是一种惰性学习算法,不需要预先训练模型,当有新的手写数字样本(新图像 )加入时,直接将其纳入数据集即可,更新成本低。另外,它对异常值有一定容忍度(在合适的 K 值下 ),比如数字图像里个别像素噪声,只要 K 值选得当,不会严重影响识别结果,并且适用于多分类问题,数字识别就是典型的 0 - 9 多分类场景。

2.缺点

当然,KNN 算法也存在一些缺点。它的计算成本较高,因为每次预测都需要计算未知样本(测试数字图像)与所有已知样本(训练数字图像 )的距离,当数据集规模较大(比如更多手写数字样本 )时,计算量会急剧增加,效率较低。而且它对数据的尺度敏感,不同特征(像素点)的量纲差异会影响距离的计算结果,因此在使用前通常需要对数据进行标准化或归一化处理,在数字识别中虽像素值本身有一定范围,但不同图像整体亮度等差异也需注意。此外,它对稀疏数据不太友好,在特征维度较高时,距离计算的意义可能会降低,即所谓的 “维度灾难”,若数字图像特征维度进一步增加(比如更高分辨率 ),这种问题会更明显。

五、KNN 算法的应用场景拓展(除数字识别外)

尽管存在一些缺点,KNN 算法凭借其独特的优势,在很多领域都有广泛的应用。

在推荐系统中,KNN 可以根据用户的历史行为和偏好(如浏览、购买记录等 ),找到与目标用户兴趣相似的 K 个用户,然后将这些相似用户喜欢的物品推荐给目标用户。

在图像识别领域,除了手写数字识别,对于一些简单的图像分类任务,如区分不同植物叶片图像、识别简单几何图形等,KNN 可以通过计算图像特征之间的距离来判断图像的类别。

在医疗诊断中,KNN 可以根据病人的症状特征(如体温、血压、各项检验指标等 ),找到与该病人症状相似的 K 个已知病例,辅助医生进行疾病的诊断。

六、总结

KNN 算法以其简单易懂的原理和灵活的应用方式,成为机器学习中的经典算法。在数字识别等场景中,它展现出了独特价值,从数据处理、模型构建到结果预测,流程清晰可操作。不过,在使用 KNN 算法时,要注意合理选择 K 值和距离度量方式,同时考虑数据的预处理和计算效率等问题。

通过深入理解 KNN 算法的原理、工作流程和参数选择,我们可以更好地将其应用到实际问题中,像数字识别、推荐系统、医疗诊断等,为解决分类、回归和推荐等任务提供有力的工具。对于初学者来说,掌握 KNN 算法不仅能打下机器学习的基础,还能培养对算法设计的理解和思考能力,借助数字识别这类直观案例,能更轻松踏入机器学习的奇妙世界。

http://www.dtcms.com/a/299948.html

相关文章:

  • 【Linux庖丁解牛】— 日志进程池 !
  • 大模型系列——Dify:知识库与外部知识库
  • SSH连接失败排查与解决教程: Connection refused
  • PromQL完全指南:掌握Prometheus核心查询语言
  • Ubuntu 22.04 配置 Zsh + Oh My Zsh + Powerlevel10k
  • 二十八、【Linux系统域名解析】DNS安装、子域授权、缓存DNS、分离解析、多域名解析
  • C++___快速入门(上)
  • 人工智能之数学基础:概率论之韦恩图的应用
  • WebAPIs里的filter
  • Android 编码规范全指南
  • 驱动-设备树-基本语法
  • Python爬虫实战:诗词名句网《三国演义》全集
  • 服务器:数字世界的隐形引擎
  • 《基于雅可比矢量近似的EIT触觉传感灵敏度非均匀校正》论文解读
  • ESP32实战:5分钟实现PC远程控制LED灯
  • C++类和对象(三)
  • IC测试之pogo pin学习与总结-20250726
  • 进制定义与转换详解
  • 1.Java发展简史与设计哲学
  • 最优估计准则与方法(5)加权最小二乘估计(WLS)_学习笔记
  • 360° 外壁镜头:小物体环外侧检测的创新突破
  • Python day25
  • MySQL中的 redolog
  • 连锁店铺巡查二维码的应用
  • 单片机CPU内部的定时器——滴答定时器
  • 智慧水库边缘计算技术路线与框架设计
  • 21-ospf多区域
  • Python编程:初入Python魔法世界
  • Java 面向对象之方法与方法重载:从基础到实践
  • Go 多模块仓库标签管理教程