【发布时间】:2021-02-07 04:32:54
【问题描述】:
我有以下基于 10 个数据点的距离矩阵:
import numpy as np
distance_matrix = np.array([[0. , 0.00981376, 0.0698306 , 0.01313118, 0.05344448,
0.0085152 , 0.01996724, 0.14019663, 0.03702411, 0.07054652],
[0.00981376, 0. , 0.06148157, 0.00563764, 0.04473798,
0.00905327, 0.01223233, 0.13140022, 0.03114453, 0.06215728],
[0.0698306 , 0.06148157, 0. , 0.05693448, 0.02083512,
0.06390897, 0.05107812, 0.07539802, 0.04003773, 0.00703263],
[0.01313118, 0.00563764, 0.05693448, 0. , 0.0408836 ,
0.00787845, 0.00799949, 0.12779965, 0.02552774, 0.05766039],
[0.05344448, 0.04473798, 0.02083512, 0.0408836 , 0. ,
0.04846382, 0.03638932, 0.0869414 , 0.03579818, 0.0192329 ],
[0.0085152 , 0.00905327, 0.06390897, 0.00787845, 0.04846382,
0. , 0.01284173, 0.13540522, 0.03010677, 0.0646998 ],
[0.01996724, 0.01223233, 0.05107812, 0.00799949, 0.03638932,
0.01284173, 0. , 0.12310601, 0.01916205, 0.05188323],
[0.14019663, 0.13140022, 0.07539802, 0.12779965, 0.0869414 ,
0.13540522, 0.12310601, 0. , 0.11271352, 0.07346808],
[0.03702411, 0.03114453, 0.04003773, 0.02552774, 0.03579818,
0.03010677, 0.01916205, 0.11271352, 0. , 0.04157886],
[0.07054652, 0.06215728, 0.00703263, 0.05766039, 0.0192329 ,
0.0646998 , 0.05188323, 0.07346808, 0.04157886, 0. ]])
我使用以下方法将distance_matrix 转换为affinity_matrix
delta = 0.1
np.exp(- distance_matrix ** 2 / (2. * delta ** 2))
这给了
affinity_matrix = np.array([[1. , 0.99519608, 0.7836321 , 0.99141566, 0.86691389,
0.99638113, 0.98026285, 0.37427863, 0.93375682, 0.77970427],
[0.99519608, 1. , 0.82778719, 0.99841211, 0.90477015,
0.9959103 , 0.99254642, 0.42176757, 0.95265821, 0.82433657],
[0.7836321 , 0.82778719, 1. , 0.85037594, 0.97852875,
0.81528476, 0.8777015 , 0.75258369, 0.92297697, 0.99753016],
[0.99141566, 0.99841211, 0.85037594, 1. , 0.91982353,
0.99690131, 0.99680552, 0.44191509, 0.96794184, 0.84684633],
[0.86691389, 0.90477015, 0.97852875, 0.91982353, 1. ,
0.88919645, 0.93593511, 0.68527137, 0.9379342 , 0.98167476],
[0.99638113, 0.9959103 , 0.81528476, 0.99690131, 0.88919645,
1. , 0.9917884 , 0.39982486, 0.95569077, 0.81114925],
[0.98026285, 0.99254642, 0.8777015 , 0.99680552, 0.93593511,
0.9917884 , 1. , 0.46871776, 0.9818083 , 0.87407117],
[0.37427863, 0.42176757, 0.75258369, 0.44191509, 0.68527137,
0.39982486, 0.46871776, 1. , 0.52982057, 0.76347268],
[0.93375682, 0.95265821, 0.92297697, 0.96794184, 0.9379342 ,
0.95569077, 0.9818083 , 0.52982057, 1. , 0.91719051],
[0.77970427, 0.82433657, 0.99753016, 0.84684633, 0.98167476,
0.81114925, 0.87407117, 0.76347268, 0.91719051, 1. ]])
我将distance_matrix 转换为热图以获得更好的数据视觉效果
import seaborn as sns
distance_matrix_df = pd.DataFrame(distance_matrix)
distance_matrix_df.columns = [x + 1 for x in range(10))]
distance_matrix_df.index = [x + 1 for x in range(10)]
sns.heatmap(distance_matrix_df, cmap='RdYlGn_r', annot=True, linewidths=0.5)
接下来我想将affinity_matrix 分成 3 个集群。在运行实际聚类之前,我会检查热图以预测聚类。很明显,#8 是一个异常值,它本身就是一个集群。
接下来我运行实际的集群。
from sklearn.cluster import SpectralClustering
clustering = SpectralClustering(n_clusters=3,
assign_labels='kmeans',
affinity='precomputed').fit(affinity_matrix)
clusters = clustering.labels_.copy()
clusters = clusters.astype(np.int32) + 1
产出产量
[1, 1, 2, 1, 2, 1, 1, 2, 3, 2]
因此,#8 是集群 2 的一部分,集群 2 由其他三个数据点组成。最初,我会假设它本身就是一个集群。我做错什么了吗?或者有人可以告诉我为什么#8 看起来像#3、#5 和#10。请指教。
【问题讨论】:
-
Clustering是一种非监督学习,因此,它可能会如你所愿,也可能不会。我认为您应该尝试其他数量的集群(为什么选择 3 个?),所以看看 here 可能会有所帮助。有很多方法可以做到这一点,有些是可视的,有些是指标,但在假设最佳集群数量之前,您绝对应该看看这些方法。 -
感谢您的帮助。对于此特定项目,集群的数量将始终为 2 或 3。我知道在某种程度上会有惊喜,但在距离矩阵#8 看起来它在自己的星球上,对吧?
-
它们看起来确实可能与其他的不同,但距离确实很近(它们从 0 到 0.14),所以这可能是一个规模问题。如果他们与其他数据点一起落入集群,我不会太自责。真诚地,我会检查它们是否适合训练数据,并可能尝试其他聚类方法。他们都是无人监督的,所以你应该经常检查他们是否做了你所期望的(如果他们做了你没想到的事情,你能从中学到什么?)
-
好的,但为什么#9 本身就是一个集群?直觉上没有意义。我用于缩放来自 Ng、Jordan 和 Weiss 的启发式算法,您在其中循环一系列缩放因子并选择聚类后给出最紧密(最小失真)聚类的值。
-
这确实是一个好问题。也许您可以绘制它的两个向量 PCA 变换以进行可视化以试图弄清楚。抱歉,如果我没有提供太多帮助。
标签: python machine-learning scikit-learn cluster-analysis unsupervised-learning