KNN算法

一、KNN算法概述

kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

二、KNN算法介绍

最简单最初级的分类器是将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类。但是怎么可能所有测试对象都会找到与之完全匹配的训练对象呢,其次就是存在一个测试对象同时与多个训练对象匹配,导致一个训练对象被分到了多个类的问题,基于这些问题呢,就产生了KNN。 KNN是通过测量不同特征值之间的距离进行分类。它的的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。K通常是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 下面通过一个简单的例子说明一下:如下图,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。

由此也说明了KNN算法的结果很大程度取决于K的选择。
在KNN中,通过计算对象间距离来作为各个对象之间的非相似性指标,避免了对象之间的匹配问题,在这里距离一般使用欧氏距离或曼哈顿距离:

同时,KNN通过依据k个对象中占优的类别进行决策,而不是单一的对象类别决策。这两点就是KNN算法的优势。
接下来对KNN算法的思想总结一下:就是在训练集中数据和标签已知的情况下,输入测试数据,将测试数据的特征与训练集中对应的特征进行相互比较,找到训练集中与之最为相似的前K个数据,则该测试数据对应的类别就是K个数据中出现次数最多的那个分类,其算法的描述为:
1)计算测试数据与各个训练数据之间的距离;
2)按照距离的递增关系进行排序;
3)选取距离最小的K个点;
4)确定前K个点所在类别的出现频率;
5)返回前K个点中出现频率最高的类别作为测试数据的预测分类。

代码:
from numpy import *
class KnnClassifier(object):
def init(self,labels,samples):
“”" Initialize classifier with training data. “”
self.labels = labels
self.samples = sample
def classify(self,point,k=3):
“”" Classify a point against k nearest
in the training data, return label. “”"
# compute distance to all training points
dist = array([L2dist(point,s) for s in self.samples])
# sort them
ndx = dist.argsort()
# use dictionary to store the k nearest
votes = {}
for i in range(k):
label = self.labels[ndx[i]]
votes.setdefault(label,0)
votes[label] += 1
return max(votes, key=lambda x: votes.get(x))

def L2dist(p1,p2):
return sqrt( sum( (p1-p2)**2) )

def L1dist(v1,v2):
return sum(abs(v1-v2))

-- coding: utf-8 --
from numpy.random import randn
import pickle
from pylab import *

#create sample data of 2D points
n = 200
#two normal distributions
class_1 = 0.6 * randn(n, 2)
class_2 = 1.2 * 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’, ‘wb’) 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.6 * randn(n, 2)
r = 0.8 * randn(n, 1) + 5
angle = 2 * pi * randn(n, 1)
class_2 = hstack((r * cos(angle), r * sin(angle)))
labels = hstack((ones(n), -ones(n)))
#save with Pickle
#with open(‘points_ring.pkl’, ‘w’) as f:
with open(‘points_ring_test.pkl’, ‘wb’) as f:
pickle.dump(class_1, f)
pickle.dump(class_2, f)
pickle.dump(labels, f)

print(“save OK!”)

#-- coding: utf-8 --
import pickle
from pylab import *
from PCV.classifiers import knn
from PCV.tools import imtools

pklist=[‘points_normal.pkl’,‘points_ring.pkl’]

figure()

#load 2D points using Pickle
for i, pklfile in enumerate(pklist):
with open(pklfile, ‘rb’) as f:
class_1 = pickle.load(f)
class_2 = pickle.load(f)
labels = pickle.load(f)
# load test data using Pickle
with open(pklfile[:-4]+’_test.pkl’, ‘rb’) as f:
class_1 = pickle.load(f)
class_2 = pickle.load(f)
labels = pickle.load(f)
model = knn.KnnClassifier(labels,vstack((class_1,class_2)))
# test on the first point
print (model.classify(class_1[0]))
#define function for plotting
def classify(x,y,model=model):
return array([model.classify([xx,yy]) for (xx,yy) in zip(x,y)])
e classification boundary
subplot(1,2,i+1)
imtools.plot_2D_boundary([-6,6,-6,6],[class_1,class_2],classify,[1,-1])
titlename=pklfile[:-4]
title(titlename)
savefig(“test1.png”)
show()
实验结果:

