knn算法

1. KNN(K-Nearest Neighbors,K最近邻)算法简介

KNN 算法是一种监督学习算法,用于分类和回归任务。它的核心思想是:给定一个样本,找出离它最近的 K 个邻居,然后根据这些邻居的标签或数值来预测该样本的标签或数值


2. KNN 算法的基本原理

  1. 训练阶段
    KNN 算法是一种懒惰学习算法,也就是说,它在训练阶段并不构建任何模型,而是直接存储训练数据。它需要的只是训练数据集。

  2. 预测阶段

    • 对于一个新的输入样本,KNN 会计算该样本与训练集中每个样本的距离(通常使用欧式距离、曼哈顿距离等)。
    • 然后找出距离最近的 K 个样本(邻居),并根据这些邻居的标签(在分类任务中)或数值(在回归任务中)来做出预测。
    • 分类任务:通过邻居的多数投票来决定新的样本的类别(最常见的类别)。
    • 回归任务:通过邻居的平均值或加权平均值来预测新的样本的数值。

3. KNN 分类的过程

假设我们有一个训练数据集,每个样本都有特征和标签:

  • 特征:如身高、体重、颜色等。
  • 标签:如是否喜欢运动(是/否)、猫或狗等分类。

3.1 步骤

  1. 选择 K 值:选择 K(一般是一个正整数),表示需要找多少个最近的邻居。K 的选择会影响分类结果,过小的 K 值可能会导致过拟合,而过大的 K 值则可能导致欠拟合。

  2. 计算距离:对于每个测试样本,计算它与训练集所有样本的距离。常用的距离度量方式包括:

    • 欧氏距离:最常见的距离度量方法,用于计算两个样本在特征空间中的“直线”距离。 d(x,y)=(x1−y1)2+(x2−y2)2+⋯+(xn−yn)2d(x, y) = \sqrt{(x_1 - y_1)^2 + (x_2 - y_2)^2 + \cdots + (x_n - y_n)^2}d(x,y)=(x1​−y1​)2+(x2​−y2​)2+⋯+(xn​−yn​)2​
    • 曼哈顿距离:计算两个样本在特征空间中的“轴对齐”距离。 d(x,y)=∣x1−y1∣+∣x2−y2∣+⋯+∣xn−yn∣d(x, y) = |x_1 - y_1| + |x_2 - y_2| + \cdots + |x_n - y_n|d(x,y)=∣x1​−y1​∣+∣x2​−y2​∣+⋯+∣xn​−yn​∣
  3. 选取最近的 K 个邻居:计算所有训练样本与测试样本的距离,选择距离最小的 K 个训练样本。

  4. 分类决策

    • 分类问题:根据 K 个邻居的标签进行投票,选择最多的标签作为测试样本的预测标签。
    • 回归问题:计算 K 个邻居的平均值或加权平均值,作为测试样本的预测数值。

4. KNN 算法的优点

  1. 简单易懂:KNN 算法直观且易于理解和实现。
  2. 无需训练过程:与许多其他算法(如决策树、支持向量机)不同,KNN 没有显式的训练过程,因此适用于动态数据。
  3. 适用于多类分类问题:KNN 算法天然适用于多类分类,不需要复杂的修改。
  4. 非参数算法:KNN 不做任何假设,因此不需要假设数据分布。

5. KNN 算法的缺点

  1. 计算开销大:KNN 在预测阶段需要计算测试样本与所有训练样本的距离,这在数据集很大的时候会非常耗时。
  2. 存储开销大:由于 KNN 不进行任何训练,所有数据都需要保存在内存中。
  3. 对噪声敏感:如果数据中有噪声,KNN 可能会错误地将噪声点作为邻居,从而影响分类结果。
  4. 高维数据问题(维度灾难):在高维数据中,特征之间的距离差异变得不明显,KNN 的效果会下降。

6. K 值的选择

K 值的选择非常重要,影响 KNN 的表现:

  • K 太小:容易受到噪声的影响,导致过拟合。
  • K 太大:可能会导致欠拟合,不能有效捕捉数据的局部模式。

通常,选择一个合适的 K 值可以通过交叉验证来完成。


7. KNN 算法的应用场景

  1. 分类任务

    • 图像分类:根据图像的特征找到最相似的图像进行分类。
    • 文本分类:根据文档的内容特征进行分类(例如垃圾邮件分类)。
    • 客户细分:根据客户的特征进行客户分类,推荐不同的服务。
  2. 回归任务

    • 预测房价:根据房屋的特征(如面积、位置、房龄等)预测房价。
    • 股票价格预测:根据历史数据预测未来的股票价格。

