K-近邻算法(KNN)

本文详细介绍了KNN算法的概念、基本原理,包括分类和回归过程,以及一个Python实现示例。重点讨论了其优点(如简单直观、对异常值不敏感、无需特征选择)和缺点(如计算复杂度高、内存消耗大和K值选择困难)。
摘要由CSDN通过智能技术生成

一、KNN算法概念

KNN算法,全称为 K-Nearest Neighbors 算法,是一种基于实例的学习(instance-based learning)方法,在机器学习领域中被广泛应用于分类和回归问题。

二、KNN算法原理

KNN算法的基本假设是“相似的事物往往会有相似的输出”。即一个观测样本的类别可以通过观察它周围邻近的K个最相似样本的类别来确定。

分类过程:
1.在进行分类时,对于新的待分类数据点,首先计算它与训练集中所有已知类别数据点的距离(常用的距离度量包括欧氏距离、马氏距离、切比雪夫距离等)。

计算距离:对于测试集中的每个样本,计算它与训练集中每个样本的距离。

        ①曼哈顿距离

        d=\sum_{i=1}^{n}\left | x_{1i}-x_{2i} \right |

        ②欧几里得距离

        d=\sqrt{\sum_{i=1}^{n}\left ( x_{1i}-x_{2i} )*(x_{1i}-x_{2i}\right )}

2.接着,按照距离从小到大排序,选取前K个最近邻的数据点作为参考。
3.最后,统计这K个最近邻数据点所属类别的频数或采用加权投票的方式,将出现频率最高的类别作为新数据点的预测类别。
回归过程:
对于回归问题,KNN算法则是通过计算K个最近邻的平均值或者其他聚合函数(如中位数)来预测目标变量的数值。

三、实例

KNN算法:

def KNN(in_x, x_lables, y_lables, k):
    x_lables_size = x_lables.shape[0]
    # 计算两个颜色之间的欧氏距离
    distances = (np.tile(in_x, (x_lables_size, 1)) - x_lables) ** 2
    ad_distance = distances.sum(axis=1)
    sq_distance = ad_distance ** 0.5  # 开方后得到最后的欧式距离
    ed_distance = sq_distance.argsort()
    classdict = {}
    for i in range(k):
        voteI_lable = y_lables[ed_distance[i]]
        classdict[voteI_lable] = classdict.get(voteI_lable, 0) + 1
    sort_classdict = sorted(classdict.items(), key=operator.itemgetter(1), reverse=True)
    return sort_classdict[0][0]

训练数据:

def DataSet():
    group = np.array([[3, 104], [2, 100], [1, 81], [10, 80], [10, 51], [51, 10], [76, 21], [101, 10], [99, 5], [98, 2]])
    lables = ['red', 'red', 'red', 'red', 'red', 'green', 'green', 'green', 'green', 'green']
    return group, lables

测试数据:

def TestData():
    test_x = [30, 50]
    return test_x

绘图:

def draw(color):
    plt.scatter(group[:, 0], group[:, 1], c=lable, alpha=0.5)
    plt.scatter(test_x[0], test_x[1], c=color, marker='x')
    plt.show()

运行结果:

输入数据所对应的类别是:red

完整代码:

import numpy as np
import operator
import matplotlib.pyplot as plt


# 训练数据
def DataSet():
    group = np.array([[3, 104], [2, 100], [1, 81], [10, 80], [10, 51], [51, 10], [76, 21], [101, 10], [99, 5], [98, 2]])
    lables = ['red', 'red', 'red', 'red', 'red', 'green', 'green', 'green', 'green', 'green']
    return group, lables


# 测试数据
def TestData():
    test_x = [30, 50]
    return test_x


def KNN(in_x, x_lables, y_lables, k):
    x_lables_size = x_lables.shape[0]
    # 计算两个颜色之间的欧氏距离
    distances = (np.tile(in_x, (x_lables_size, 1)) - x_lables) ** 2
    ad_distance = distances.sum(axis=1)
    sq_distance = ad_distance ** 0.5  # 开方后得到最后的欧式距离
    ed_distance = sq_distance.argsort()
    classdict = {}
    for i in range(k):
        voteI_lable = y_lables[ed_distance[i]]
        classdict[voteI_lable] = classdict.get(voteI_lable, 0) + 1
    sort_classdict = sorted(classdict.items(), key=operator.itemgetter(1), reverse=True)
    return sort_classdict[0][0]


def draw(color):
    plt.scatter(group[:, 0], group[:, 1], c=lable, alpha=0.5)
    plt.scatter(test_x[0], test_x[1], c=color, marker='x')
    plt.show()


if __name__ == '__main__':
    group, lable = DataSet()
    test_x = TestData()
    print('输入数据所对应的类别是:{}'.format(KNN(test_x, group, lable, 3)))
    draw(KNN(test_x, group, lable, 3))

四、总结

KNN算法的优点:
1.理论简单:KNN算法原理直观易懂,无需构建复杂的数学模型,只需存储训练数据即可。
2.对异常值不敏感:由于直接比较临近样本,因此对离群点的敏感度相对较低。
3.无须做特征选择:KNN不需要对数据进行特殊预处理,也不需要事先了解数据分布,适用于非线性分类问题。
KNN算法的缺点:
1.计算复杂度高:随着样本数量增加,计算所有样本的距离以及排序操作的时间成本会迅速增大,尤其在大型数据集上效率较低。
2.内存消耗大:需要存储所有训练样本,当样本空间维度高或样本数量多时,占用大量内存资源。
3.参数K的选择:K值的选择对模型性能有很大影响,没有统一的标准来决定最优K值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值