解释 HDBSCAN 聚类的行为

问题描述

我有一个包含 6 个元素的数据集。我使用 Gower 距离计算了距离矩阵,得到以下矩阵:

enter image description here

通过查看这个矩阵,我可以看出元素 #0 与元素 #4 和 #5 最相似,所以我假设 HDBSCAN 的输出是将它们聚集在一起,并假设其余的是异常值;然而,事实并非如此。

clusterer = hdbscan.HDBSCAN(min_cluster_size=2,min_samples=3,metric='precomputed',cluster_selection_epsilon=0.1,cluster_selection_method = 'eom').fit(distance_matrix) 

簇形成:

集群 0: {element #0,element #2}

集群 1: {元素 #4,元素 #5}

异常值: {element #1,element #3}

这是我不明白的行为。此外,参数 cluster_selection_epsiloncluster_selection_method 似乎对我的结果根本没有影响,我不明白为什么。

我再次尝试将参数更改为 min_cluster_size=2,min_samples=1

簇形成:

集群 0: {元素#0,元素#2,元素#4,元素#5}

集群 1: {元素#1,元素#3}

以及参数的任何其他变化都会导致所有点都被归类为异常值。

有人可以帮助解释这种行为,并解释为什么 cluster_selection_epsiloncluster_selection_method 不影响形成的集群。我认为通过将 cluster_selection_epsilon 设置为 0.1,我将确保集群内的点相距 0.1 或更小(例如,元素 #0 和元素 #2 不会聚集在一起)

以下是两个聚类试验的直观表示:

enter image description here

enter image description here

解决方法

正如help page中提到的,hdbscan的核心是1)计算相互可达距离和2)应用单链接算法。由于您没有那么多数据点并且您的距离度量是预先计算的,您可以看到您的聚类是由单个链接决定的:

import numpy as np
import hdbscan
import matplotlib.pyplot as plt
import seaborn as sns

x = np.array([[0.0,0.741,0.344,1.0,0.062,0.084],[0.741,0.0,0.648,0.592,0.678,0.657],[0.344,0.282,0.261],[1.0,0.655,0.937,0.916],[0.062,0.107],[0.084,0.65,0.261,0.916,0.107,0.0]])

clusterer = hdbscan.HDBSCAN(min_cluster_size=2,min_samples=1,metric='precomputed').fit(x)
clusterer.single_linkage_tree_.plot(cmap='viridis',colorbar=True)

enter image description here

结果将是:

clusterer.labels_

[0 1 0 1 0 0]

因为最小簇数必须是 2。所以实现这一点的唯一方法是将元素 0、2、4、5 放在一起。

一个快速的解决方案是简单地砍树并获得您想要的集群:

clusterer.single_linkage_tree_.get_clusters(0.15,min_cluster_size=2)

[ 0 -1 -1 -1  0  0]

或者您只是使用 sklearn.cluster.AgglomerativeClustering 中的一些东西,因为您不依赖 hdbscan 来计算距离度量。