KNN算法

目录

1.模型

2.策略

3.算法


knn(KNearest Neighbors)三要素:

1.距离度量(Distance Metric)

KNN算法中,距离度量是核心,它决定了如何计算新数据点与训练数据点之间的相似度。常用的距离度量包括:

  • 欧氏距离(Euclidean Distance):多维空间中最常见的距离度量方式。
  • 曼哈顿距离(Manhattan Distance):也称为城市街区距离,适用于各个坐标维度的绝对值之和。
  • 闵可夫斯基距离(Minkowski Distance):是欧氏距离和曼哈顿距离的推广,通过参数调整可以变化为其他距离度量。

切比雪夫距离(Chebyshev Distance):在多维空间中,最大坐标差的距离。

2.K值的选择

  • K值的选择对KNN算法的性能有重要影响。K值太小,模型可能会对噪声数据过于敏感,导致过拟合;K值太大,模型可能会受到远离新数据点的训练样本的影响,导致欠拟合。

  • K值的选择通常基于经验或通过交叉验证等方法来确定最优的K值。

选择K值的方法交叉验证,通过交叉验证来评估不同K值的性能,选择最佳K值。

 K值的影响

3.决策规则(Decision Rule)

KNN算法的决策规则决定了如何根据K个最近邻的已知类别来确定新数据点的类别。最常见的决策规则包括:

  • 平均值(Averaging):对于回归问题,可以取K个最近邻目标值的平均值作为预测结果。
  • 加权投票(Weighted Voting):考虑距离的倒数作为权重,距离越近的邻居对预测结果的影响越大。
  • 多数投票(Majority Voting):选择K个最近邻中出现次数最多的类别作为新数据点的预测类别。

基本步骤

  1. 确定K值:选择一个正整数K,代表考虑的最近邻居的数量。
  2. 计算距离:计算待分类样本与训练集中每个样本的距离。
  3. 找到最近的K个邻居:根据距离排序,选择距离最近的K个样本。
  4. 进行投票:让这K个邻居对新样本的类别进行“投票”,最常见的类别即为预测结果。

1.模型

数据决定空间划分

2.策略

k个最近邻的最大类别投票

3.算法

对待分类样本,计算与所有已知样本的距离,获得最近k个样本的标签,“权值最多数”类别为输出待分类样本类别。

K近邻算法的一般流程

1.收集数据:可以使用任何方法

2.准备数据:距离计算所需要的数值,最后是结构化的 数据格式。

3.分析数据:可以使用任何方法

4.训练算法:(此步骤kNN)中不适用

5.测试算法:计算错误率

使用算法:首先需要输入样本数据和结构化的输出结果, 然后运行k-近邻算法判定输入数据分别属于哪个分类, 最后应用对计算出的分类执行后续的处理。

实例:

KD树:优化K-NN搜索

KD树(K-Dimensional Tree)是一种用于多维空间搜索的数据结构,特别适合于K-NN算法中的最近邻搜索。

KD树的优势

  • 减少计算量:通过树结构快速缩小搜索范围,减少距离计算的次数。
  • 提高效率:在高维数据中尤其有效,避免了暴力搜索的高时间复杂度。

KD树的构建

  1. 选择轴:在每个维度上选择一个轴进行分割。
  2. 分割数据:根据选定轴的中位数将数据分为两部分。
  3. 递归构建:对每部分递归构建子树。

KNN算法:判别模型

KNN算法是一种判别模型,因为它直接从训练数据中学习决策边界。然而,它也可以在某种程度上被视为生成模型,因为它可以估计数据的概率分布。

优点

精度高

对异常值不敏感

无数据输入假定

缺点

计算复杂度高

空间复杂度高

适用数据范围

数值型和标称型

代码实现KNN,以鸢尾花为例

欧式距离为例:

from math import sqrt
distances = np.round([sqrt(np.sum((x_train - x_pre)**2)) for x_train in X_train],3)

K折交叉验证

from sklearn.model_selection import KFold 
from sklearn.neighbors import KNeighborsClassifier
X=iris.data
y=iris.target
# 定义我们想要搜索的K值(候选集),这里定义8个不同的值
ks=[1,3,5,7,9,11,13,15]
# 例:进行5折交叉验证,KFold返回的是每一折中训练数据和验证数据的index
# 假设数据样本为:[1,3,5,6,11,12,43,12,44,2],总共10个样本
# 则返回的kf的格式为(前面的是训练数据,后面的是验证数据):
# [0,1,3,5,6,7,8,9],[2,4]
# [0,1,2,4,6,7,8,9],[3,5]
# [1,2,3,4,5,6,7,8],[0,9]
# [0,1,2,3,4,5,7,9],[6,8]
# [0,2,3,4,5,6,8,9],[1,7]
kf =KFold(n_splits=5,random_state=2001,shuffle=True)
# 保存当前最好的K值和对应的准确值
best_k=ks[0]
best_score=0

# 循环每一个K值
for k in ks:
    curr_score=0
    for train_index,valid_index in kf.split(X):
        #每一折的训练以及计算准确率
        clf=KNeighborsClassifier(n_neighbors=k)
        clf.fit(X[train_index],y[train_index])
        curr_score=curr_score+clf.score(X[valid_index],y[valid_index])
    #求5折的平均准确率
    avg_score=curr_score/5
    if avg_score>best_score:
        best_k=k
        best_score=avg_score
    print("现在的最佳准确率:%.2f"%best_score,"现在的最佳K值 %d"%best_k)

print("最终最佳准确率:%.2f"%best_score,"最终的最佳K值 %d"%best_k)

运行效果:

  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值