机器学习算法—— K-近邻算法
一.K-近邻算法简介
K-近邻算法(K-Nearest Neighbors,简称 KNN)是一种基础、直观且非常常用的监督学习算法,主要用于解决分类和回归问题。
它的核心思想可以用一句老话来概括:“物以类聚,人以群分”。换句话说,一个数据点的类别或值,很可能与其最邻近的“邻居”相似。就是通过你的“邻居”来判断你属于哪个 类别
KNN 如何工作?(以分类问题为例)
存储数据: KNN 是一种惰性学习算法。它不会在训练阶段从数据中学习一个明确的模型(比如像线性回归那样得到一个公式)。它只是简单地存储整个训练数据集。
计算距离: 当你有一个新的、未知类别的数据点需要预测时,KNN 会计算这个新点到训练数据集中所有点的距离(通常是欧氏距离,也可以是曼哈顿距离、闵可夫斯基距离等)。
寻找邻居: 在计算出的所有距离中,找出距离最近的 K 个训练数据点。这里的
K
是一个用户预先设定的正整数(比如 K=3, 5, 10)。投票决策:
分类: 查看这 K 个邻居中哪个类别占多数。新数据点就被分配到多数票的那个类别。
回归: 取这 K 个邻居目标值的平均值(或中位数)作为新数据点的预测值。
二.K近邻算法的api的初步使用
Scikit-learn (通常缩写为 sklearn
) 是一个用于 Python 编程语言的、强大且广泛使用的开源机器学习库。它以 NumPy、SciPy 和 Matplotlib 为基础,专注于传统机器学习的核心任务,特别擅长处理中小型结构化/表格数据。
Scikit-learn 是进行传统机器学习(特别是基于结构化数据的分类、回归、聚类、降维)的首选 Python 库,以其易用性、一致性和强大的功能组合,成为数据科学家和机器学习工程师不可或缺的工具箱。对于更复杂的任务(如深度学习或大规模分布式训练),则需要结合其他专用库使用。
1.pip安装Scikit-learn的方法
在cmd命令行窗口下运行以下代码:
# 标准安装
pip install scikit-learn# 如果已安装旧版,升级到最新版
pip install --upgrade scikit-learn
2.K-近邻算法API
代码展示:
from sklearn.neighbors import KNeighborsClassifier
# 获取数据
x=[[1],[2],[0],[0]]
y=[1,1,0,0]# 机器学习过程
# 实例化一个训练模型
estimator=KNeighborsClassifier(n_neighbors=3)
# 模型训练
estimator.fit(x,y)
# 模型预测
print(estimator.predict([[1.5],[2.5]]))
三.kd树
KD树(K-Dimensional Tree)是一种用于高效处理多维空间数据的二叉树数据结构,专门优化K近邻(KNN)算法的搜索效率。它能显著减少计算距离的次数,尤其适用于低维空间(通常维度k < 20)。
1. KD 树的核心概念
定义:KD 树(K-Dimensional Tree)是一种用于高效组织 k 维空间数据的二叉树结构。
核心目的:加速 KNN 算法的搜索过程,将暴力搜索的复杂度从 O(n)O(n) 优化至平均 O(logn)O(logn)。
关键特性:
每个节点代表一个超矩形区域。
非叶子节点通过超平面(垂直于坐标轴)分割空间。
分割维度按层级循环选择(如:深度 dmod kdmodk)。
2.KD树操作原理
空间划分机制
交替分割:递归地在不同维度交替划分空间
根节点:选择第1维分割
第1层子节点:选择第2维分割
第k层子节点:选择第(k mod d)+1维分割(d为总维度)
分割点选择:
最优策略:选择方差最大的维度(最大化分割效果)
简化策略:轮流选择维度(实现更简单)
分割值:通常取当前维度数据的中位数
class KDNode:def __init__(self, point, axis):self.point = point # 当前节点数据点self.axis = axis # 分割维度(0,1,...,k-1)self.left = None # 左子树(当前维度值≤分割值)self.right = None # 右子树(当前维度值>分割值)
四.关键参数:K 值
K
的选择对 KNN 的性能至关重要。K 太小 (如 K=1):
模型对训练数据中的噪声或异常点非常敏感,容易过拟合。
决策边界变得非常复杂和不规则。
K 太大:
模型过于平滑,可能会忽略数据中重要的局部模式,导致欠拟合。
计算成本增加。
可能会将不同类别的点都包含进来,导致预测不准确(尤其是在类别边界不清晰时)。
如何选择 K: 通常需要通过交叉验证等技术来选择一个在验证集上表现最好的 K 值。经验上,K 值常取一个较小的奇数(如 3, 5, 7),以减少平票的可能性(分类任务)。
五.KNN 的特点
优点
简单直观: 概念容易理解,实现相对简单。
无需训练: 惰性学习,没有显式的训练过程(只是存储数据)。
对新数据适应性强: 随着新训练数据的加入,算法能立即适应(无需重新训练整个模型)。
适用于多分类问题: 天然支持多类别分类。
可用于非线性问题: 由于是基于局部信息做决策,能够处理决策边界非常复杂(非线性)的问题。
缺点
计算成本高(预测阶段): 每次预测都需要计算新点到所有训练点的距离。当训练集非常大或特征维度很高时,预测速度会非常慢。
对特征尺度敏感: 如果特征的量纲(单位)差异很大,距离计算会被量级大的特征主导。必须进行特征缩放(标准化/归一化)。
对高维数据不友好: 在高维空间中,点与点之间的距离变得不那么有意义(“维数灾难”),可能导致性能下降。
对不平衡数据敏感: 如果某个类别的样本数量远多于其他类别,那么在投票时,大类别可能会主导 K 个邻居,导致对小类别的预测不准确。
需要存储全部数据: 占用内存空间大。
对无关特征和噪声敏感: 无关特征会干扰距离计算,噪声点会影响邻居的选择和投票结果。
K 值选择影响大: 需要仔细调优 K 值。
六.算法综合案例
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler# 获取数据集
iris = load_iris()# 数据基本处理
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2)# 特征工程
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)# 机器学习(模型选择,模型训练)
# 1.实例化一个训练模型
estimator=KNeighborsClassifier(n_neighbors=110)
# 2.模型训练
estimator.fit(x_train,y_train)# 模型评估
y_predict=estimator.predict(x_test)
print("预测结果为:",y_predict==y_test)
print("预测结果为:",y_predict)score=estimator.score(x_test,y_test)
print("模型的准确率为:",score)
KNN 是一种基于实例的、非参数的简单而强大的机器学习算法。它的核心是通过查找数据点在特征空间中的最近邻居来进行预测。虽然它在小数据集和低维问题上表现良好且易于理解,但其在大型或高维数据集上的计算效率和性能是其主要的局限性。选择合适的 K 值、进行特征缩放和降维通常是获得良好 KNN 模型的关键步骤。
应用场景
分类: 手写数字识别、垃圾邮件检测、图像分类(简单场景)、客户分群预测、疾病诊断辅助。
回归: 房价预测(基于相似房屋)、根据相似用户行为预测用户评分。
推荐系统: 基于相似用户(用户KNN)或相似物品(物品KNN)进行推荐。