我正在尝试使用 HDBSCAN 算法在包含 146,000 个观察值的大型数据集上实现聚类。当我使用(默认)Minkowski/Euclidean 距离度量对这些观察结果进行聚类时,整个数据的聚类很顺利,只需要 8 秒。但是,我正在尝试使用我自己的指标执行聚类。在对数据子集进行操作时,这很好,尽管速度要慢得多。但是,当尝试在完整数据集上实现它时,我立即遇到内存错误。这是有道理的,因为由于数据集的大小,成对距离矩阵将占用大约 150GB。然而,这让我想知道使用默认度量如何没有这样的问题,同时查看 HDBSCAN 源代码显示在这种情况下还调用了 Sklearn 的成对距离,这将返回整个矩阵。
我的指标代码和一些结果:
import hdbscan
import pandas as pd
import time
import numpy as np
from numpy.linalg import norm
def spex_distance(a, b):
euclidean = norm(a[:2] - b[:2])
exp_vec_a, exp_vec_b = a[2:], b[2:]
cos_sim = np.dot(exp_vec_a, exp_vec_b) / (norm(exp_vec_a) * norm(exp_vec_b))
if cos_sim > 0:
return euclidean / cos_sim
else:
return np.inf
def main():
data = pd.read_pickle(file_location)
small_data = data[:1000]
t0 = time.time()
hdb_custom = hdbscan.HDBSCAN(metric=spex_distance)
hdb_custom.fit(small_data)
print(f"Time needed for clustering subset with custom metric: {time.time()-t0}") # 10 sec
t0 = time.time()
hdb_default = hdbscan.HDBSCAN()
hdb_default.fit(small_data)
print(f"Time needed for clustering subset with default metric: {time.time()-t0}") # 0.03 sec
t0 = time.time()
hdb_default.fit(data)
print(f"Time needed for clustering full dataset with default metric: {time.time()-t0}") # 9 sec
hdb_custom.fit(data) # fails with memory error