numpy函数实现K-近邻算法

本文详细介绍了如何利用numpy实现K-近邻(KNN)算法,包括array、shape、tile等函数的运用,以及数据预处理、距离计算、分类预测等步骤。通过示例展示了KNN在约会网站配对效果改善中的应用,强调了算法的优缺点,并提供了完整程序示例。
摘要由CSDN通过智能技术生成

K-近邻算法的原理是采用测量不同特征值之间的距离方法进行分类。
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。
使用数据范围:数值型和标称型。
实现K-近邻算法的计算路径,对未知类别熟悉的数据集中的每个点依次执行以下操作:

  1. 计算已知类别数据集中的点与当前点之间的距离;
  2. 按照距离递增次序排序;
  3. 选取与当前点距离最近的K个点;
  4. 缺点前K个点所在类别的出现频率;
  5. 返回前K个点出现频率最高的类别作为当前点的预测分类。

以下是函数学习过程以及算法实现步骤。

array函数

numpy中的array是用来创建数组的,使用array函数创建时,参数必须是由方括号括起来的列表,而不能使用多个数值作为参数调用array。

   >>> from numpy import *
>>> a=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
>>> a
array([[1. , 1.1],
       [1. , 1. ],
       [0. , 0. ],
       [0. , 0.1]])

shape函数

shape函数是numpy.core.fromnumeric中的函数,它的功能是查看矩阵或者数组的维数。
首先a.shape是查询数组的形状,从第一维、第二维、依次查询数组长度,查询结果为tuple数据类型,如:

>>> from numpy import *
>>> a=array([[[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]],[[1.0,1.1],[1.0,1.0],[0,0],[0,0
.1]]])
>>> a
array([[[1. , 1.1],
        [1. , 1. ],
        [0. , 0. ],
        [0. , 0.1]],

       [[1. , 1.1],
        [1. , 1. ],
        [0. , 0. ],
        [0. , 0.1]]])
>>> a.shape
(2, 4, 2)

然后制定查询第几维的长度,就是指定查询shape结果的tuple中的数据,因此查询第一维数组的长度,使用

>>> a.shape[0]
2

tile函数

原型:numpy.tile(A,reps)

tile共有2个参数,A指待输入数组,reps则决定A重复的次数。整个函数用于重复数组A来构建新的数组。这里的reps参数可以是任意长度的tuple,依次标识构建的新数组,前面的数字分别代表构建的第几维数组的长度,最后一个数字指定A数组在最低维的重复次数。如:

>>> b=tile([0,1],(3,2))
>>> b
array([[0, 1, 0, 1],
       [0, 1, 0, 1],
       [0, 1, 0, 1]])
>>> b=tile([0,1],(3,1))
>>> b
array([[0, 1],
       [0, 1],
       [0, 1]])
>>> b=tile([0,1],(1,2))
>>> b
array([[0, 1, 0, 1]])
>>> b=tile([0,1],(3,2,3))
>>> b
array([[[0, 1, 0, 1, 0, 1],
        [0, 1, 0, 1, 0, 1]],

       [[0, 1, 0, 1, 0, 1],
        [0, 1, 0, 1, 0, 1]],

       [[0, 1, 0, 1, 0, 1],
        [0, 1, 0, 1, 0, 1]]])

数组运算

数组运算请参考高等代数中数组运算章节,不过numpy中的数组运算与高等代数中有一点区别,对缺失的维度会从第一行依次自动进行补全,然后进行加减运算,如:

>>> a=array([1,2,3,4])
>>> b=array([[2,3,4,5],[7,6,5,4]])
>>> b-a
array([[1, 1, 1, 1],
       [6, 4, 2, 0]])

sum函数

首先sum()是求和函数

>>> a=array([6,3,7])
>>> a.sum() #对数组进行求和
16

>>> a=array([[6,3,7],[2,3]])
>>> a.sum() #并没有求和,而是按照list对数组进行了打印
[6, 3, 7, 2, 3]

然后尝试在sum()中加入参数,如array.sum(axis=1)和array.sum(axis=1),axis的参数只允许为0或者1,其中axis=0, 表示对列求和,7 axis=1, 表示对行求和。

