提交 d9d8a024 编写于 作者: H Hanmin Qin 提交者: loopyme

1.6 最近邻 (0.21.3)

上级 8b361893
......@@ -5,12 +5,13 @@
        [@Veyron C](https://github.com/caopeirui)
        [@舞空](https://github.com/pan8664716)
        [@Loopy](https://github.com/loopyme)
[@qinhanmin2014](https://github.com/qinhanmin2014)
翻译者:
        [@那伊抹微笑](https://github.com/wangyangting)
[`sklearn.neighbors`](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.neighbors) 提供了 neighbors-based (基于邻居的) 无监督学习以及监督学习方法的功能。 无监督的最近邻是许多其它学习方法的基础,尤其是 manifold learning (流学习) 和 spectral clustering (谱聚类)。 neighbors-based (基于邻居的) 监督学习分为两种: [classification](#162-最近邻分类) (分类)针对的是具有离散标签的数据,[regression](#163-最近邻回归) (回归)针对的是具有连续标签的数据。
[`sklearn.neighbors`](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.neighbors) 提供了 neighbors-based (基于邻居的) 无监督学习以及监督学习方法的功能。 无监督的最近邻是许多其它学习方法的基础,尤其是 manifold learning (流学习) 和 spectral clustering (谱聚类)。 neighbors-based (基于邻居的) 监督学习分为两种: [classification](#162-最近邻分类) (分类)针对的是具有离散标签的数据,[regression](#163-最近邻回归) (回归)针对的是具有连续标签的数据。
最近邻方法背后的原理是从训练样本中找到与新点在距离上最近的预定数量的几个点,然后从这些点中预测标签。 这些点的数量可以是用户自定义的常量(K-最近邻学习), 也可以根据不同的点的局部密度(基于半径的最近邻学习)。距离通常可以通过任何度量来衡量: standard Euclidean distance(标准欧式距离)是最常见的选择。Neighbors-based(基于邻居的)方法被称为 *非泛化* 机器学习方法, 因为它们只是简单地”记住”了其所有的训练数据(可能转换为一个快速索引结构,如 [Ball Tree](#1643-ball-树)[KD Tree](#1642-k-d-树))。
最近邻方法背后的原理是从训练样本中找到与新点在距离上最近的预定数量的几个点,然后从这些点中预测标签。 这些点的数量可以是用户自定义的常量(K-最近邻学习), 也可以根据不同的点的局部密度(基于半径的最近邻学习)确定。距离通常可以通过任何度量来衡量: standard Euclidean distance(标准欧式距离)是最常见的选择。Neighbors-based(基于邻居的)方法被称为 *非泛化* 机器学习方法, 因为它们只是简单地”记住”了其所有的训练数据(可能转换为一个快速索引结构,如 [Ball Tree](#1643-ball-树)[KD Tree](#1642-k-d-树))。
尽管它简单,但最近邻算法已经成功地适用于很多的分类和回归问题,例如手写数字或卫星图像的场景。 作为一个 non-parametric(非参数化)方法,它经常成功地应用于决策边界非常不规则的分类情景下。
......@@ -20,7 +21,7 @@
## 1.6.1. 无监督最近邻
[`NearestNeighbors`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.NearestNeighbors.html#sklearn.neighbors.NearestNeighbors "sklearn.neighbors.NearestNeighbors") (最近邻)实现了 unsupervised nearest neighbors learning(无监督的最近邻学习)。 它为三种不同的最近邻算法提供统一的接口:[`BallTree`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.BallTree.html#sklearn.neighbors.BallTree "sklearn.neighbors.BallTree"), [`KDTree`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html#sklearn.neighbors.KDTree "sklearn.neighbors.KDTree"), 还有基于 [`sklearn.metrics.pairwise`](classes.html#module-sklearn.metrics.pairwise "sklearn.metrics.pairwise") 的 brute-force 算法。算法的选择可通过关键字 `'algorithm'` 来控制, 并必须是 `['auto', 'ball_tree', 'kd_tree', 'brute']` 其中的一个。当默认值设置为 `'auto'` 时,算法会尝试从训练数据中确定最佳方法。有关上述每个选项的优缺点,参见 [`Nearest Neighbor Algorithms`_](#id11)
[`NearestNeighbors`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.NearestNeighbors.html#sklearn.neighbors.NearestNeighbors "sklearn.neighbors.NearestNeighbors") (最近邻)实现了 unsupervised nearest neighbors learning(无监督的最近邻学习)。 它为三种不同的最近邻算法提供统一的接口:[`BallTree`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.BallTree.html#sklearn.neighbors.BallTree "sklearn.neighbors.BallTree"), [`KDTree`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html#sklearn.neighbors.KDTree "sklearn.neighbors.KDTree"), 还有基于 [`sklearn.metrics.pairwise`](classes.html#module-sklearn.metrics.pairwise "sklearn.metrics.pairwise") 的 brute-force 算法。算法的选择可通过关键字 `'algorithm'` 来控制, 并必须是 `['auto', 'ball_tree', 'kd_tree', 'brute']` 其中的一个。当设置为默认值 `'auto'` 时,算法会尝试从训练数据中确定最佳方法。有关上述每个选项的优缺点,参见 [`Nearest Neighbor Algorithms`_](#id11)
> **警告**
>
......@@ -153,7 +154,7 @@ scikit-learn 实现了两种不同的最近邻回归:[`KNeighborsRegressor`](h
### 1.6.4.3. Ball 树
为了解决 KD 树在高维上效率低下的问题, *ball 树* 数据结构就被研发出来了. 其中 KD 树沿卡迪尔轴(即坐标轴)分割数据, ball 树在沿着一系列的 hyper-spheres 来分割数据. 通过这种方法构建的树要比 KD 树消耗更多的时间, 但是这种数据结构对于高结构化的数据是非常有效的, 即使在高维度上也是一样.
为了解决 KD 树在高维上效率低下的问题, *ball 树* 数据结构就被研发出来了. 其中 KD 树沿笛卡尔轴(即坐标轴)分割数据, ball 树在沿着一系列的 hyper-spheres 来分割数据. 通过这种方法构建的树要比 KD 树消耗更多的时间, 但是这种数据结构对于高结构化的数据是非常有效的, 即使在高维度上也是一样.
ball 树将数据递归地划分为由质心 C 和半径 R 定义的节点,使得节点中的每个点位于由 ![r](img/451ef7ed1a14a6cdc38324c8a5c7c683.jpg) 和 ![C](img/4b6d782a67ac392e97215c46b7590bf7.jpg) 定义的 hyper-sphere 内. 通过使用 *triangle inequality(三角不等式)* 减少近邻搜索的候选点数:
......@@ -177,9 +178,7 @@ ball 树将数据递归地划分为由质心 C 和半径 R 定义的节点,使
* KD tree 的查询时间 的变化是很难精确描述的.对于较小的 ![D](img/e03066df748abd9273db055cb79f0f01.jpg) (小于20) 的成本大约是 ![O[D\log(N)]](img/f211ed45608192b0763ed51c85b60811.jpg), 并且 KD 树更加有效.对于较大的 ![D](img/e03066df748abd9273db055cb79f0f01.jpg) 成本的增加接近 ![O[DN]](img/c5b0e465d16add1d02594ec434515c04.jpg), 由于树结构引起的开销会导致查询效率比暴力还要低.
对于小数据集 (n小于30), log(N)相当于N, 暴力算法比基于树的算法更加有效. [`KDTree`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html#sklearn.neighbors.KDTree "sklearn.neighbors.KDTree") 和 [`BallTree`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.BallTree.html#sklearn.neighbors.BallTree "sklearn.neighbors.BallTree") 通过提供一个 *leaf size* 参数来解决这个问题:
这控制了查询切换到暴力计算样本数量. 使得两种算法的效率都能接近于对较小的 ![N](img/a44a7c045f2217894a894c482861387a.jpg) 的暴力计算的效率.
对于小数据集 (n小于30), log(N)相当于N, 暴力算法比基于树的算法更加有效. [`KDTree`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html#sklearn.neighbors.KDTree "sklearn.neighbors.KDTree") 和 [`BallTree`](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.BallTree.html#sklearn.neighbors.BallTree "sklearn.neighbors.BallTree") 通过提供一个 *leaf size* 参数来解决这个问题: 这控制了查询切换到暴力计算样本数量. 使得两种算法对较小的 ![N](img/a44a7c045f2217894a894c482861387a.jpg)的效率都能接近于暴力计算.
* 数据结构: 数据的 *intrinsic dimensionality* (本征维数) 和/或数据的 *sparsity* (稀疏度). 本征维数是指数据所在的流形的维数 ![d \le D](img/20310556eb1fb84146ff2584e166fd9c.jpg), 在参数空间可以是线性或非线性的. 稀疏度指的是数据填充参数空间的程度(这与“稀疏”矩阵中使用的概念不同, 数据矩阵可能没有零项, 但是从这个意义上来讲,它的 **structure** 仍然是 “稀疏” 的)。
......@@ -197,13 +196,11 @@ ball 树将数据递归地划分为由质心 C 和半径 R 定义的节点,使
* query points(查询点)数. ball tree 和 KD Tree 都需要一个构建阶段. 在许多查询中分摊时,这种结构的成本可以忽略不计。 如果只执行少量的查询, 可是构建成本却占总成本的很大一部分. 如果仅需查询很少的点, 暴力方法会比基于树的方法更好.
一般地, `algorithm = 'auto'` 选择 `'kd_tree'` 如果 ![k < N/2](img/f8f807bd22e1f9f3c4271c78c8cb33fa.jpg) 并且 `'effective_metric_'``'kd_tree'` 的列表 `'VALID_METRICS'` 中. 它选择 `'ball_tree'` 如果 ![k < N/2](img/f8f807bd22e1f9f3c4271c78c8cb33fa.jpg) 并且 `'effective_metric_'``'ball_tree'` 的列表 `'VALID_METRICS'` 中. 它选择 `'brute'` 如果 ![k < N/2](img/f8f807bd22e1f9f3c4271c78c8cb33fa.jpg) 并且 `'effective_metric_'` 不在 `'kd_tree'``'ball_tree'` 的列表 `'VALID_METRICS'` 中. 它选择 `'brute'` 如果 ![k >= N/2](img/bdc1e4261347e1c74950e91fa4f2230f.jpg).
这种选择基于以下假设: 查询点的数量与训练点的数量至少在相同的数量级, 并且 `leaf_size` 接近其默认值 `30`.
一般地, 如果 ![k >= N/2](img/bdc1e4261347e1c74950e91fa4f2230f.jpg), 或输入是稀疏矩阵,或`'effective_metric_'` 不在 `'kd_tree'``'ball_tree'``'VALID_METRICS'` 列表中,那么`algorithm = 'auto'`选择 `'brute'`。 如果 ![k < N/2](img/f8f807bd22e1f9f3c4271c78c8cb33fa.jpg) 并且 `'effective_metric_'``'kd_tree'``'VALID_METRICS'` 列表中,那么 `algorithm = 'auto'`选择 `'kd_tree'`。 如果 ![k < N/2](img/f8f807bd22e1f9f3c4271c78c8cb33fa.jpg) 并且 `'effective_metric_'``'ball_tree'``'VALID_METRICS'` 列表中,那么 `algorithm = 'auto'`选择 `'ball_tree'`。 这种选择基于以下假设: 查询点的数量与训练点的数量至少在相同的数量级, 并且 `leaf_size` 接近其默认值 `30`.
### 1.6.4.5. `leaf_size` 的影响
如上所述, 对于小样本暴力搜索是比基于数的搜索更有效的方法. 这一事实在 ball 树和 KD 树中被解释为在叶节点内部切换到蛮力搜索. 该开关的级别可以使用参数 `leaf_size` 来指定. 这个参数选择有很多的效果:
如上所述, 对于小样本暴力搜索是比基于树的搜索更有效的方法. 这一事实在 ball 树和 KD 树中被解释为在叶节点内部切换到暴力搜索. 该开关的级别可以使用参数 `leaf_size` 来指定. 这个参数选择有很多的效果:
**构造时间**: 更大的 `leaf_size` 会导致更快的树构建时间, 因为需要创建更少的节点.
......@@ -246,6 +243,8 @@ NearestCentroid(metric='euclidean', shrink_threshold=None)
邻域成分分析(NCA, [NeighborhoodComponentsAnalysis](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.NeighborhoodComponentsAnalysis.html#sklearn.neighbors.NeighborhoodComponentsAnalysis))是一种距离度量学习算法,其目的是提高最近邻分类相对于标准欧氏距离的准确性。该算法直接最大化训练集上k近邻(KNN)得分的随机变量,还可以拟合数据的低维线性投影,用于数据可视化和快速分类。
[![1_6_1](img/1_6_1.png)](https://scikit-learn.org/stable/auto_examples/neighbors/plot_nca_illustration.html) [![1_6_2](img/1_6_2.png)](https://scikit-learn.org/stable/auto_examples/neighbors/plot_nca_illustration.html)
在上图中,我们考虑随机生成的数据集中的一些点。重点研究了3号样本点的随机KNN分类问题.样本3和另一个点之间的链路厚度与它们之间的距离成正比,可以看作是随机最近邻预测规则分配给该点的相对权重(或概率)。在原始空间中,样本3有许多来自不同类的随机邻居,因此正确的分类不太可能。然而,在NCA学习的投影空间中,唯一权重不可忽略的随机邻域与样本3属于同一类,保证了样本3的分类良好。有关详细信息,请参阅[数学公式]()。
#### 1.6.6.1. 分类
......@@ -277,10 +276,10 @@ Pipeline(...)
[![sphx_glr_plot_nca_classification_0021.png](img/sphx_glr_plot_nca_classification_0021.png)](https://scikit-learn.org/stable/auto_examples/neighbors/plot_nca_classification.html)
图中仅对虹膜数据集上的两个特征进行训练和评分,显示最近邻分类和邻域成分分析分类的决策边界,可以直观的看到差异。
图中仅对鸢尾花数据集上的两个特征进行训练和评分,显示最近邻分类和邻域成分分析分类的决策边界,可以直观的看到差异。
#### 1.6.6.2. 降维
NCA可用于进行监督降维。输入数据被投影到一个由最小化NCA目标的方向组成的线性子空间上。可以使用参数`n_components`设置所需的维数。例如,下图显示了主成分分析的降维([sklearn.decomposition.PCA](https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html#sklearn.decomposition.PCA)),线性判别分析([sklearn.discriminant_analysis.LinearDiscriminantAnalysis](https://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html#sklearn.discriminant_analysis.LinearDiscriminantAnalysis))和社区成分分析([NeighborhoodComponentsAnalysis](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.NeighborhoodComponentsAnalysis.html#sklearn.neighbors.NeighborhoodComponentsAnalysis))在一个64个特征,1797个样本的数字数据集的降维结果。数据集被划分为大小相同的训练集和测试集,然后进行标准化。为了评价该方法的分类精度,对每种方法找到的二维投影点进行了3-最近邻分类精度的计算。每个数据样本属于10个类中的一个。
NCA可用于进行监督降维。输入数据被投影到一个由最小化NCA目标的方向组成的线性子空间上。可以使用参数`n_components`设置所需的维数。例如,下图显示了主成分分析的降维([sklearn.decomposition.PCA](https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html#sklearn.decomposition.PCA)),线性判别分析([sklearn.discriminant_analysis.LinearDiscriminantAnalysis](https://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html#sklearn.discriminant_analysis.LinearDiscriminantAnalysis))和邻域成分分析([NeighborhoodComponentsAnalysis](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.NeighborhoodComponentsAnalysis.html#sklearn.neighbors.NeighborhoodComponentsAnalysis))在一个64个特征,1797个样本的数字数据集的降维结果。数据集被划分为大小相同的训练集和测试集,然后进行标准化。为了评价该方法的分类精度,对每种方法找到的二维投影点进行了3-最近邻分类精度的计算。每个数据样本属于10个类中的一个。
[![sphx_glr_plot_nca_dim_reduction_0011.png](img/sphx_glr_plot_nca_dim_reduction_0011.png)](https://scikit-learn.org/stable/auto_examples/neighbors/plot_nca_dim_reduction.html)
[![sphx_glr_plot_nca_dim_reduction_0021.png](img/sphx_glr_plot_nca_dim_reduction_0021.png)](https://scikit-learn.org/stable/auto_examples/neighbors/plot_nca_dim_reduction.html)
......@@ -323,11 +322,11 @@ NCA可以看作是拟合一个(平方)Mahalanobis距离矩阵:
#### 1.6.6.5 复杂度
##### 1.6.6.5.1 训练
NCA存储一对距离矩阵,占用了(n_samples ** 2)的内存。时间复杂度取决于优化算法的迭代次数。但是,可以使用参数`max_iter`设置迭代的最大次数。对于每个迭代,时间复杂度为O(n_components x n_samples x min(n_samples, n_features))
NCA存储一对距离矩阵,占用了(n_samples ** 2)的内存。时间复杂度取决于优化算法的迭代次数。但是,可以使用参数`max_iter`设置迭代的最大次数。对于每个迭代,时间复杂度为`O(n_components x n_samples x min(n_samples, n_features))`
##### 1.6.6.5.2 变形
这里变形操作返回值为LX<sup>T</sup>,因此它的时间复杂度等于n_components x n_features x n_samples_test。操作中没有增加空间复杂度。
这里变形操作返回值为LX<sup>T</sup>,因此它的时间复杂度等于`n_components x n_features x n_samples_test`。操作中没有增加空间复杂度。
> **参考资料**:
>* [1] [“Neighbourhood Components Analysis”. Advances in Neural Information”](http://www.cs.nyu.edu/~roweis/papers/ncanips.pdf), J. Goldberger, G. Hinton, S. Roweis, R. Salakhutdinov, Advances in Neural Information Processing Systems, Vol. 17, May 2005, pp. 513-520.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册