8. KNN 算法的代码示例

假设我们有一个简单的二维数据集,目标是进行分类。

import matplotlib.pyplot as plt
import numpy as np
from sklearn.neighbors import KNeighborsClassifier

# 定义样本特征数据和对应的标签
X = np.array([[1, 2], [2, 3], [3, 1], [2, 4], [6, 5], [7, 8], [8, 6], [6, 7], [7, 9], [8, 8]])
labels = np.array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1])

# 定义一个新的特征数据
X_new = np.array([[3, 5]])

# 绘制类别为0的数据,红色点
plt.scatter(X[labels == 0, 0], X[labels == 0, 1], color="red", label="Class 0")

# 绘制类别为1的数据,蓝色点
plt.scatter(X[labels == 1, 0], X[labels == 1, 1], color="blue", marker="o", label="Class 1")

# 绘制新的特征数据,绿色加号
plt.scatter(X_new[0, 0], X_new[0, 1], color="green", marker="+", label="New Point")

# 定义k值
k = 3  # 表示需要查找最近的三个邻居

# 计算新的特征数据与样本特征数据的欧氏距离
distances = [np.linalg.norm(X_new - X_) for X_ in X]  # 使用np.linalg.norm计算欧式距离
print("欧氏距离:", distances)

# 查找最近的k个邻居
nearest_indices = np.argsort(distances)[:k]  # 返回距离最小的k个样本的索引
print("最近的k个邻居索引:", nearest_indices)
# 根据索引获取最近邻居的标签
nearest_labels = labels[nearest_indices]
print("最近邻居的标签:", nearest_labels)

# 统计最近邻标签中出现次数最多的类别
from collections import Counter

nearest_labels = Counter(nearest_labels).most_common(1)[0][0]
print("预测类别:", nearest_labels)
# 第二种方法:
# 创建KNeighborsClassifier分类器对象
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X, labels)  # 使用样本的特征和标签训Lor
new_label = knn.predict(X_new)  # 预测新数据
print(new_label)
# 绘制图例和标题
plt.legend()
plt.title("KNN Visualization")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")

# 显示图像
plt.show()

### KNN算法概述 KNN(K-Nearest Neighbors,K近邻)是一种简单却强大的分类与回归方法,在实际应用中非常常见。作为一种有监督学习算法,其核心思想是通过计算待测样本与已知样本之间的距离,找到离该样本近的K个邻居,并依据这些邻居的信息完成预测[^1]。 --- ### KNN算法原理 KNN算法的工作机制主要分为以下几个方面: #### 距离度量 为了判断两个样本之间的相似程度,通常采用欧氏距离或其他形式的距离度量方式。对于特征空间中的两点 \(x_i\) 和 \(x_j\) ,它们之间的欧氏距离定义如下: \[ d(x_i, x_j) = \sqrt{\sum_{k=1}^{n}(x_{ik} - x_{jk})^2} \] 其中,\(n\) 表示特征维度的数量[^2]。 #### 邻居选取 选定参数 \(K\) 后,算法会从训练集中选出与当前测试样本距离小的前 \(K\) 个样本作为“邻居”。这里的 \(K\) 是一个超参数,需根据具体应用场景调整[^3]。 #### 类别决策 在分类任务中,终输出由这 \(K\) 个邻居共同决定。常见的策略包括投票法(多数表决)、加权投票法等。例如,当使用多数表决时,类别标签出现次数多的即为预测结果。 --- ### KNN算法实现 以下是基于Python的一个简易版KNN分类器实现代码示例: ```python import numpy as np from collections import Counter def euclidean_distance(x1, x2): """ 计算欧几里得距离 """ return np.sqrt(np.sum((x1 - x2)**2)) class KNN: 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_sample in X_test: distances = [euclidean_distance(test_sample, train_sample) for train_sample in self.X_train] nearest_indices = np.argsort(distances)[:self.k] nearest_labels = [self.y_train[i] for i in nearest_indices] most_common_label = Counter(nearest_labels).most_common(1)[0][0] predictions.append(most_common_label) return predictions ``` 上述代码实现了完整的KNN流程,包括自定义欧式距离函数以及利用`Counter`模块统计频率高的类别标签。 --- ### 性能评估与优化 在实际操作过程中,可以通过修改变量 `hoRatio` 或者调参数 \(K\) 的大小来观察模型性能变化情况。需要注意的是,不同的数据分布可能会导致佳配置有所不同,因此建议多次实验并记录误差率以便后续改进。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

serenity宁静

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值