K近邻算法

本文深入探讨了K近邻算法的基本原理,包括如何定义近邻、确定预测值及评估预测准确性。介绍了基于单变量和多变量的K近邻算法过程,强调了数据预处理的重要性,如标准化和归一化,并讨论了K近邻算法的优缺点。

K近邻算法,意味着在通过分析K个近邻的数据得知所求数据。

回归和分类皆可。

 

问题:

K是什么意思

如何定义近邻

知道近邻怎么确定自己想要的值

这个值是否准确,如何评估预测结果

基于单变量和基于多变量的过程是一样的吗

 

过程:

K:所选择近邻的个数

如何确定近邻,即如何才算是近邻:欧氏距离

确定近邻后,取其相应数据的均值,从而确定所求数据对应值。

有基于单变量和多变量的K近邻算法

例如,我想出租一个房子,有三个房间,我想看看其他有三个房间的房子大多租多少钱。

那么搜索数据,通过计算欧氏距离,筛选出来有三个房间的房子,洗牌一下,取前K个作为自己的近邻,计算租金的平均值,那么我们现在可以确定设定的大概租金。(基于单变量)

同理,我想出租一个房子,有三个房间,带有一个大阳台,房子面积大于120平方,那么就有多个维度需要考虑,同样也可以通过计算欧氏距离,找到近邻。

那么之后怎么知道自己预测的租金是否合适呢?

首先需要进行模型评估:将原始数据集分为训练集和测试集,比如73开(训练集70% 测试集30%)。我们通过训练集来锻炼我们使用K近邻预测租金的能力,之后在测试集中使用我们的能力来预测租金,看看我们预测的价格和实际价格是否相差太多。

同时,利用将原始数据集分为训练集和测试集,我们可以避免我们使用K近邻预测租金的能力过于贴合数据集,也就是过拟合现象,即我们的预测能力受到原始数据集的限制了,只能预测原始数据集的数据,一旦预测数据集以外的房屋类型就会出现较大偏差或预测不准。

用一个考试来举例解释:老师课上给我们练习题做练习,这些练习题我都会了,认为出现这种练习题都是这样解决的,那考试的时候,老师出题,除了类似的题,但其实解题方法有点不同,并不是完全和之前那些练习题的解题方法一致,那么过拟合就是我认为解决那些题的方法和解练习题的方法也是一样的,因此最后解出来的结果肯定会有较大的偏差或不对。

之后我们来看我们预测值和实际值之间的差异:

基于单变量:利用RMSE均方根误差来计算预测值和实际值的差值。RMSE越大,说明预测值和实际值相差越大,模型预测效果不好。

基于多变量:此时需要注意不同变量间的取值差异对欧氏距离的影响。

例如,变量房间数,通常是个位数,和变量房子大小,通常是百位数。我们需要考虑这两个变量的时候,如果不对变量进行处理直接进行欧式距离的计算会发现,计算房间数的值通常比较小,计算房子大小的值通常比较大,而我们衡量近邻是用欧式距离的,那么是否就意味着,变量房子大小起的作用比变量房间数起的作用更大(对欧式距离的值影响更大),但实际上是否有这种影响呢?我们并不确定,那么我们应该是对他们均等处理的。

因此基于多变量的K近邻算法,需要对多个变量进行预处理。

预处理分为标准化(StandardScaler)和归一化(MinMaxScaler)

标准化:把变量的取值压缩到等比例空间中。大多用Z-score 标准化

归一化:把变量的取值压缩到0-1区间上。大多用(X-min)/(max-min)

进行标准化之后就能均等对待多个变量。

之后和基于单变量的K近邻算法一样,最后用RMSE来评估。

K近邻问题:计算太耗时间,需要在所有数据中逐个计算。不适合数据量庞大的时候使用。

K近邻优点:不需要训练模型。

优化:可以利用交叉验证来提高预测能力。

### k近邻算法原理 k近邻算法(KNN算法),最初由Thomas等人在1967年提[^2],核心思在于通过计算未知样本与其他已知样本之间的距离来判断未知样本的类别。对于给定的一个测试样本 \( X_{test} \),算法会找到训练集中与其最相近的\( k \)个邻居,并根据这些邻居的多数表决结果决定该测试样本所属的类别。 #### 参数说明 - **K**: 表示选取多少个最近邻参与决策过程。通常情况下,\( k \)是一个不超过20的小整数[^3]。 - **距离度量方法**: 用于衡量两个样本间的相似程度。常见的有欧氏距离、曼哈顿距离等不同方式[^1]。 当确定了合适的\( k \)之后,在实际操作中还需要考虑如何处理平局情况以及是否采用加权机制等问题。例如,可以通过赋予较近距离更高的权重来进行更精确的选择。 ### 实现步骤 以下是利用Python实现简单的KNN分类器的例子: ```python from collections import Counter import numpy as np def euclidean_distance(x1, x2): """ 计算两点间欧式距离 """ return np.sqrt(np.sum((x1 - x2)**2)) class KNearestNeighbors: def __init__(self, k=3): self.k = k def fit(self, X_train, y_train): self.X_train = X_train self.y_train = y_train def predict(self, X_test): predictions = [] for test_point in X_test: distances = [euclidean_distance(test_point, train_point) for train_point in self.X_train] # 获取最小距离索引列表 nearest_indices = sorted(range(len(distances)), key=lambda i: distances[i])[:self.k] # 统计各类标签数量 labels_count = Counter([self.y_train[index] for index in nearest_indices]) # 添加预测结果到返回数组里 most_common_label = labels_count.most_common(1)[0][0] predictions.append(most_common_label) return predictions ``` 此段代码定义了一个名为`KNearestNeighbors` 的类,实现了基本的功能,包括初始化设置\( k \)(`__init__`)、拟合模型(`fit`) 和做预测 (`predict`) 。其中 `euclidean_distance()` 函数用来计算两向量之间欧几里得距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值