我怎么知道我的 k-means 聚类算法正遭受维数灾难?

机器算法验证 聚类 k-均值 高维
2022-02-16 19:52:17

我相信这个问题的标题说明了一切。

2个回答

它有助于思考什么是维度的诅咒CV上有几个非常不错的主题值得一读。这是一个开始的地方: 向孩子解释“维度的诅咒”

我注意到您对这如何适用于k- 表示聚类。值得注意的是k-means 是一种最小化(仅)平方欧几里得距离的搜索策略。鉴于此,值得思考欧几里得距离与维度灾难的关系(请参阅:为什么欧几里得距离在高维中不是一个好的度量?)。

这些线程的简短回答是,空间的体积(大小)相对于维数以令人难以置信的速度增加。甚至10维度(对我来说似乎不是非常“高维度”)可以带来诅咒。如果您的数据在该空间中均匀分布,则所有对象彼此之间的距离大致相等。然而,正如@Anony-Mousse 在他对该问题的回答中指出的那样,这种现象取决于数据在空间内的排列方式;如果他们不统一,你不一定有这个问题。这就引出了均匀分布的高维数据是否非常普遍的问题(参见:“维度灾难”是否真的存在于真实数据中?)。

我认为重要的不一定是变量的数量(数据的字面维度),而是数据的有效维度。在假设下10尺寸“太高”k-意思是,最简单的策略是计算您拥有的功能数量。但是,如果您想考虑有效维度,您可以执行主成分分析 (PCA) 并查看特征值如何下降。大多数变化存在于几个维度中(通常跨越数据集的原始维度)是很常见的。这意味着您不太可能遇到问题k- 意味着您的有效维度实际上要小得多。

一个更复杂的方法是检查数据集中成对距离的分布,沿着@hxd1011 在他的回答中建议的行。查看简单的边际分布会给你一些可能的均匀性的暗示。如果您将所有变量归一化以位于区间内[0, 1], 成对距离必须在区间内[0, D]. 高度集中的距离会造成问题;另一方面,多模态分布可能是有希望的(您可以在我的回答中看到一个示例:如何在聚类中同时使用二元和连续变量?)。

然而,无论k-手段将“工作”仍然是一个复杂的问题。在您的数据中存在有意义的潜在分组的假设下,它们不一定存在于您的所有维度或最大化变化的构造维度(即主成分)中。集群可以在较低变化的维度中(请参阅:PCA 的示例,其中具有低变化的 PC 是“有用的”)。也就是说,您可以在您的几个维度上或在低变体 PC 上,在内部接近且在它们之间很好分离的点的集群,但在高变体 PC 上却不相似,这将导致k-意味着忽略您所追求的集群并选择人造集群(可以在此处看到一些示例:如何理解 K-means 的缺点)。

我的回答不限于 K 均值,而是检查我们是否对任何基于距离的方法都存在维度灾难。K-means 基于距离度量(例如,欧几里得距离)

在运行算法之前,我们可以检查距离度量分布,即所有数据对的所有距离度量。如果你有N数据点,你应该有0.5N(N1)距离度量。如果数据太大,我们可以检查一个样本。

如果我们遇到维度灾难问题,您会看到,这些值彼此非常接近。这似乎非常违反直觉,因为这意味着每个人都离每个人都近或远,而距离测量基本上是无用的。


这是一些模拟,可以向您展示这种违反直觉的结果。如果所有的特征都是均匀分布的,如果维度太多,每个距离度量都应该接近16,它来自xi=01xj=01(xixj)2dxidxj. 随意将均匀分布更改为其他分布。例如,如果我们更改为正态分布(更改runifrnorm),它将收敛到另一个具有大数维数的数。

这是维度从 1 到 500 的模拟,特征是从 0 到 1 的均匀分布。

plot(0, type="n",xlim=c(0,0.5),ylim=c(0,50))
abline(v=1/6,lty=2,col=2)
grid()

n_data=1e3
for (p in c(1:5,10,15,20,25,50,100,250,500)){
    x=matrix(runif(n_data*p),ncol=p)
    all_dist=as.vector(dist(x))^2/p
    lines(density(all_dist))
}

在此处输入图像描述