一、基本介绍
(一)K邻近分类法(KNN)
- KNN算法在分类方法中,是属于简单且应用得最多的方法之一,它把要分类的对象与训练几种已知类标记的所有对象进行对比,并由k近邻对指派到哪个类进行投票。
- KNN算法简单来说,就是先设定一个k值,根据这个k值来划分近邻区域,区域中哪个类所划分到的个数多,就将这个元素分为这一类。但是在此之前,KNN算法需要一定数量的训练集来训练对对象特征的分类,这点和BP神经网络有点类似,举个例子,在做手写数字识别时,我们需要事先将大量的手写数字集导入并根据它进行训练,相当于一个学习的过程,程序训练结束后(学习结束后)对后续测试的数字有所“印象”,那么就根据这个“印象”来对数字进行分类。
- KNN算法虽然分类效果较好,但是也存在一些缺点:k值的选择会影响分类的性能,对于大训练集,搜索起来的速度慢,且算法的可并行性也很一般。
- 简单的分类过程:
(1)计算待分类数据和不同类中每一个数据的距离(欧氏或马氏)。
(2)选出最小的前K数据个距离,这里用到选择排序法。
(3)对比这前K个距离,找出K个数据中包含最多的是那个类的数据,即为待分类数据所在的类。
(二)稠密SIFT特征
- 要对图像进行分类,我们需要一个特征向量来表示一幅图像,我们之前所常用的为sift特征提取,这里我们会使用到另外一种——稠密SIFT特征向量,在整幅图像上用一个规则的网格应用SIFT描述子可以得到稠密SIFT的表示形式(方向梯度直方图)。
- dense sift即直接指定关键点位置和描述子采样区域,计算sift特征。
- 主要过程是:
(1)用一个patch在图像上以一定步长step滑动,代码中step=1,这个patch就是描述子采样区域,patch size是4bins4bins,bin size可以自己指定,代码中是3pixels3pixels。这里说的bin对应到《sift特征提取》中的第4步就是指子区域area。图中的bounding box是sift特征点的范围。
(2)计算每个像素点的梯度(同sparse sift),统计每个bin内的像素点在8个方向上的梯度直方图,这样就生成了448维的sift特征。
转载自:https://blog.csdn.net/langb2014/article/details/48738669
二、实验运行分析与结果
(一)简单二维数据分类
- 创建两个不同的二维点集,用不同的保存文件名运行两次,一次为points_normal.pkl,points_ring.pkl,一次为points_normal_test.pkl,points_ring_test.pkl,得到4个二维数据集文件,每个分布都有两个文件,一个用来训练,一个用来测试。
# -*- coding: utf-8 -*-
from numpy.random import randn
import pickle
from pylab import *
# create sample data of 2D points
n = 300
# two normal distributions
class_1 = 0.7 * randn(n,2)#随机生成300个二维的数组
class_2 = 1.4 * randn(n,2) + array([5,1])
labels = hstack((ones(n),-ones(n)))
# save with Pickle
#with open('points_normal.pkl', 'w') as f:
with open('points_normal_test.pkl', 'w') as f:
pickle.dump(class_1,f)
pickle.dump(class_2,f)
pickle.dump(labels,f)
# normal distribution and ring around it
print "save OK!"
class_1 = 0.7 * randn(n,2)
r = 0.8 * randn(n,1) + 5
angle =