在我的 Python 代码中,我想根据给定的距离矩阵对一组对象进行聚类。然而,有些对象永远不应该出现在同一个簇中。选择簇的数量以便问题是可解决的。我想使用 sklearn 库中的 AgglomerativeClustering 类。我将不兼容对象的距离设置为 1,这在某些情况下并不能阻止它们最终出现在同一个簇中。我还尝试通过关键字“connectivity”将连接矩阵传递给 AgglomerativeClustering。这并不适用于所有情况。下面是一个归结的问题。
如果我不使用连接关键字,我会得到集群标签 [0 1 0 1 0]。这是有道理的,因为不兼容的对象 0 和 1 不在同一簇中,不兼容的对象 2 和 3 也不在同一簇中。但是,当我提供连接矩阵时,我得到簇标签 [0 1 0 0 0]。这似乎与连接矩阵中的连接关系相矛盾,因为对象 2 和 3 不应该位于同一簇中。
我没有正确使用“连通性”这个论点吗?如果是这样,如何使用它来实现我上面描述的目标?
import numpy as np
from sklearn.cluster import AgglomerativeClustering
n_clusters = 2
distance_matrix = np.array([
[0.,1.,0.,0.,0.],
[1.,0.,0.,0.,0.],
[0.,0.,0.,1.,0.],
[0.,0.,1.,0.,0.],
[0.,0.,0.,0.,0.]
])
connectivity_matrix = np.array([
[True, False, True, True, True],
[False, True, True, True, True],
[True, True, True, False, True],
[True, True, False, True, True],
[True, True, True, True, True]
])
agglomerativeClustering = AgglomerativeClustering(n_clusters=n_clusters, metric='precomputed',
linkage='average')
cluster_labels_wo_connectivity_matrix = agglomerativeClustering.fit_predict(distance_matrix)
agglomerativeClustering = AgglomerativeClustering(n_clusters=n_clusters, metric='precomputed',
linkage='average', connectivity=connectivity_matrix)
cluster_labels_with_connectivity_matrix = agglomerativeClustering.fit_predict(distance_matrix)
print("Cluster labels without considering connectivity matrix: ", cluster_labels_wo_connectivity_matrix)
print("Cluster labels with considering connectivity matrix: ", cluster_labels_with_connectivity_matrix)
我尝试选择其他类型的“链接”,有时有帮助,有时没有。我尝试创建一个返回连接矩阵的可调用函数,例如本例中的“kneighbors_graph”:https://scikit-learn.org/stable/auto_examples/cluster/plot_agglomerative_clustering.html 这没有什么区别。
stackoverflow 上最接近的相关问题是这个:Scikit-learn 聚合聚类连接矩阵
但是,在我的例子中,连接矩阵隐含的图形是相连的。
我没有正确使用“连通性”这个论点吗?如果是这样,如何使用它来实现我上面描述的目标?
我的印象是你使用它是正确的。我希望受约束的模型能够找到与原始解决方案类似的有效解决方案,原因是原始解决方案尊重约束。我不知道为什么结果看起来是错误的,但以下似乎可以通过测试用例解决这个问题。
从原始距离矩阵开始,我使用
manifold.MDS()
对其进行反转,它会找到尽可能尊重原始距离的空间点配置。这是它找到的解决方案之一(我规定了 n_components=2
或 2D):
从视觉上看,这种反演展现了原始距离矩阵的一些显着特征:类 0/1 和 2/3 被推开,而类 4 距离任何类都不太远。 MDS 显然在这个距离矩阵上遇到了困难,得分为 0.71(超过 0.2 被认为很差),而且当使用更多组件时得分没有提高。这些因素表明原始距离矩阵的结构存在问题。
原始距离矩阵和 MDS 矩阵:
array([[0. , 1. , 0.98, 0.18, 0.5 ],
[1. , 0. , 0.18, 0.98, 0.5 ],
[0.98, 0.18, 0. , 1. , 0.5 ],
[0.18, 0.98, 1. , 0. , 0.5 ],
[0.5 , 0.5 , 0.5 , 0.5 , 0. ]])
MDS 表示与原始表示有“一些”相似之处。区别在于 0 类和 2 类被认为几乎与 0/1 类和 2/3 类一样远。 它呈现
[0, 1, 1, 0, 0]
的有效聚类,其中类 (0, 2, 3) 在一个聚类中,而 (1, 4) 定义一个单独的聚类。
AgglomerativeClustering(
n_clusters=2,
linkage='average',
connectivity=connectivity_matrix
).fit_predict(mds_coords)
或者等效地,使用 MDS 结果中的距离矩阵:
from sklearn.metrics import pairwise_distances
mds_distance_matrix = pairwise_distances(mds_coords)
AgglomerativeClustering(
n_clusters=2,
linkage='average',
connectivity=connectivity_matrix,
metric='precomputed',
).fit_predict(mds_distance_matrix)