【发布时间】:2018-12-14 07:52:43
【问题描述】:
我一直在研究用于集群雷达数据的 DBSCAN 的替代实现(如基于网格的 DBSCAN)。到目前为止,我一直在使用 sklearn 的标准欧几里得 DBSCAN,它可以在不到一秒的时间内运行 26,000 个数据点。但是,当我指定自己的距离度量时,如下所示:
X = np.column_stack((beam, gate, time_index))
num_pts = X.shape[0]
epsilons = np.array([[beam_eps]*num_pts, [gate_eps] * num_pts, [time_eps] * num_pts]).T
metric = lambda x, y, eps: np.sqrt(np.sum((x/eps - y/eps)**2))
def dist_metric(x, y, eps):
return np.sqrt(np.sum((x - y)**2))
db = DBSCAN(eps=eps, min_samples=minPts, metric=dist_metric, metric_params={'eps': epsilons}).fit(X)
在相同的数据上运行从 0.36 秒到 92 分钟。
我在该代码 sn-p 中所做的也可以通过预先转换数据并运行标准欧几里得 DBSCAN 来完成,但我正在尝试实现一个相当快的基于网格的 DBSCAN 版本,其中水平 epsilon根据与雷达的距离而有所不同,所以我无法做到这一点。
上述距离度量的部分缓慢是因为我认为除以 epsilon,因为如果我使用只是欧几里德距离的“自定义度量”,它只需要大约一分钟即可运行:
metric = lambda x, y: np.sqrt(np.sum((x - y)**2))
sklearn 的 euclidean DBSCAN 是如何跑得这么快的?我一直在挖掘代码,但到目前为止还没有弄明白。
【问题讨论】:
-
你确定你的欧几里得距离 lambda 有那么快吗?因为通常情况下,我认为作为 Python 函数或 lambda 的自定义指标与内置指标之间的区别在于它们是直接用 Cython 甚至 C 或 C++ 实现的,请参阅我的帖子 here。
-
如果你有足够的空间,另一个选项是预先计算矩阵
标签: optimization scikit-learn cluster-analysis data-mining dbscan