k近邻法

模型

  • 使用的模型实际上对应于特征空间的划分.模型的三个基本要素:
    1.距离度量
    2. k值的选择
    3. 分类决策规则决定.
  • k值的选择:k值的选择,k如果选择的过小会导致过拟合,模型会变得复杂.
  • 思想脉络
  • 方法的流程简述:
    给定一个训练数据集,对于新的输入实例,在训练数据集中找到与之最临近的k个实例,这k个实例的多数属于某个类,

    就把实例分为这个类.
    这个算法没有显示的训练过程,应用的过程就是训练的过程

算法推导

  • 1 公式推导
    无显示的算法推导过程.
    要注意的是,不同的距离度量所确定的最近邻点是不同的
    欧式距离,曼哈顿距离,以及闵科夫斯基距离.
  • 2.算法实现方法
    一种是线性扫描,计算输入实例与每一个训练实例的距离,但是当训练集很大的时候,计算非常耗时.
    一种是利用特殊的结构存储训练数据.减少计算距离的次数的kd树方法.
  • kd树方法:
    减少搜索的计算量.
    我的理解就是先根据一个坐标轴的值,划分一个二叉树,然后遍历二叉树进行最小点的比较.找出距离最小的点.
    kd树的详细介绍:


    kd树是每个节点均为k维数值点的二叉树,每个节点代表一个超平面,朝平面垂直于当前划分维度的坐标轴,在该维度上将空间划分为两个部分,一部分在右子树,一部分在左子树.

编程实现

  • 0.自己编程实现,自己构造数据
# date&time:2018.05.23
# review :2018.09.21
# @author :Danny
import numpy as np
def create_data():
"""
return : the train and test data
"""
train_data=np.array([[1.0,1.1,1],[1.0,1.0,1],[0,0,-1],[0,0.1,-1]])
x_test=np.array([1,1])
return train_data,x_test def kNN(train_data,x_test,k):
"""
type train_data:np.array([[x,y,c]])
type k: the k values
return the label of x_test
"""
x=train_data[:,0:2]
label=train_data[:,2]
diff=x-x_test
distance=np.sqrt(np.sum(diff**2,axis=1))
sort_distance_index=distance.argsort() # 将距离按大小顺序提取下标index ,这样就可以利用下标取相对应的label值.
class_label_count={}
# start to voting the label
for i in range(k):
vote_label=label[sort_distance_index[i]]
if vote_label not in class_label_count: # 典型的字典计数办法.
class_label_count[vote_label]=0
class_label_count[vote_label]+=1
return max(class_label_count,key=class_label_count.get)  # 返回字典中values值最大所对应的key ,也就是需要找的class_label if __name__=="main":
train_data,x_test=create()
k=1
result_label=kNN(train_data,x_test,k)
print("the test_data label:{}".format(result_label))
  • 1.对于小数量集合的线性扫描的方法
"""
date&time :2018.05.23 不要浮躁,静下心来 慢慢学习.
@author:Peter and Danny kNN implement with kd_tree. in the first place ,follow the machine learning in action kNN algorithms,and comprehensions the principle.
"""
# classify function
from numpy import *
import operator
import os
def classify(inX,dataSet,labels,k):
"""
:param inX: vector to compare to existing dataset (1xN)
:param dataSet: size m data set of known vectors (NxM)
:param labels: data set labels (1xM vector)
:param k: number of neighbors to use for comparison (should be an odd number)
:return: sortedClassCount
"""
dataSetSize=dataSet.shape[0]
diffMat=tile(inX,(dataSetSize,1))-dataSet
sqDiffMat=diffMat**2
sqDistances=sqDiffMat.sum(axis=1)
Distance=sqDistances**0.5
sortedDistances=Distance.argsort() # return a distance elements index in sorted
classCount={} # define a dictionary
for i in range(k):
voteIlabel=labels[sortedDistances[i]] # don't how to extract the label
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0] # return the voting label # construct dataSet
def createDataSet():
"""
:return: the group and labels
"""
group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels=['A','A','B','B']
return group,labels if __name__=='__main__':
group,labels=createDataSet()
result=classify([1.0,1.2],group,labels,3)
print("the label :{}".format(result))
print("\n dating site with kNN \n")
the label :A
  • 还存在两个主要问题:
    1.K值在利用cross-validation的选择问题
    2.voting 方法的使用及编程实现.

kd树实现kNN

kd_tree实现

# kd 树的构建代码
def kd_tree(points,depth):
if len(points)==0:
return None
cutting_dim=depth%len(points[0]) # 切分的维度数
# 这一段构建代码不是很懂.
medium_index=len(points)//2
points.sort(key=itemgetter(cutting_dim))
node=Node(points[medium_index])
node.left=kd_tree(points[:medium_index],depth+1)
node.right=kd_tree(points[medium_index+1:],depth+1)
return node # 寻找最小坐标值点,利用递归 def findmin(n,depth,cutting_dim,min):
if min is None:
min=n.location
if n is None:
return min
current_cutting_dim=depth%len(min)
if n.location[cutting_dim]<min[cuting_dim]:
min=n.location
if cutting_dim==current_cutting_dim:
return findmin(n.left,depth+1,cutting_dim,min)
else:
leftmin=findmin(n.left,depth+1,cutting_dim,min)
rightmin=findmin(n.right,depth+1,cutting_dim,min)
if leftmin[cutting_dim]>rightmin[cutting_dim]:
return rightmin
else:
return leftmin

