【发布时间】:2021-07-13 01:18:03
【问题描述】:
我想使用 sklearn 的一种聚类算法,但限制是某些点集必须属于同一类。例如,给定下面的一组点,我想强制所有红点属于同一类,所有蓝点属于同一类。我也希望红色和蓝色点可以属于同一类。如果这在 sklearn 中是不可能的,我也愿意使用其他库。
【问题讨论】:
标签: python scikit-learn cluster-analysis
我想使用 sklearn 的一种聚类算法,但限制是某些点集必须属于同一类。例如,给定下面的一组点,我想强制所有红点属于同一类,所有蓝点属于同一类。我也希望红色和蓝色点可以属于同一类。如果这在 sklearn 中是不可能的,我也愿意使用其他库。
【问题讨论】:
标签: python scikit-learn cluster-analysis
它的名称是“constrained clustering”,这是一系列半监督聚类方法,其中用户还可以提供以下约束:
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-Average(P')||^2+Var(P')).
现在,由于 k-means 试图找到将最小化到所有点(包括 P')的平方距离之和的 k 个点,因此将 P' 替换为 n 个点都等于 Average(P')(或一个点权重为 |P'|) 将强制所有这些点位于同一簇中,并将约束损失函数精确地减小 |P'|Var(P') (这是 P' 的常数,不依赖于k 点,因此不影响约束 k-means 的解)。
这意味着您可以简单地将 P' 中的任何点替换为 Average(P'),然后求解常规 k-means,这将等效于受约束的 k-means。 您可以使用您希望位于同一集群中的任何一组点来执行此操作。
编辑:我刚刚在你的一个评论中看到你说这个关于用平均值替换点“也许这是我使用的图像中的一个缺陷,但我不一定知道红色和蓝色点彼此靠近。如果它们分散在整个空间中,我认为这可能会产生奇怪的影响。不过我喜欢这个主意。”
因此,与您的评论所暗示的不同,不,用平均值替换点不会产生奇怪的隐含,无论它们彼此相距多远。
【讨论】: