了解维度灾难的插图吗?

机器算法验证 机器学习 高维
2022-03-24 21:51:44

在这篇被高度引用的文章中,当大多数特征都无关紧要时,我理解高维诅咒是如何起作用的:关于机器学习的一些有用的知识,但我一直在阅读下面的插图:

这是因为在高维中,所有示例看起来都相似。例如,假设示例布置在规则网格上,并考虑一个测试示例如果网格是 d 维的,的 2d 最近的示例都与它的距离相同。因此,随着维度的增加,越来越多的示例成为的最近邻,直到最近邻(因此类)的选择实际上是随机的xtxtxt

第一句话不直观特别是,如果网格是 d 维的,的 2d 最近的示例都在相同的距离xt

具体来说,二维平面中有两个坐标(A 和 B):

在此处输入图像描述 使用geogebra

假设 (0, 0) 是测试示例,我们可以看到 A 比 B 更接近它。我想知道在任何更高维空间中 B 是否会像 A 一样接近测试示例?如果是这样,怎么做?如果不是,那么所有样本看起来如何相似?

4个回答

让我们看看前几个维度。

  • 对于,如果示例布置在规则网格上,这仅意味着它们在直线上的距离相等,例如,在整数处。我们可以假设我们的测试示例 位于原点有两个距离相等的最近邻居,即处的点。d=1xtxt=0111

  • 对于,我们有一个平面,规则网格可以由所有二维整数点组成。对于在原点的测试示例(不失一般性),有四个最近的邻居,同样都是距离d=21(0,1)(1,0)(0,1)(1,0)

  • 对于,我们在三维空间中有一个规则网格。我们在原点的测试示例现在有六个最近的邻居,都在距离处。d=31

一般来说,由于我们有维并且可以假设我们的规则网格仅由维整数点组成,我们可以在原点处进行测试示例,然后我们可以通过选择最近邻尺寸并将该坐标设置为,并将所有其他坐标保留为dd2dd110

这说明的问题是,如果我们的问题中没有结构(即,我们的示例在规则网格上,没有集群,可能有一些噪声),那么选择固定数量最近邻居可能只是意味着在随机的,因为有这么多最近的邻居,可能只是因为噪声而被区分。k

特别是,如果网格是 d 维的,的 2d 最近的示例都在相同的距离xt谁能想象一下插图(如果可能的话)?

该示例涉及常规网格。

常规网格中,每条网格线(在每个维度上)都有两个相邻节点,一个在 +1,一个在 -1。

对于非正则分布,2d 最近的邻居不再处于完全相同的距离,并且存在一些随机性。但是规则网格的例子表明,有很多方向可以找到最近的邻居(这使得噪声更容易超过信号)。

我认为@Stephan Kolassa 很好地解释了作者在那段中的意思。“在高维情况下,所有样本看起来都相似”的理论基础在本文的第 3.4 节“不稳定性结果”中进行了阐述

基本上跳过第 6 页的证明

...所有点都收敛到距查询点相同的距离。因此在这些条件下,最近邻的概念不再有用。

我认为如果作者引用这篇论文而不是使用那个网格示例,演示文稿会更加清晰。更高维度的结果可能不直观,因为我们生活在一个 3D 世界中。

想象一下单位立方体所有训练数据都在这个立方体内均匀采样,即,我们正在考虑这样一个测试点的最近邻。[0,1]di,xi[0,1]dk=10

在此处输入图像描述

设 ℓ 是包含测试点的所有 k 最近邻的最小超立方体的边长。然后如果 n=1000,ℓ 有多大?dkn(kn)1/d

在此处输入图像描述

因此,当 d≫0 时,几乎需要整个空间来找到 10-NN。

为了模拟这种现象,我进行了以下实验(实现参考中的示例):

import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams.update({'figure.figsize':(7,5), 'figure.dpi':100})
import numpy as np
np.random.seed(0) 
from scipy.spatial import distance_matrix
min_val = 0
max_val = 1
n = 1000

for d in (2, 3, 10, 100, 1000, 10000):
    a = np.random.rand(n, d)
    b = np.random.rand(n, d)
    distances = distance_matrix(a, b)
    distances = np.array(distances).flatten()
    plt.hist(distances, bins=100, weights=np.ones(len(distances)) / len(distances))
    # plt.gca().set(title='Frequency Histogram', ylabel='Frequency')
    plt.show() 

并且这些图与参考中的图非常吻合。

参考:

  1. 第 2 讲:k-最近邻