在 sklearn 或其他集群库中进行集群时,有没有办法强制将一组点分配给相同的 class?

Is there a way to enforce that a set of points are assigned to the same class when clustering in sklearn or other clustering library?

我想使用 sklearn 的一种聚类算法,但有某些点集必须属于相同 class 的限制。例如,给定下面的点集,我想强制所有红色点属于同一个 class,所有蓝色点都属于同一个 class。我也希望红色和蓝色点可以属于同一个class。如果这在 sklearn 中是不可能的,我也愿意使用其他库。

一种适用于任何库的可能解决方案是为蓝色集群定义一个“超级点”,为红色集群定义另一个“超级点”。

因此,只需将蓝色超级点定义为每个蓝色点的平均值/中值,红色也类似。然后运行在这两个超点上的聚类加上剩余的点

它的名称是“constrained clustering”,它是一系列半监督聚类方法,用户还可以在其中提供约束条件:

  1. 必须Link - 两个节点必须属于同一个集群
  2. 不能Link - 两个节点不能属于同一个集群

有一个 COP-KMeans algorithm 的实现,它提供了这样的 API:

import numpy
from copkmeans.cop_kmeans import cop_kmeans
input_matrix = numpy.random.rand(100, 500)
must_link = [(0, 10), (0, 20), (0, 30)]
cannot_link = [(1, 10), (2, 10), (3, 10)]
clusters, centers = cop_kmeans(dataset=input_matrix, k=5, ml=must_link,cl=cannot_link)

在您的情况下实际上不需要使用约束聚类。假设所有点都是一个名为 P 的集合,并且您有一个点 P' 的子集,您希望它们位于同一集群中。任意点x到P'点的距离平方和可以表示为:

|P'|(||x-平均值(P')||^2+Var(P')).

现在,由于 k-means 尝试找到 k 个点,这些点将最小化到所有点(包括 P')的平方距离之和,然后用 n 个点替换 P' 全部等于 Average(P')(或一个权重为 |P'| 的点将强制所有这些点都在同一个集群中,并将约束损失函数减少恰好 |P'|Var(P')(这是 P' 的常数,不取决于 k 个点,因此不影响约束 k 均值的解)。

这意味着您可以简单地将 P' 中的任何点替换为 Average(P'),然后求解常规 k-means,这将等同于约束 k-means。 您可以对要位于同一集群中的任何点集执行此操作。

编辑:我刚刚在您的一条评论中看到,您在将点替换为平均值时说了这一点“也许这是我使用的图像中的一个缺陷,但我不一定知道红色和蓝点彼此靠近。如果它们分散在 space 中,我认为这可能会产生奇怪的影响。不过我喜欢这个主意。“

因此,与您的评论所建议的不同,不,用平均值替换点不会有奇怪的隐含,无论它们彼此相距多远。