【问题标题】:Manually find the distance between centroid and labelled data points手动查找质心和标记数据点之间的距离
【发布时间】:2021-06-10 17:25:45
【问题描述】:

我对一些数据X 进行了一些聚类分析,得到了标签y 和质心c。现在,我正在尝试计算X它们分配的集群的质心 c 之间的距离。当我们有少量点时,这很容易:

import numpy as np

# 10 random points in 3D space
X = np.random.rand(10,3)

# define the number of clusters, say 3
clusters = 3

# give each point a random label 
# (in the real code this is found using KMeans, for example)
y = np.asarray([np.random.randint(0,clusters) for i in range(10)]).reshape(-1,1)

# randomly assign location of centroids 
# (in the real code this is found using KMeans, for example)
c = np.random.rand(clusters,3)

# calculate distances
distances = []
for i in range(len(X)):
    distances.append(np.linalg.norm(X[i]-c[y[i][0]]))

不幸的是,实际数据有更多行。有没有办法以某种方式对其进行矢量化(而不是使用for loop)?我似乎无法理解映射。

【问题讨论】:

  • 你可以试试scypicdist

标签: python numpy cluster-analysis k-means


【解决方案1】:

感谢 numpy 的 array indexing,您实际上可以将您的 for 循环变成一个单行并完全避免显式循环:

distances = np.linalg.norm(X- np.einsum('ijk->ik', c[y]), axis=1)

将执行与原始 for 循环相同的操作。

编辑:谢谢@Kris,我忘记了axis 关键字,因为我没有指定它,numpy 自动计算整个展平矩阵的范数,而不仅仅是沿行(轴 1)。我现在已经更新了它,它应该为每个点返回一个距离数组。此外,@Kris 为他们的特定应用建议了 einsum。

【讨论】:

  • 嗯,这只是给了我一个标量值,而不是每个点的距离数组。
  • 是的,忘记指定轴了哈哈-我已经在上面添加了。
  • 好的,所以您的编辑给了我一个 n x 3 数组,而不是我希望的 n x 1 数组。为了解决这个问题,我不得不稍微改变线性方程的右边。 np.einsum('ijk->ik', c[y]) 而不是 c[y] 似乎可以使尺寸正确。
  • 哦,我没有意识到你想要一个标量距离——我假设“距离”是指从每个点到其质心的 3D 矢量。我会把它添加到我的答案中
猜你喜欢
  • 1970-01-01
  • 2019-11-20
  • 2019-06-11
  • 2021-09-23
  • 1970-01-01
  • 2019-09-16
  • 2012-06-20
  • 2017-05-01
  • 2021-01-14
相关资源
最近更新 更多