sklearn:最近邻搜索sklearn.neighbors
http://blog.csdn.net/pipisorry/article/details/53156836
ball tree
k-d tree也有问题[最近邻查找算法kd-tree]。矩形并不是用到这里最好的方式。偏斜的数据集会造成我们想要保持树的平衡与保持区域的正方形特性的冲突。另外,矩形甚至是正方形并不是用在这里最完美的形状,由于它的角。如果图6中的圆再大一些,即黑点距离目标点点再远一些,圆就会与左上角的矩形相交,需要多检查一个区域的点,而且那个区域是当前区域双亲结点的兄弟结点的子结点。为了解决上面的问题,我们引入了ball tree。
ball tree
解决上面问题的方案就是使用超球面而不是超矩形划分区域。使用球面可能会造成球面间的重叠,但却没有关系。ball tree就是一个k维超球面来覆盖这些观测点,把它们放到树里面。图7(a)显示了一个2维平面包含16个观测实例的图,图7(b)是其对应的ball tree,其中结点中的数字表示包含的观测点数。
图 7 ball tree对二维平面的划分和ball tree
不同层次的圆被用不同的风格画出。树中的每个结点对应一个圆,结点的数字表示该区域保含的观测点数,但不一定就是图中该区域囊括的点数,因为有重叠的情况,并且一个观测点只能属于一个区域。实际的ball tree的结点保存圆心和半径。叶子结点保存它包含的观测点。
使用ball tree时,先自上而下找到包含target的叶子结点,从此结点中找到离它最近的观测点。这个距离就是最近邻的距离的上界。检查它的兄弟结点中是否包含比这个上界更小的观测点。方法是:如果目标点距离兄弟结点的圆心的距离大于这个圆的圆心加上前面的上界的值,则这个兄弟结点不可能包含所要的观测点。(如图8)否则,检查这个兄弟结点是否包含符合条件的观测点。
图 8 点与超圆
那么,ball tree的分割算法是什么呢?
选择一个距离当前圆心最远的观测点i1,和距离i1最远的观测点 i2,将圆中所有离这两个点最近的观测点都赋给这两个簇的中心,然后计算每一个簇的中心点和包含所有其所属观测点的最小半径。对包含n个观测点的超圆进行分割,只需要线性的时间。
与k-d tree一样,如果结点包含的观测点到达了预先设定的最小值,这个顶点就可以不再分割了。
kdtree和balltree的区别和联系
个人见解,
kd-tree基于欧氏距离的特性:
balltree基于更一般的距离特性:
因此:
kd-tree只能用于欧氏距离,并且处理高维数据效果不佳。
balltree在kd-tree能够处理的数据范围内要慢于kd-tree。
sklearn中使用kdtree和balltree
这个库的tree实现不太好,输入的数据会转换成ndarray,输出也是ndarray,这样就没办法传递附加数据了。。。也是烦人。。。
参数训练
KDTree(X, leaf_size=40, metric=’minkowski’, **kwargs)
BallTree(X, leaf_size=40, metric=’minkowski’, **kwargs)
参数解释
X : array-like, shape = [n_samples, n_features] 但也可以是dataframe类型(只要输入原始df数据的float类型的列(或者提前转换成)就可以)
leaf_size : positive integer (default = 40)
改变leaf_size不会改变查询结果,但是会显著影响查询速度(其实应该也包含训练速度吧)和存储内存。The amount of memory needed to store the tree scales as approximately n_samples / leaf_size.
metric : string or DistanceMetric object 用于树的距离度量:the distance metric to use for the tree. Default=’minkowski’with p=2 (that is, a euclidean metric). See the documentationof the DistanceMetric class for a list of available metrics.ball_tree.valid_metrics gives a list of the metrics whichare valid for BallTree.
查看可用的度量方法
from sklearn import neighbors
neighbors.KDTree.valid_metrics
['chebyshev',
'manhattan',
'infinity',
'p',
'l1',
'cityblock',
'euclidean',
'minkowski',
'l2']
[sklearn距离度量函数[sklearn.neighbors
.DistanceMetric¶]
近邻查找
query (X[, k, return_distance, dualtree, ...]) |
query the tree for the k nearest neighbors |
query_radius |
query_radius(self, X, r, count_only = False) |
Note:
1 query查询时返回的是距离和下标,下标对应的是输入的原始数据的下标,所以原始数据可以附加很多字段(只是不输入到树的构建数据中)就可以了。
2 lz测试时发现每次query查询时都会调用距离度量函数。
query
dist, inds = loc_kdtree.query(l_array[0].reshape(1, -1), k=5)
query返回值是距离(这里的数值就是metrics计算出来的那个数值)和samples的下标。
Note: 要注意的是index返回的是一个二维数组,第个一维数组元素对应的是一个查询的近邻结果。所以如果训练数据直接调用l_array[inds]返回的是一个三维数组,只查询一个二维数据的近邻时应该使用l_array[inds[0]]。
i : array of integers - shape: x.shape[:-1] + (k,). each entry gives the list of indices ofneighbors of the corresponding point.
query_radius半径查找
默认只返回index:ind = tree.query_radius(X[0], r=0.3)
count : if count_only == True
ind : if count_only == False and return_distance == False
(ind, dist) : if count_only == False and return_distance == True. 注意返回顺序还和query还不一样。。。
count : array of integers, shape = X.shape[:-1] each entry gives the number of neighbors withina distance r of the corresponding point.
其它参数及其含义
# variables to keep track of building & querying stats
cdef int n_trims
cdef int n_leaves
cdef int n_splits
cdef int n_calls
def get_tree_stats(self):
return (self.n_trims, self.n_leaves, self.n_splits)
def reset_n_calls(self):
self.n_calls = 0
def get_n_calls(self):
return self.n_calls
def get_arrays(self):
return (self.data_arr, self.idx_array_arr,
self.node_data_arr, self.node_bounds_arr)
[scikit-learn/sklearn/neighbors/binary_tree.pxi]
kdtree实现时的错误
还有一个坑就是sklearn版本问题,本地错误解决,放到服务器上远程跑还是出错,发现从0.18升级到0.18.1就不会报错了,也是醉了。。。
ValueError: metric PyFuncDistance is not valid for KDTree
The ball tree works with any of the following distance metrics, which match those found in the module scipy.spatial.distance:['euclidean', 'minkowski', 'manhattan', 'chebyshev', 'seuclidean', 'mahalanobis', 'wminkowski', 'hamming', 'canberra', 'braycurtis', 'matching', 'jaccard', 'dice', 'kulsinski', 'rogerstanimoto', 'russellrao', 'sokalmichener', 'sokalsneath', 'haversine']
Alternatively, the user can specify a callable Python function to act as the distance metric. While this will be quite a bit slower than using one of the optimized metrics above, it adds nice flexibility.
The kd-tree works with only the first four of the above metrics. This limitation is primarily because the distance bounds are less efficiently calculated for metrics which are not axis-aligned.
[Benchmarking Nearest Neighbor Searches in Python]
直接将metric写成一个函数会出错,因为metric参数接受的类型为:string or DistanceMetric object
loc_kdtree = neighbors.KDTree(l_array, metric=lambda i, j: distance.vincenty(tuple(i), tuple(j)).miles)
if callable(metric):
if algorithm == 'kd_tree':
# callable metric is only valid for brute force and ball_tree
raise ValueError(
"kd_tree algorithm does not support callable metric '%s'" % metric)
elif metric not in VALID_METRICS[alg_check]:
raise ValueError("Metric '%s' not valid for algorithm '%s'" % (metric, algorithm))
ValueError: func must be a callable taking two arrays
[Sklearn kNN usage with a user defined metric]
[Sklearn kNN usage with a user defined metric (again)]
[Sklearn kNN usage with a user defined metric]
TypeError: __init__() takes exactly 1 positional argument (0 given)
参数是func=lambda不是pyfunc=lambda
loc_kdtree = neighbors.KDTree(l_array, metric='pyfunc', func=lambda i, j: distance.vincenty(i, j).miles)
或者loc_kdtree = neighbors.KDTree(l_array, metric=neighbors.DistanceMetric.get_metric('pyfunc',func=lambda i, j: distance.vincenty(i, j).miles))
ValueError: Buffer has wrong number of dimensions (expected 2, got 1)
用于训练的数据应该是二维的,如果输入的是一维的列表什么的,可以在外面加一个[]号。
sklearn Deprecation Warning
Deprecation Warning: Passing 1d arrays as data is deprecated in 0.17 and will raise ValueError in 0.19
出错问题:
分类器分类预测时:clf.predict([1, 1])
最近邻查询时:kdtree.query(l_array[0])...
原因:输入的预测或者查询不是二维的而是一维的
解决:改成二维的:clf.predict([
[1, 1]
]), kdtree.query([l_array[0]])
Note: 这个warning有点坑啊,应该可以通过修复sklearn代码解决吧。
[Getting deprecation warning in Sklearn over 1d array, despite not having a 1D array]
最近邻查找的应用
[Is a kd-tree suitable for 4D space-time data (x,y,z,time)?]
[Datetime as a dimension in python KDTree]
from: http://blog.csdn.net/pipisorry/article/details/53156836
ref: [scikit-learn modules 1.6. Nearest Neighbors]
[scikit-learn/sklearn/neighbors/]
sklearn:最近邻搜索sklearn.neighbors的更多相关文章
- 统计学习方法——KD树最近邻搜索
李航老师书上的的算法说明没怎么看懂,看了网上的博客,悟出一套循环(建立好KD树以后的最近邻搜索),我想应该是这样的(例子是李航<统计学习算法>第三章56页:例3.3): 步骤 结点查询标记 ...
- 快速近似最近邻搜索库 FLANN - Fast Library for Approximate Nearest Neighbors
What is FLANN? FLANN is a library for performing fast approximate nearest neighbor searches in high ...
- Approximate Nearest Neighbors.接近最近邻搜索
(一):次优最近邻:http://en.wikipedia.org/wiki/Nearest_neighbor_search 有少量修改:如有疑问,请看链接原文.....1.Survey:Neares ...
- 【sklearn】from sklearn.extermals import joblib(保存模型和加载模型)
原创博文,转载请注明出处! sklearn中保存和加载模型的方法 1.载入模块 from sklearn.externals joblib. model = joblib. # -*- coding: ...
- 基于KD-Tree的最近邻搜索
目标:查询目标点附近的10个最近邻邻居. load fisheriris x = meas(:,:); figure(); g1=gscatter(x(:,),x(:,),species); %spe ...
- sklearn系列之 sklearn.svm.SVC详解
首先我们应该对SVM的参数有一个详细的认知: sklearn.svm.SVC 参数说明: 本身这个函数也是基于libsvm实现的,所以在参数设置上有很多相似的地方.(PS: libsvm中的二次规划问 ...
- PythonOpenCV:MLP用于最近邻搜索
一:简单C++版本的链接: http://blog.csdn.net/kaka20080622/article/details/9039749 OpenCV的ml模块实现了人工神经网络(Artific ...
- scikit-learning API
API参考 这是scikit学习的类和函数参考.有关详细信息,请参阅完整的用户指南,因为类和功能原始规格可能不足以给出其使用的完整指导. sklearn.base:基类和效用函数 所有估计器的基类. ...
- day-9 sklearn库和python自带库实现最近邻KNN算法
K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一.该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的 ...
随机推荐
- linux 基本使用命令
arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS / DMI ...
- [HEOI2015]小Z的房间
Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. ...
- codesforces 671D Roads in Yusland
Mayor of Yusland just won the lottery and decided to spent money on something good for town. For exa ...
- hdu 5119(2014北京)
题意: 随机选择一个数,如果后面有比他小的就进行交换,直到没有为止(算一轮).求多少轮后为递增序列 思路: 倒着找,如果有比经过的最小数大的,ans+1 #include <iostream&g ...
- Codeforces278E Tourists
来自FallDream的博客,未经允许,请勿转载,谢谢. 给定一张无向图,有点权,要支持单点修改点权和询问从一个点到另一个点不重复经过节点的路径上点权最小值的最小值. n,m<=10^5 考虑求 ...
- bzoj 1835: [ZJOI2010]基站选址
Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄 ...
- bzoj1073[SCOI2007]kshort
1073: [SCOI2007]kshort Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1483 Solved: 373[Submit][Sta ...
- 常用SQL Server命令(持续) | Commonly used SQL Server command list (Cont')
---------------------------------------------------- 1. 查看某数据库中某表详细信息 SP_HELP USE DB_NAME GO SP_HELP ...
- Unix文件系统的主要特点是什么?
1. 树型层次结构 2. 可安装拆卸的文件系统 3. 文件是无结构的字符流式文件 4. Unix文件系统吧外部设备和文件目录作为文件处理
- SSD:TensorFlow中的单次多重检测器
SSD:TensorFlow中的单次多重检测器 SSD Notebook 包含 SSD TensorFlow 的最小示例. 很快,就检测出了两个主要步骤:在图像上运行SSD网络,并使用通用算法(top ...