ML:Scikit-Learn 学习笔记(1) --- Nearest Neighbors 最近邻 综述

Scikit-Learn 学习笔记(1) — Nearest Neighbors 最近邻 综述

1 前言

最近在做机器学习的作业,要用到Scilit-Learn这个东西,由于我这个人功利性比较明显,让我看那文档着实不爽,因为看了就过了。。所以我又来写博客了,发挥我这学期看到什么就写什么的热情。

这个笔记我想做成的形式就是挑选的翻译+理解的形式,所以真的是笔记哦

2 综述

在scikit-learn当中,最近邻的相关代码在 sklearn.neighbors 这里面,提供了有监督和无监督的最近邻学习方法。在机器学习中,无监督的最近邻思想是很多其他算法的重要基础,尤其是流行学习(manifold learning 链接1),和谱聚类(Spectral Clustering 链接),而有监督的最近邻则主要有如下两个用途:对离散标签的归类,和对具有连续标签(取值)的回归。

最近邻的核心思想是,对于需要预测的点(空间上的),找到和他距离最近的几个点,并根据这几个点的类别来对新的点做预测。关于这些点的数量,可以是用户自定义,因此就有了KNN(K-nearest neighbor learning),或者是基于当前点的密度来确定(基于半径的最近邻 radius-based neighbor learning)。另一个重要的话题是如何衡量点与点之间的距离,通常上说呢,几乎任何的方式都是可行的,不过一般来说,欧几里得距离也是最常用的(还有曼哈顿什么的哦)。基于最近邻思想的相关算法,都是不需要泛化的,因为他们每次都需要考虑所有的数据,也正因如此,为了加速,通常我们会使用一些额外的数据结构来加速,比如Ball-Tree和KD-Tree

尽管我们都觉得最近邻这个思想很简单,但实际是他也很粗暴,最近邻的相关算法适用于很多的分类和回归问题,例如我们常见的手写数字识别,或者卫星图像分类等。最近邻是一个不太需要参数的方法(原文是不需要,non-parametric,但我觉得至少指定几个邻居也算一个参数,不是么?),它特别适用于在一些没有规律、规则边界的素具当中。

在在scikit-learn当中,sklearn.neighbors 可以输入Numpy的数组数据,或者是scipy.sparse里的数据,对于稠密的矩阵,一大堆的可能的距离矩阵都是支持的,而对于稀疏矩阵,任何Minkowski矩阵都是可以用的。

3 无监督的最近邻

NearestNeighbors 里实现了无监督的最近邻学习,他为三种不同的学习算法(Ball-Tree,KD-Tree,还有基于sklearn.metrics.pairwise. 规则的brute-force)提供了统一的接口,需要使用哪种算法只需要设置参数时指定关键字‘algorithm’为[‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’] 其中的一种就好,当然,默认值是auto,在auto下,将会从你给定的测试数据当中选择最终性能最好的哪一个算法,对于算法的好坏,可以看看相关介绍。

对于最近邻里拥有相同距离的点,scikit-learn将会按照其顺序来选择使用

3.1 实战

这里将会给出一个简单的例子来:

>>> from sklearn.neighbors import NearestNeighbors
>>> import numpy as np
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
>>> nbrs = NearestNeighbors(n_neighbors=2, algorithm='ball_tree').fit(X)
>>> distances, indices = nbrs.kneighbors(X)
>>> indices                                           
array([[0, 1], [1, 0], [2, 1], [3, 4], [4, 3], [5, 4]]...)
>>> distances
array([[ 0. , 1. ], [ 0. , 1. ], [ 0. , 1.41421356], [ 0. , 1. ], [ 0. , 1. ], [ 0. , 1.41421356]])

对于上面的例子来说,又有一个关键字‘n_neighbors’ 可以指定K-NN里面的K的数量,而在上面里面,对于每个点,给了两个在训练集中最近的点,其中一个就是它本身了,所以最小的为0.

在程序里面,还可以将他输出成一个矩阵,标示连接关系

>>> nbrs.kneighbors_graph(X).toarray()
array([[ 1., 1., 0., 0., 0., 0.], [ 1., 1., 0., 0., 0., 0.], [ 0., 1., 1., 0., 0., 0.], [ 0., 0., 0., 1., 1., 0.], [ 0., 0., 0., 1., 1., 0.], [ 0., 0., 0., 0., 1., 1.]])

同时,正如之前所说的,我们还可以使用KD-Tree和Ball-Tree去寻找最近邻,对于这种情况,我想下面的代码就足以帮你理解了:

>>> from sklearn.neighbors import KDTree
>>> import numpy as np
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
>>> kdt = KDTree(X, leaf_size=30, metric='euclidean')
>>> kdt.query(X, k=2, return_distance=False)          
array([[0, 1], [1, 0], [2, 1], [3, 4], [4, 3], [5, 4]]...)

在这里KD-Tree和Ball-Tree其实有更多的可选参数,需要的话大家请上官方文档查看。

今天的内容就介绍到这里,随后更新基于最近邻的聚类、回归以及分析等的内容

附录

1、流形学习(manifold learning)综述
http://blog.csdn.net/chl033/article/details/6107042
2、 谱聚类(Spectral Clustering)
http://www.cnblogs.com/vivounicorn/archive/2012/02/10/2343377.html
本文官方文档地址:
http://scikit-learn.org/stable/modules/neighbors.html

你可能感兴趣的:(机器学习,分类,knn,scikit,最近邻)