稠密SIFT算法

一、原理

传统的SIFT算法即Sparse SIFT,不能很好地表征不同类之间的特征差异,达不到所需的分类要求。而Dense SIFT算法,是一种对输入图像进行分块处理,再进行SIFT运算的特征提取过程。Dense SIFT根据可调的参数大小,来适当满足不同分类任务下对图像的特征表征能力。
该算法首先将表达目标的矩形区域分成相同大小的矩形块,计算每一个小块的SIFT特征,再对各个小块的稠密SIFT特征在中心位置进行采样,建模目标的表达.然后度量两个图像区域的不相似性,先计算两个区域对应小块的Bhattacharyya距离,再对各距离加权求和作为两个区域间的距离.因为目标所在区域靠近边缘的部分可能受到背景像素的影响,而区域的内部则更一致,所以越靠近区域中心权函数的值越大.最后提出了能适应目标尺度变化的跟踪算法。
代码:
#-- coding: utf-8 --
from PCV.localdescriptors import dsift
import os
from PCV.localdescriptors import sift
from pylab import *
from PCV.classifiers import knn

def get_imagelist(path):
“”" Returns a list of filenames for
all jpg images in a directory. “”"
return [os.path.join(path,f) for f in os.listdir(path) if f.endswith(’.ppm’)]

def read_gesture_features_labels(path):
# create list of all files ending in .dsift
featlist = [os.path.join(path,f) for f in os.listdir(path) if f.endswith(’.dsift’)]
# read the features
features = []
for featfile in featlist:
l,d = sift.read_features_from_file(featfile)
features.append(d.flatten())
features = array(features)
# create labels
labels = [featfile.split(’/’)[-1][0] for featfile in featlist]
return features,array(labels)

def print_confusion(res,labels,classnames):
n = len(classnames)
# confusion matrix
class_ind = dict([(classnames[i],i) for i in range(n)])
confuse = zeros((n,n))
for i in range(len(test_labels)):
confuse[class_ind[res[i]],class_ind[test_labels[i]]] += 1
print (‘Confusion matrix for’)
print (classnames)
print (confuse)

filelist_train = get_imagelist(‘gesture/train’)
filelist_test = get_imagelist(‘gesture/test1’)
imlist=filelist_train+filelist_test

#process images at fixed size (50,50)
for filename in imlist:
featfile = filename[:-3]+‘dsift’
dsift.process_image_dsift(filename,featfile,10,5,resize=(50,50))

features,labels = read_gesture_features_labels(‘gesture/train/’)
test_features,test_labels = read_gesture_features_labels(‘gesture/test/’)
classnames = unique(labels)

#test kNN
k = 1
knn_classifier = knn.KnnClassifier(labels,features)
res = array([knn_classifier.classify(test_features[i],k) for i in
range(len(test_labels))])
#accuracy
acc = sum(1.0*(res==test_labels)) / len(test_labels)
print (‘Accuracy:’, acc)

print_confusion(res,test_labels,classnames)
实验结果:

实验总结:
在进行图片识别时,KNN算法对图片的识别敏感。
在训练集大的时,正确率可以达到80%左右。
在训练集小的时,正确率可以达到50%左右。
在静态手势数据库下,陌生场景下的手势正确率只能达到7%左右,但是保持稳定状态。
从一方面,说明训练集过小,容易造成数据过拟合的问题
从另一方面,对不是很明显的手势区别也可以判断,分类敏感。

