机器学习--K近邻算法(KNN)(2)

本文详细介绍了K-Nearest-Neighbor(KNN)算法,包括其工作机制、K值选择、距离度量和分类评价规则。讨论了KD树的构建和搜索过程,以及KNN在分类和回归问题中的应用,如鸢尾花数据集分类、手写数字识别和波士顿房价模型。此外,还强调了K值选择的重要性,以及如何通过拆分数据集寻找最优K值以提高模型性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简介

K-Nearest-Neighbor 算法是一种常用的监督学习算法,它没有显式的训练过程,是‘懒惰学习’的显著代表,此类学习算法仅在训练阶段将训练集保存起来,训练时间开销为0,待收到测试样本后在进行处理

k近邻模型的三要素: K值选择、距离度量、分类评价规则

二、工作机制

给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本,然后基于这k个‘邻居’的信息来进行预测。

在分类任务中,可使用“投票法”,即选择这k个样本中出现类别最多的标记作为预测结果;评价分类问题可以使用准确率 score

在回归任务中使用“平均法”,将这k个样本的实值输出标记的平均值作为预测结果;评价回归问题可以使用MSE(均方误差)、MAE(平均绝对值误差),需要注意,语法上y值必须是可以计算的数值类型。
最佳拟合:经验误差和泛化误差相近,泛化误差尽可能小

还可以基于距离远近进行加权平均或加权投票,距离越近,权重越大

距离度量方式:
在这里插入图片描述

其中p=2,就是欧氏距离
p=1,就是曼哈顿距离

三、算法实现

K近邻算法的实现最简单的方法是线性扫描,该方法要计算待预测样本与每一个训练实例的距离,当训练集很大时,计算非常耗时,显然这种方法不太可行。故引入kd树

如果实例点是随机分布的,kd树更适用于训练样本数远大于空间维数时的k近邻搜索。当空间维数接近训练实例数时。它的效率会迅速下降,几乎接近线性扫描。

3.1 KD树

Kd-树是K-dimension tree的缩写,是对数据点在k维空间(如二维(x,y),三维(x,y,z),k维(x1,y,z…))中划分的一种数据结构,主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。本质上说,Kd-树就是一种平衡二叉树。

构造KD树相当于不断用垂直于坐标轴的超平面将K维空间进行切分,构成一系列的K维超矩形区域,直至子区域没有节点。KD树中的每一个节点对应于一个k维超矩形区域。

通常选择训练实例点再选定坐标轴上的中位数为切分点,这样得到平衡KD树,但平衡KD树不一定就是搜索效率最优的。

3.2 KD树搜索过程

①、在kd树中找出包含目标点的x的叶结点:从根结点出发,递归地向下访问kd树。若目标点x当前维的坐标小于切分点的坐标,则移动到左子结点,否则移动到右子结点。直到子结点为叶结点为止。
②、以此叶结点为“当前最近点”。
③、递归地向上回退,在每个结点进行以下操作:
(a)如果该结点保存的实例点比当前最近点距离目标点更近,则以该实例点为“当前最近点”。
(b)当前最近点一定存在于该节点的一个子结点对应的区域。检查该子结点的父结点的另一子结点对应的区域是否有更近的点。具体地,检查另一子结点对应的区域是否与以目标点为球心、以目标点与“当前最近点的距离为半径的超球体相交。如果相交,可能在另一个子结点对应的区域内存在距离目标点更近的点,移动到另一个子结点。接着,递归地进行最近邻搜索;如果不相交,向上回退。
④、当回退到根结点是,搜索结束,最后的“当前最近点”即为x的最近邻点。

四、简单应用

一般用于小样本集的数据模型,K不能为样本集的容量,K值不能为偶数。K的(经验)取值上限为sqrt(样本容量)

3.1 自定义数据集进行KNN预测(分类)

film:
在这里插入图片描述

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

# 导入我们自己构建的伪数据集
film = pd.read_excel('C:/Users/Administrator/Desktop/films.xlsx')

# 获取特征向量集合,和标签集合
y = film['类别'].copy()
X = film[['动作镜头','爱情镜头']].copy()

# 生成一组待预测样本
X_test = np.array([[11,6],[5,17]])

# 取X中的数值
X.values


# 绘制样本集在特征空间中的分布状况
plt.figure(figsize=(8,5))
plt.scatter(X['动作镜头'],X['爱情镜头'],s=100,c=y.map({
    '动作':0,
    '爱情':1
}),cmap=plt.cm.winter)
plt.legend([])

# 显示中文
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值