当前位置:   article > 正文

最邻近方法nn_机器学习之K-邻近算法

最邻近扩散法

ef7afd52c820a645e7d0a85b2664aedc.png
机器学习之K-邻近算法​bioinfo.online
9c1432e887918fb2635ca29f20065af7.png

K-邻近算法(KNN)

特征

  • 优点:精确度高、对异常值不敏感、无数据输入假定
  • 缺点:计算复杂度高、空间复杂度高
  • 适用数据范围:数值型和标称型

一般流程

  • 收集数据:可以使用任何方法
  • 准备数据:距离计算所需要的数值,最好是结构化的数据格式
  • 分析数据:可以使用任何方法
  • 训练算法:这个不适用于K-邻近算法
  • 测试算法:计算错误率
  • 使用算法:得到预测结果

算法理论概述

使用欧式距离计算两个向量点A和B之间的距离

例如:计算点(0,0)与点(1,2)之间的距离为:

以一个简单例子介绍KNN算法

这里给出一个简单的分类问题,根据KNN算法求出C所在的类别是A还是B。如果只看图,我们很容易发现C属于类别B,因为C距B的距离短。

使用K邻近算法的分析流程:

  • 计算已知类别数据集中的点(A B)与当前点(C)之间的距离
  • 按照距离的递增次序排序
  • 选取与当前点(C)距离最小的K个点(BBA)
  • 确定前K个点在类别中出现的频率
  • 返回前K个点出现频率最高的类别当做当前点的预测分类

505a0d12b76843597939bef5c3585ba7.png

完整的代码如下:

  1. from numpy import *
  2. def createDataSet():
  3. group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
  4. labels=["A","A","B","B"]
  5. return group,labels
  6. group,labels=createDataSet()
  7. # 使用K邻近算需要4个参数:
  8. # inX 需要预测分类向量
  9. # dataSet 训练样本数据集
  10. # labels 训练样本对应的标签
  11. # k 选择最邻近的数目
  12. def classify0(inX,dataSet,labels,k):
  13. # 获得训练样本的个数,本例中有4个
  14. dataSetSize=dataSet.shape[0] # 4
  15. # 复制inX,为4行1列
  16. diffMat=tile(inX,(dataSetSize,1))
  17. '''
  18. [[0.2 0.4]
  19. [0.2 0.4]
  20. [0.2 0.4]
  21. [0.2 0.4]]
  22. '''
  23. # 计算两点之差
  24. diffMat=diffMat-dataSet
  25. '''
  26. [[-0.8 -0.7]
  27. [-0.8 -0.6]
  28. [ 0.2 0.4]
  29. [ 0.2 0.3]]
  30. '''
  31. # 计算平方和
  32. sqDiffMat=diffMat**2
  33. '''
  34. [[0.64 0.49]
  35. [0.64 0.36]
  36. [0.04 0.16]
  37. [0.04 0.09]]
  38. '''
  39. # 相加
  40. sqDistances=sqDiffMat.sum(axis=1)
  41. '''
  42. [1.13 1. 0.2 0.13]
  43. '''
  44. # 开放
  45. distance=sqDistances**0.5
  46. '''
  47. [1.06301458 1. 0.4472136 0.36055513]
  48. '''
  49. # 升序排序,返回的是数组下标
  50. sortedDistIndicies=distance.argsort()
  51. '''
  52. [3 2 1 0] 数组下标为0的元素最大
  53. '''
  54. classCount={} # {'B': 2, 'A': 1}
  55. for i in range(k):
  56. # 循环k次,获取升序排列的第i个标签
  57. voteIlabel=labels[sortedDistIndicies[i]] # B B A
  58. # 计算在循环的k次中,某一个标签出现的次数
  59. classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
  60. ''' k = 3
  61. {'B': 1} 第一次循环
  62. {'B': 2} 第二次循环
  63. {'B': 2, 'A': 1} 第三次循环,A出现1次,B出现2次
  64. '''
  65. # 降序排列得到的字典的值
  66. sortedClassCount = sorted(classCount.items(),key=lambda item: item[1],reverse=True)
  67. '''
  68. [('B', 2), ('A', 1)]
  69. '''
  70. return sortedClassCount[0][0]
  71. # 预测向量[0.2,0.4] 所在的分类
  72. result=classify0([0.2,0.4],group,labels,3)
  73. print(result)

现在我们使用classify0预测sklearn中鸢尾花数据集

鸢尾花的数据集有四个变量 ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
  1. from sklearn import datasets
  2. from KnnMethod import classify0
  3. iris = datasets.load_iris()
  4. iris_X = iris.data
  5. iris_y = iris.target
  6. # 预测向量[5.8, 2.7, 5.1 ,1.9] 所在的分类
  7. result=classify0([5.8, 2.7, 5.1 ,1.9],iris_X,iris_y,3)
  8. print(result) # 2

使用sklearn的通用机器学习模式

  1. import numpy as np
  2. from sklearn import datasets
  3. from sklearn.model_selection import train_test_split
  4. from sklearn.neighbors import KNeighborsClassifier
  5. iris = datasets.load_iris()
  6. iris_X = iris.data
  7. iris_y = iris.target
  8. X_train,X_test,y_train,y_test = train_test_split(iris_X,iris_y,test_size=0.3)
  9. knn = KNeighborsClassifier()
  10. knn.fit(X_train, y_train)
  11. # 预测[5.8, 2.7, 5.1 ,1.9]
  12. print(knn.predict([[5.8, 2.7, 5.1 ,1.9]]))
  13. print(knn.predict(X_test))
  14. print(y_test)

结果:可以看到机器学习并不是100%正确

  1. [2]
  2. [0 2 2 1 1 1 0 1 0 1 2 0 0 0 2 2 0 2 0 2 0 0 1 0 1 0 0 0 0 0 2 2 2 2 2 1 2
  3. 2 1 0 2 0 0 1 1]
  4. [0 2 2 1 1 1 0 1 0 1 2 0 0 0 1 2 0 2 0 2 0 0 1 0 1 0 0 0 0 0 2 2 2 2 2 1 2
  5. 2 1 0 2 0 0 1 1]
注:本内容参考《机器学习实战》这本书
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/442556
推荐阅读
相关标签
  

闽ICP备14008679号