k近邻法的实现的更多相关文章

  1. 学习笔记——k近邻法

    对新的输入实例,在训练数据集中找到与该实例最邻近的\(k\)个实例,这\(k\)个实例的多数属于某个类,就把该输入实例分给这个类. \(k\) 近邻法(\(k\)-nearest neighbor, ...

  2. 统计学习方法三:K近邻

    一.什么是K近邻? K近邻是一种基本的分类和回归方法. 在分类时,对新的实例,根据其K个最近邻的训练实例的类别,通过多数表决权等方式预测其类别. 通俗的讲,找K个和其关系最近的邻居,哪个类别的邻居多, ...

  3. 《统计学习方法》笔记三 k近邻法

    本系列笔记内容参考来源为李航<统计学习方法> k近邻是一种基本分类与回归方法,书中只讨论分类情况.输入为实例的特征向量,输出为实例的类别.k值的选择.距离度量及分类决策规则是k近邻法的三个 ...

  4. K近邻法(KNN)原理小结

    K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用.比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出 ...

  5. k临近法的实现:kd树

    # coding:utf-8 import numpy as np import matplotlib.pyplot as plt T = [[2, 3], [5, 4], [9, 6], [4, 7 ...

  6. 从K近邻算法谈到KD树、SIFT+BBF算法

    转自 http://blog.csdn.net/v_july_v/article/details/8203674 ,感谢july的辛勤劳动 前言 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章 ...

  7. 机器学习03:K近邻算法

    本文来自同步博客. P.S. 不知道怎么显示数学公式以及排版文章.所以如果觉得文章下面格式乱的话请自行跳转到上述链接.后续我将不再对数学公式进行截图,毕竟行内公式截图的话排版会很乱.看原博客地址会有更 ...

  8. <转>从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    转自 http://blog.csdn.net/likika2012/article/details/39619687 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章待写:1.KD树:2.神经 ...

  9. 机器学习 Python实践-K近邻算法

    机器学习K近邻算法的实现主要是参考<机器学习实战>这本书. 一.K近邻(KNN)算法 K最近邻(k-Nearest Neighbour,KNN)分类算法,理解的思路是:如果一个样本在特征空 ...

随机推荐

  1. win7 磁盘碎片整理

    最近每天早上开机,都出现开机正常,但是所有软件都没法点开,性能特别差: 咨询了运维小伙伴,提示可以整理下电脑磁盘碎片试试.那么如何整理呢,如下详细说明 1.先整理C盘,打开我的电脑,在C盘上,右击-- ...

  2. Gridea+GitHub搭建个人博客

    某日闲余时间看到一篇介绍Gridea博客平台的文章,大概看了一下觉得此平台还不错,随即自己进入Gridea官网瞅了瞅.哇,这搭建过程也太简单了吧,比Hexo博客搭建要容易很多,而且还有后台管理客户端, ...

  3. cesium学习——cesium中的坐标

    一.坐标展现形式 在cesium中,对于坐标数值单位有三种:角度.弧度和坐标值 1.角度 角度就是我们所熟悉的经纬度,对于地球的坐标建立如下: 图中以本初子午线作为x和z的面,建立了一个空间坐标系.可 ...

  4. 【kafka】一、消息队列

    在高并发的应用场景中,由于来不及同步处理请求,接收到的请求往往会发生阻塞.例如,大量的插入.更新请求同时到达数据库,这会导致行或表被锁住,最后会因为请求堆积过多而触发“连接数过多的异常” 的错误.因此 ...

  5. JS 中构造函数和普通函数的区别

    原来只是随意的了解了下 , 但是最近有点忘了 于是详细了解下 加深下印象. 1.构造函数也是一个普通函数,创建方式和普通函数一样,但构造函数习惯上首字母大写 2.构造函数和普通函数的区别在于:调用方式 ...

  6. 【Java例题】5.5 两个字符串中最长公共子串

    5. 查找两个字符串中含有的最长字符数的公共子串. package chapter5; import java.util.Scanner; public class demo5 { public st ...

  7. [Spring cloud 一步步实现广告系统] 15. 使用开源组件监听Binlog 实现增量索引准备

    MySQL Binlog简介 什么是binlog? 一个二进制日志,用来记录对数据发生或潜在发生更改的SQL语句,并以而进行的形式保存在磁盘中. binlog 的作用? 最主要有3个用途: 数据复制( ...

  8. Java中只有值传递,(及值传递与引用传递详解)

    首先呢,我们来说一下值传递与引用传递的区别(这两个玩意儿实在调用函数的时候提到的) 比如说 code( a) code( int a ) code(a)是调用函数,a是我们原本函数的一个值类型,然后使 ...

  9. zookeeper中的分布式一致性协议

    1. zookeeper中的一致性协议-ZAB协议 在深入了解ZK之前,相信很多同学都会认为ZK就是Paxos算法的一个实现.但事实上,ZK并没有完全采用Paxos算法,而是使用了一种称为ZooKee ...

  10. centos虚拟机配置静态ip

    昨天在配置虚拟机的时候因为之前没有设置静态IP,而是使用DHCP动态分配的,导致关机后下次开机虚拟机的ip是随机变动的.严重影响了工作体验啊,遂设置静态ip以保全! 虚拟机使用的是CentOS6.5, ...