• 机器学习——K近邻算法(KNN)及其python实现


    参考视频与文献:

    https://www.bilibili.com/video/BV1HX4y137TN/?spm_id_from=333.788&vd_source=77c874a500ef21df351103560dada737

    统计学习方法(第二版)李航(编著) 

    k近邻法(k-nearest neighbor,k-NN)是一种基本分类与回归方法。k近邻法的输入为实例的特征向量,对应于特征空间的点;输出为实例的类别,可以取多类。k近邻法假设给定一个训练数据集,其中的实例类别已定。分类时,对新的实例,根据其k个最近邻的训练实例的类别,通过多数表决等方式进行预测。因此,k近邻法不具有显式的学习过程。k近邻法实际上利用训练数据集对特征向量空间进行划分,并作为其分类的“模型”。k值的选择、距离度量及分类决策规则是k近邻法的三个基本要素。

    k值的选择会对k近邻法的结果产生重大影响。

    如果选择较小的k值,就相当于用较小的邻域中的训练实例进行预测,“学习”的近似误差(approximation error)会减小,只有与输入实例较近的(相似的)训练实例才会对预测结果起作用。但缺点是“学习”的估计误差(estimation error)会增大,预测结果会对近邻的实例点非常敏感。如果邻近的实例点恰巧是噪声,预测就会出错。换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合

    如果选择较大的k值,就相当于用较大邻域中的训练实例进行预测。其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增大。这时与输入实例较远的(不相似的)训练实例也会对预测起作用,使预测发生错误。k值的增大就意味着整体的模型变得简单。

    如果k=N,那么无论输入实例是什么,都将简单地预测它属于在训练实例中最多的类。这时,模型过于简单,完全忽略训练实例中的大量有用信息,是不可取的。

    在应用中,k值一般取一个比较小的数值。通常采用交叉验证法来选取最优的k值。

    此时K=3,待确定的样本寻找离它最近的三个样本 

     

     

     

     程序如下:

    1. import numpy as np
    2. import operator
    3. '''
    4. trainData - 训练集 N,D
    5. testData - 测试 1,D
    6. labels - 训练集标签
    7. '''
    8. # k一般取奇数
    9. def knn(trainData, testData, labels, k):
    10. # 计算训练样本的行数
    11. rowSize = trainData.shape[0]
    12. # 计算训练样本和测试样本的差值
    13. diff = np.tile(testData, (rowSize, 1)) - trainData # 把测试样本复制N份,然后与训练样本相减
    14. # 计算差值的平方和
    15. sqrDiff = diff ** 2 # 计算欧氏距离
    16. sqrDiffSum = sqrDiff.sum(axis=1) # 沿着D的维度求和
    17. # 计算距离
    18. distances = sqrDiffSum ** 0.5
    19. # 对所得的距离从低到高进行排序
    20. sortDistance = distances.argsort() # 返回的输入数据的位置
    21. count = {}
    22. for i in range(k):
    23. vote = labels[sortDistance[i]]
    24. # print(vote)
    25. count[vote] = count.get(vote, 0) + 1
    26. # 对类别出现的频数从高到低进行排序
    27. sortCount = sorted(count.items(), key=operator.itemgetter(1), reverse=True)
    28. # 返回出现频数最高的类别
    29. return sortCount[0][0]
    30. file_data = 'iris.data'
    31. # 数据读取
    32. data = np.loadtxt(file_data,dtype = float, delimiter = ',',usecols=(0,1,2,3)) # 取出输入数据前4
    33. lab = np.loadtxt(file_data,dtype = str, delimiter = ',',usecols=(4)) # 取出输入数据最后一列
    34. # 分为训练集和测试集和
    35. N = 150
    36. N_train = 100
    37. N_test = 50
    38. perm = np.random.permutation(N)
    39. index_train = perm[:N_train]
    40. index_test = perm[N_train:]
    41. data_train = data[index_train,:]
    42. lab_train = lab[index_train]
    43. data_test = data[index_test,:]
    44. lab_test = lab[index_test]
    45. # 参数设定
    46. k= 5
    47. n_right = 0
    48. for i in range(N_test):
    49. test = data_test[i,:]
    50. det = knn(data_train, test, lab_train, k)
    51. if det == lab_test[i]:
    52. n_right = n_right+1
    53. print('Sample %d lab_ture = %s lab_det = %s'%(i,lab_test[i],det))
    54. # 结果分析
    55. print('Accuracy = %.2f %%'%(n_right*100/N_test))

    KNN算法的优势和劣势
    了解KNN算法的优势和劣势,可以帮助我们在选择学习算法的时候做出更加明智的决定。那我们就来看看KNN算法都有哪些优势以及其缺陷所在!

    KNN算法优点

    简单易用,相比其他算法,KNN算是比较简洁明了的算法。即使没有很高的数学基础也能搞清楚它的原理。
    模型训练时间快,上面说到KNN算法是惰性的,这里也就不再过多讲述。
    预测效果好。
    对异常值不敏感
    KNN算法缺点

    对内存要求较高,因为该算法存储了所有训练数据
    预测阶段可能很慢
    对不相关的功能和数据规模敏感

    简单得说,当需要使用分类算法,且数据比较大的时候就可以尝试使用KNN算法进行分类了。

  • 相关阅读:
    Go——数组
    802.11-2020协议学习__专题__TxTime-Calculation__HR/DSSS
    零基础Linux_15(基础IO_文件)软硬链接+动静态库详解
    【AI视野·今日CV 计算机视觉论文速览 第248期】Mon, 18 Sep 2023
    79-基于STM32单片机的条形码扫描识别系统(实物图+源码+原理图+PCB+论文)
    Mac下使用nvm,执行微信小程序自定义处理命令失败
    决策树(Decision Trees)
    如何解决“德语/文”等外文字符显示乱码问题
    一文入门【NestJs】Providers
    linux-进程管理
  • 原文地址:https://blog.csdn.net/qq_42233059/article/details/126852185