我已经将大量点(~3000)聚集到(~400)个集群中。我想绘制数据并可视化集群。我想确保附近的集群有不同的颜色。任何人都可以推荐一种为集群着色的方法吗?
这是一个概念性问题,但我对 python 或 R 中的解决方案最感兴趣。
我已经将大量点(~3000)聚集到(~400)个集群中。我想绘制数据并可视化集群。我想确保附近的集群有不同的颜色。任何人都可以推荐一种为集群着色的方法吗?
这是一个概念性问题,但我对 python 或 R 中的解决方案最感兴趣。
matplotlib已经负责用不同的颜色为相邻的集群着色。但是,我相信它为每个集群使用了独特的颜色。如果是这样的话,400 种颜色就太多了。
可能有更好的方法,但在最坏的情况下,试试这个:
我们想用最少的颜色着色。因此,问题变成了图着色问题,我们不希望两个连接的相邻节点具有相同的颜色。找到最小颜色数量是一个 np-hard 问题,但我们可以使用近似算法。
一种方法可能是将您的集群质心定义为图形节点并存储它们的连接,然后使用图形着色算法。
第 1 步:将您的集群存储为邻接矩阵,并将该矩阵转换为图形,其中每个质心代表一个集群,邻接矩阵包含每个质心与其他质心之间的连通性(邻域)。 解释 代码
第 2 步:使用着色算法为图的节点着色。
这篇文章包含一个着色算法,它获取图形并返回它的着色。
第 3 步:拥有每个质心的颜色,您可以用最少的颜色数为整个集群着色。
我发现获取每个集群的质心,运行 k-nearest-neighbors,然后应用https://en.wikipedia.org/wiki/Greedy_coloring效果很好。只需不断增加 K 直到集群脱颖而出。
编辑:按照@Fatemeh Asgarinejad 的建议,使用从集群质心到其他集群成员的最小距离作为计算 KNN Now 的距离。当簇重叠或具有不规则形状时,这速度较慢,但似乎提供了更强大的着色。
我的python代码:
# data is a pandas data frame of data points with cluster labels
from sklearn.neighbors import NearestNeighbors
def assign_cluster_colors(data, clusters, n_colors=10, n_neighbors = 8):
centroids = data.groupby('cluster').agg({'x':np.mean,'y':np.mean})
color_ids = np.arange(n_colors)
distances = np.empty(shape=(centroids.shape[0],centroids.shape[0]))
groups = tsne_data.groupby('cluster')
for centroid in centroids.itertuples():
c_dists = groups.apply(lambda r: min(np.sqrt(np.square(centroid.x - r.x) + np.square(centroid.y-r.y))))
distances[:,centroid.Index] = c_dists
nbrs = NearestNeighbors(n_neighbors=n_neighbors,metric='precomputed').fit(distances)
distances, indices = nbrs.kneighbors()
color_assignments = np.repeat(-1,len(centroids))
for i in range(len(centroids)):
knn = indices[i]
knn_colors = color_assignments[knn]
available_colors = color_ids[list(set(color_ids) - set(knn_colors))]
if(len(available_colors) > 0):
color_assignments[i] = available_colors[0]
else:
raise Exception("Can't color this many neighbors with this many colors")
centroids = centroids.reset_index()
colors = centroids.loc[:,['cluster']]
colors['color'] = color_assignments
data = data.merge(colors,on='cluster')
return(data)