计算机视觉--KNN算法和稠密SIFT实现图像识别(手势识别)相关推荐

  1. 计算机视觉——KNN算法以及手势识别应用

    文章目录 概述 KNN算法原理 KNN二维分类器模型 DSIFT 手势识别应用 手势识别具体流程 概述 本文介绍了KNN算法的基本原理,以及配合dfift(稠密sift)进行一个手势识别方面的应用 K ...

  2. 计算机视觉——KNN算法(k近邻)

    一.KNN算法是什么? k近邻算法是一种基本分类和回归方法. 简单来说,k近邻原理表示为,在给定一个训练集中,输入一个新数据,然后找寻新的输入实例在训练集中最邻近的k个实例.这个k个实例的多数属于某个 ...

  3. knn可视化、稠密dsift原理、手势识别

    一.knn可视化: 1.knn算法简单介绍: KNN是一种监督学习算法,通过计算新数据与训练数据特征值之间的距离,然后选取K(K>=1)个距离最近的邻居进行分类判(投票法)或者回归.若K=1,新 ...

  4. 基于KNN算法的图像识别

    你需要完成一个图像识别的任务,主要使用的模型是KNN算法.使用的数据集是cifar-10,是图像识别领域最为经典的数据及之一.具体的数据可以从以下的链接下载: https://www.cs.toron ...

  5. 十年之后,CV经典教材《计算机视觉:算法与应用》迎来第二版,初稿开放下载...

    击上方"3D视觉工坊",选择"星标" 干货第一时间送达 来源丨机器之心 你也在用<计算机视觉:算法与应用>入门 CV 吗?或许你手里的版本已经有点过 ...

  6. 教你用OpenCV实现机器学习最简单的k-NN算法

    前言:OpenCV 的构建是为了提供计算机视觉的通用基础接口,现在已经成为经典和最优秀的计算机视觉和机器学习的综合算法工具集.作为一个开源项目,研究者.商业用户和政府部门都可以轻松利用和修改现成的代码 ...

  7. 招聘|字节跳动招计算机视觉方向算法实习生

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 计算机视觉方向算法实习生 职位描述: 1.研究和开发图像.视频.文字识别领域的算法,并将算法落地应用: ...

  8. ML之kNN:k最近邻kNN算法的简介、应用、经典案例之详细攻略

    ML之kNN:k最近邻kNN算法的简介.应用.经典案例之详细攻略 目录 kNN算法的简介 1.kNN思路过程 1.1.k的意义 1.2.kNN求最近距离案例解释原理-通过实际案例,探究kNN思路过程 ...

  9. KNN算法与线性分类器

    一.图像识别 1.简单介绍 图像识别的核心问题:矩阵. 图像识别的任务就是给定图像即矩阵后,对矩阵去做图像识别,以得到一组概率,以此来判断图像的所属类别. 2.不足之处 图像识别的困难之处:准确率一直 ...

最新文章

  1. typescript索引类型_TypeScript类型声明书写详解
  2. 5月26 留言板练习题
  3. excel查找空值快捷键_Excel工资表怎么做?3分钟学会利用函数生成工资表
  4. vo listVO paggerHelper mapper使用原则
  5. Spring Boot2 整合 MyBatis 多数据源
  6. Windows核心思想-宽字符与窄字符(Unicode和ASCII)
  7. Zabbix3.2.6之通过JMX监控Tomcat
  8. q learning简单理解_班级励志标语格言-生活其实很简单,过了今天就是明天
  9. linux查进程内存问题,关于linux下内存问题排查的工具
  10. 【算法】希尔排序 推导方法
  11. redis-实现排行榜
  12. c语言boon类型函数,函数式编程functional programming的特点
  13. Jetson Nano 读取 GPS数据(TTL转 USB)
  14. 大学四年,学了这些计算机基础知识,成为了别人眼中的大神
  15. python中包的导入
  16. 跳房子(二维表上的搜索)
  17. 对话旷视CEO印奇:一文看尽他创业九年的思考
  18. Springboot+vue开发的图书借阅管理系统项目源码下载-P0029
  19. Android-MVP模式详解,一篇文章帮你解答
  20. 基于qt:五子棋游戏

热门文章

  1. OpenLayers标记地图点及点击地图点显示自定义弹出框
  2. C++开发短信验证码通知短信
  3. 纯CSS Material Design风格按钮
  4. 思科模拟器 --- 路由器RIP动态路由配置
  5. web前端期末大作业 魅力广西我的家乡介绍网页制作(HTML+CSS)
  6. 商业智能时代,大数据分析行业前景
  7. @ConfigurationProperties(prefix = “xx.xx.xx“)
  8. 字节跳动算法工程师总结:腾讯+字节+阿里面经真题汇总,含面试题+答案
  9. (一)软件开发背景 - 天津市政府采购中心网
  10. 舆情、网络舆情、舆情分析