对于这样的任务,我想到的最简单的解决方案是使用与稍后的层次聚类步骤计划的完全相同的指标(在您的情况下,使用 p=2 的 eucledian / minkowski)进行简单的 kmeans 聚类(或批处理变体)。对于最初的 kmeans 步骤,您选择了集群的数量 k,以便对这些集群中心的距离计算是可行的。有了这个,你基本上初始化了层次结构下一层的层次聚类。
import numpy as np
from sklearn.cluster import KMeans
from scipy.spatial.distance import pdist, squareform
from sklearn.neighbors import NearestNeighbors
x = np.random.rand(600000*2).reshape((600000, -1))
kmeans = KMeans(k=int(len(x)/100), n_jobs=16)
kmeans.fit(x)
x_ = kmeans.cluster_centers_
D = squareform(pdist(x_))
这里 x 是您的数据(这里通过正方形中的随机坐标进行模拟),第一步的缩减因子是 100。在计算时间方面,这个操作仍然相当昂贵。一个更快的解决方案如下:
请注意,如果您的数据非常统一,请考虑随机预选数据子集(可能具有类似于泊松圆盘采样中发生的距离标准)而不是 kmeans。那将是超级快:
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances
# input data
x = np.random.rand(600000*2).reshape((600000, -1))
# reduction of the size of the set of samples using uniformity
# chose a couple of times randomly from the input data and compute clusters in that subset
# this allows to avoid expensive clustering on the huge input data set
repetitions = 20
reduction = 1000
x_ = [x[np.random.choice(len(x), size=int(len(x)/reduction), replace=False)] for i in range(repetitions)]
x_ = np.reshape(x_, (repetitions*int(len(x)/reduction),2))
kmeans = KMeans(int(len(x)/reduction), n_jobs = 16)
kmeans.fit(x_)
# Compute the distance matrix to start with for the hierarchical clustering
D = pairwise_distances(kmeans.cluster_centers_, n_jobs=16)
# Compute the assignments from each data point to any of the level-0 clusters
D_data2clusters = pairwise_distances(x, kmeans.cluster_centers_, n_jobs=16)
cluster_labels = np.argmin(D_data2clusters,1)
from matplotlib import pyplot as plt
for cluster in np.unique(cluster_labels):
plt.scatter(*x[cluster_labels == cluster].T)
plt.scatter(*kmeans.cluster_centers_.T)
plt.savefig("clustertest")

这里kmeans.cluster_centers_(绿点)或距离矩阵D可以作为层次聚类的输入。
from scipy.cluster.hierarchy import linkage, dendrogram
z = linkage(D)
plt.figure()
dendrogram(z)
plt.savefig("dendrogram")

在这种情况下,另一种可能的解决方法是使用基于邻居树的方法计算不完整的距离矩阵。这基本上是您对距离矩阵的近似。
为此,您首先将 sklearn.neighbors.NearestNeighbors 树拟合到您的数据,然后使用“距离”模式(这是一个稀疏距离矩阵)计算图形。您需要将非对角零值推到很远的距离(或无穷大)。在该稀疏矩阵中,基本上只存储有关每个数据的较近邻域的信息,甚至不计算更大的距离并将其放入该矩阵中。但是,对于您的场景内存,必须分配大小为 600000^2 的浮点矩阵 - 即 2.62 TiB,这是不现实的。
假设您有这样的距离矩阵,您可以尝试解决任何层次聚类方法是否适当地处理那种不完整的距离矩阵,但正如前面的答案所指出的那样,它会非常昂贵。因此,我建议在这种情况下使用非常有效的 kmeans(如上所示在数据本身上 - 在这种情况下批处理版本也可能有用)或kmedoid(在稀疏距离矩阵上),您可以构建和应用分层方式也是。
通常,如果您可以重新制定算法以使其不需要立即访问完整距离矩阵,则可以使用 sklearn 的pairwise_distances_chunked。