一:理论基础
k近邻算法的本质是将指定对象根据已知特征值分类。为了提高算法的可靠性,在实施时会取k个近邻点,这k个近邻点中属于哪个类的较多,然后就将当前待识别点划分为哪个类。为了方便判断,k值通常取奇数。
二:计算
k近邻算法在获取各个样本的特征值后,计算待识别样本的特征值与各个已知分类的样本特征值之间的距离,然后找出k个最近邻的样本,根据k个最近邻样本中占比最高的样本所属的类别来确定待识别样本的分类。
1:归一化
在计算与特征值的距离时要充分考虑不同参数之间的权值,一般情况下,需要对参数进行处理,使其所有参数具有相同的权值,而通常的做法就是进行数据归一化,使用该特征值除以所有特征值中的最大值(或者最大值与最小值的差)。
2:距离计算
距离计算方式有很多,在此列常见的两种:
1:用绝对值之和表示距离,即曼哈顿距离。
2:计算平方和的平方根,即欧氏距离。
三:opencv中k近邻模块的基本使用
先使用以下函数生成用于后续训练的空算法模型:
knn=cv2.ml.KNearest_create()
获得模型后,针对该模型数据进行训练,其语法格式如下:
knn.train(data,flage,label)
data:表示用于训练的原始数据
flage:训练数据排列格式,cv2.ml.ROW_SAMPLE:训练数据按行排列,即每条训练数据占一行,cv2.ml.COL_SAMPLE:训练数据按列排列,即每条训练数据占一列,训练时根据实际的数据情况进行选择其中的一种即可。
label:原始数据的标签
在训练完毕后,使用以下函数进行测试:
ret,results,neighbours,dist=knn.findNearest(testdata,k)
ret:标识位(一般不用管)
results:模型输出的测试数据的分类类型
neighbours:距测试数据最近的k个训练数据的标签
dist:距测试数据最近的k个训练数据与该测试数据的距离
如:有两组数据集,一组位于左下角,一组位于右下角,随机生成一个数组,判断该数组属于那个分组
import cv2
import numpy as np
import matplotlib.pyplot as plt
#在指定范围内生成两组数据集
rand1=np.random.randint(0,30,(20,2)).astype(np.float32)
rand2=np.random.randint(70,100,(20,2)).astype(np.float32)
traindata=np.vstack((rand1,rand2))
#生成两组数据集的标签
r1label=np.zeros((20,1)).astype(np.float32)
r2label=np.ones((20,1)).astype(np.float32)
trainlabel=np.vstack((r1label,r2label))
g=traindata[trainlabel.flatten()==0]
plt.scatter(g[:,0],g[:,1],80,"g","o")
b=traindata[trainlabel.flatten()==1]
plt.scatter(b[:,0],b[:,1],80,"b","s")
#在指定范围内随机生成一个数组
testdata=np.random.randint(0,100,(1,2)).astype(np.float32)
plt.scatter(testdata[:,0],testdata[:,1],80,"r","*")
knn=cv2.ml.KNearest_create()
knn.train(traindata,cv2.ml.ROW_SAMPLE,trainlabel)
ret,results,neighbours,dist=knn.findNearest(testdata,5)
print("当前随机数组的标签类型:",results)
print("距当前随机数组距离最近的5个随机数组的标签类型:",neighbours)
print("当前随机数组距离最近的5个随机数组的距离",dist)
plt.show()