从候选列表中找到最佳 k-means

Posted

技术标签:

【中文标题】从候选列表中找到最佳 k-means【英文标题】:find best k-means from a list of candidates 【发布时间】:2021-02-08 13:32:59 【问题描述】:

我有一个大小为 n 的点数组,称为 A,还有一个大小为 O(k)>k 的候选数组,称为 S。我想在 S 中找到 k 个点,使得到 A 的点的距离平方和从 k 个点到它们最近的点将被最小化。一种方法是检查 S 中任何可能的 k 点的成本并取最小值,但这需要 O(k^k*n) 时间,有没有更有效的方法来做到这一点?

我需要一个最优解或一个常数近似值。

我需要这个的原因是我试图尽可能快地找到 k-means 的常数近似值,然后将其用于核心集构造(核心集 = 数据最小化,同时仍然保持任何查询的成本大约相同)。我能够证明,如果我们假设在最优聚类中每个聚类都有 omega(n/k) 点,我们可以非常快速地创建一个大小为 O(k) 的候选者列表,其中包含 k 的 3 近似值-意思是,所以我想知道我们是否可以及时找到那些 k 点或它们的成本的常数近似值,这比穷举搜索要快。

k=2 的示例 在此示例中,S 是绿点,A 是红点。该算法应返回 S 中的 2 个圆圈点,因为它们最小化了从 A 的点到 2 的最近点的距离平方和。

【问题讨论】:

"和一个大小为 O(k)>k 的候选数组称为 S" 我假设你想写类似 "K > k" 而不是 "O(k) > k" @Stef 我的意思是 K>k,但也是 K=O(k)。 @Elliott 不,它们是高维的。 您当前的公式意味着如果 A 中的所有 n 点在 S 中具有相同的最近点,则 S 中的所有 k-1 其他点及其与 A 中的点的距离无关紧要,这是正确的吗? @tobias_k 最小化平方距离之和不同于最小化距离之和。是的,如果它们都具有相同的最近点而不是其他 k-1 点是任意的。 【参考方案1】:

我有一个大小为n 的点数组,称为A,还有一个大小为O(k)>k 的候选数组,称为S。我想在S 中找到k 点,以便最小化从A 的点到距离k 点最近的点的平方距离之和。

听起来这个问题可以简单地通过检查N点和K点来找到N中具有最小平方距离的k点。

因此,我现在相当确定这实际上是在 N 点中为 K 点中的每个点找到 k-nearest neighbors(K-NN 作为计算几何问题,而不是模式识别定义)而实际上并不是 k-means。

对于更高维度,在算法中同时考虑维度D 通常很有用。

提到的算法确实是O(NDk^2) 然后在考虑K-NN 时。这可以通过对距离使用快速选择算法改进为O(NDk)。这允许对照O(N) 中的每个K 点检查N 点列表,以找到最近的k 点。

https://en.wikipedia.org/wiki/Quickselect

编辑: 似乎对快速选择以及是否可以使用有些混淆。这是一个O(DkNlogN) 解决方案,它使用标准排序O(NlogN) 而不是快速选择O(N)。虽然这在实践中可能会更快,而且正如您在大多数语言中看到的那样,它很容易实现。

results = 
for y in F:
  def distanceSquared(x):
    distance(x,y) # Custom distance for each y

  # First k sorted by distanceSquared
  results[y] = S.sort(key=distanceSquared)[:k]
return results

更新新视觉效果

# Build up distance sums O(A*N*D)
results = 
for y in F:
  def distanceSquared(x):
    distance(x,y) # Custom distance for each y

  # Sum of distance squared from y for all points in S
  results[y] = sum(map(distanceSquared, S))

def results_key_value(key):
  results[key]

# First k results sorted by key O(D*AlogA)
results.keys().sort(key=results_key_value)[:k]

您可以只考虑从S 点中选择的 Z 个随机点来进行近似。或者,您可以合并S 中的点,前提是它们足够接近。这可以将S 减小到更小的尺寸,只要S 的尺寸保持在F^2 左右或更大,它不应该影响F 中的哪些点被选择得太多。尽管您还需要调整点的权重以更好地处理它。 IE:表示 10 个点的点的平方距离乘以 10,以说明它作为 10 个点而不是 1。

【讨论】:

不,我正在尝试从 O(k) 候选列表中找到最佳 k 均值。需要 (O(k) choose k)*n=O(k^k*n) 来检查所有可能的选项。 啊,是的,再读一遍,看起来这实际上比 k-means 更 KNN。改变了我的答案。 我不确定 KNN 在这种情况下如何提供帮助。 KNN 获取已知的标记集群并使用它们对未标记的数据点进行分类,这与我正在尝试做的事情无关。我正在尝试做的是,给定一个列表 S,从 S 中找到一个大小为 k 的子列表 F,使得从某个列表 A 的点到它们在 F 中的最近点的距离平方和最小化。这就像为 A 找到最佳 k 均值,但约束条件是 k 均值本身(即每个集群的“中心”)必须是 S 的子集。 我很抱歉,似乎 K-NN Wikipedia 确实过于关注 K-NN 的一个非常具体的用途,而没有足够的实际“找到给定点的 K-最近邻”问题。听起来你应该很好,只需使用我提供的快速选择答案。除非您需要重复使用不同的F 列表来测试相同的N 列表,否则它基本上就大 O 表示法而言是您所能得到的,即使如此它也应该比您现在拥有的更好,除非K 确实非常小(比如小于 10 左右)。如果输入足够小,最快的算法通常是最简单的。 如果您将标签视为 F 列表中的点之一,K-NN 仍然有效。 K-NN 只是一种算法,您需要将其应用于F 列表中的每个点。但是,是的,快速选择应该可以完成这项工作。

以上是关于从候选列表中找到最佳 k-means的主要内容,如果未能解决你的问题,请参考以下文章

算法----列表查找以及列表排序

列表查找的两种方法

NLP:从 QuestionAnsweringPipeline 中获得 5 个最佳候选人

列表查找以及二分查找

算法与数据结构

跨多个候选项查找多个子字符串的最佳匹配