K 近邻算法(K-Nearest Neighbors,KNN)既可以处理分类问题,也可以处理回归问题。
KNN 是一种懒惰学习算法。
- 懒惰学习算法:指直到出现新的测试样本,该算法才开始依据训练样本进行样本的预测处理工作。
- 也就是说,该算法事先不会对训练样本进行任何处理,只会懒散地等待测试样本的到来,然后才开始工作。
懒惰学习算法构建的目标函数能够更近似测试样本数据本身,但同时它需要更大的存储空间用于存储训练样本数据。
- 懒惰学习算法非常适用于 具有较少特征属性 的 大型数据库 的问题。
KNN 算法原理
在训练集中,每个样本假设都是一个具有 个特征属性的向量,即 ,可看作每个样本在 维特征空间内分布。每个样本还有一个标签 。
目的是找到一个函数,使得 ,以确定新样本 的标签。
样本在 维特征空间内分布,可以找到样本间的一种“距离”,用于评估样本间的相似程度。
- 欧氏距离:(适用于特征属性是连续变量)
- 曼哈顿距离:(适用于特征属性是连续变量)
- 闵可夫斯基距离:(适用于特征属性是连续变量)
- 汉明距离:(适用于特征属性是离散变量)
KNN 的任务是在训练集中,依据距离找到与新样本(测试样本) 最相似的那 个训练样本。
- 若做分类问题,则多数表决,在 个训练样本中,哪个分类的样本数多,哪个分类就是 的预测分类。
- 若做回归问题, 的预测值 为:
在考虑训练集与测试样本之间距离大小的影响下,使得距离更小的样本具有更大的权值, 个最邻近样本中第 个样本 与测试样本 的权值定义为:
- 对于回归问题,预测结果 变成:
- 对于分类问题,最终分类结果为权值最大的类。
KNN 的 需要预先确定:
- 若值过大,会使特征空间内明确分类边界变得模糊;
- 若值过小,则引入误差。
常用 交叉验证法 选择 值。
- 把训练数据 分为 份,用其中的 份训练模型,把剩余的1份数据用于评估模型的质量。
基于OpenCV实现KNN
OpenCV 并没有采用交叉验证和距离权值的方法。
相关函数:
1 | // 创建模型 |
例子-小麦品种籽粒数据集
数据集地址:https://archive.ics.uci.edu/dataset/236/seeds
三种不同小麦品种籽粒几何特性的测定。数据集具有7个属性:
- 一个区域
- 周边P
- 紧性
- 核的长度
- 核的宽度
- 不对称系数
- 核槽长度
部分数据如下:
area | perimeter | compactness | length of kernel | width of kernel | asymmetry coefficient | length of kernel groove | class |
---|---|---|---|---|---|---|---|
15.26 | 14.84 | 0.871 | 5.763 | 3.312 | 2.221 | 5.22 | 1 |
14.88 | 14.57 | 0.8811 | 5.554 | 3.333 | 1.018 | 4.956 | 1 |
14.29 | 14.09 | 0.905 | 5.291 | 3.337 | 2.699 | 4.825 | 1 |
13.84 | 13.94 | 0.8955 | 5.324 | 3.379 | 2.259 | 4.805 | 1 |
16.14 | 14.99 | 0.9034 | 5.658 | 3.562 | 1.355 | 5.175 | 1 |
14.38 | 14.21 | 0.8951 | 5.386 | 3.312 | 2.462 | 4.956 | 1 |
12.74 | 13.67 | 0.8564 | 5.395 | 2.956 | 2.504 | 4.869 | 1 |
使用自实现 KNN 和 OpenCV 提供的 KNN 类进行训练计算,结果如下:
1 | Train Data imported: 150 |
代码及数据集地址:KNN - Gitee