>>> a=array([[6,3,7],[2,3,4],[9,7,5]])
>>> a.sum()
46
>>> a.sum(axis=0)
array([17, 13, 16])
>>> a.sum(axis=1)
array([16,  9, 21])
>>> a.sum(axis=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Administrator\Anaconda3\lib\site-packages\numpy\core\_methods.p
y", line 36, in _sum
    return umr_sum(a, axis, dtype, out, keepdims, initial)
numpy.core._internal.AxisError: axis 3 is out of bounds for array of dimension 2

根据以上函数可以计算两个向量点之间的距离,数学过程见下图,
在这里插入图片描述

python实现代码如下:

from  numpy import *
import operator
def creatDateSet(): #导入已知类别数据集和分类结果
    group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels=['A','A','B','B']
    return group,labels
def classify0(inX,dataSet,labels,k):
    dataSetSize=dataSet.shape[0] #求已知样本的数组形状
    diffMat=tile(inX,(dataSetSize,1))-dataSet  #未知点与已知点的差向量集合
    sqDiffMat=diffMat**2 
    sqDistances=sqDiffMat.sum(axis=1) #对差向量矩阵的行求和
    distances=sqDistances**0.5 #求每个差向量的距离(欧式距离)
    return dataSetSize,diffMat,sqDiffMat,sqDistances,distances  #返回各变量的结果,打印计算过程
    
group,labels=creatDateSet() #调用已知类别数据集
a=classify0([0,0],group,labels,3) #调用K-近邻算法函数,并输入未知向量inX,及K值
print(a[4])

array([1.48660687, 1.41421356, 0.        , 0.1       ])

argsort函数

argsort函数返回的是数组值从小到大的索引值,如:

>>> a=array([1.48660687, 1.41421356, 0.        , 0.1       ])
>>> a.argsort()
array([2, 3, 1, 0], dtype=int64)

字典的使用

Python 字典(Dictionary) get() 函数返回指定键的值,如果值不在字典中返回默认值。

from  numpy import *
import operator
def creatDateSet():
    group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels=['A','A','B','B']
    return group,labels
def classify0(inX,dataSet,labels,k):
    dataSetSize=dataSet.shape[0]
    diffMat=tile(inX,(dataSetSize,1))-dataSet
    sqDiffMat=diffMat**2
    sqDistances
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个基于k-近邻算法进行SIFT特征点和路网数据中的道路特征点的图像匹配的Python代码示例: ```python import cv2 import numpy as np # 读取图像和路网数据 img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE) road_data = np.load('road_data.npy') # 初始化SIFT算法 sift = cv2.xfeatures2d.SIFT_create() # 提取图像中的SIFT特征点和描述符 kp1, des1 = sift.detectAndCompute(img, None) # 初始化k-近邻算法 flann_params = dict(algorithm=1, trees=5) flann = cv2.FlannBasedMatcher(flann_params, {}) # 匹配图像特征点和路网数据中的道路特征点 matches = flann.knnMatch(des1, road_data, k=2) # 选取最佳匹配 good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) # 获取匹配的特征点坐标 img_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) road_pts = np.float32([road_data[m.trainIdx] for m in good_matches]).reshape(-1, 1, 2) # 计算单应性矩阵 H, mask = cv2.findHomography(img_pts, road_pts, cv2.RANSAC, 5.0) # 应用单应性矩阵将图像映射到路网上 result = cv2.warpPerspective(img, H, (img.shape[1], img.shape[0])) # 显示结果 cv2.imshow('Result', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 其中,`image.jpg`是输入的图像文件,`road_data.npy`是路网数据文件,可以使用`np.load()`函数加载。在代码中,我们首先使用SIFT算法提取图像中的特征点和描述符,然后使用k-近邻算法匹配图像特征点和路网数据中的道路特征点。接着,我们选取最佳匹配,并使用`cv2.findHomography()`函数计算单应性矩阵。最后,我们将图像应用单应性矩阵映射到路网上,并显示结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值