嗨,我一直在尝试为 Neo4j 实现 DBSCAN 算法,但遇到了严重的性能瓶颈。我将描述实现,然后寻求帮助。
我对可能的 epsilon 值进行了离散化,并将每个节点的每个离散化下的邻居数计数,以便能够在一个查询中检索所有核心节点。
START a = node(*)
WHERE a.rel<cutoff threshold>! >= {minp}
RETURN a
这部分很快,不快的部分是后续查询:
START a = node({i})
SET a.label<cutoff threshold>_<minpoints> = {clust}
WITH a
MATCH a -[:'|'.join(<valid distance relations>)]- (x)
WHERE not(has(x.label<cutoff threshold>_<minpoints>))
WITH x
SET x.label<cutoff threshold>_<minpoints>={clust}
RETURN x
然后我选择一个核心节点开始,只要还有核心节点邻居,运行上面的查询来标记他们的邻居。
我认为问题在于我的图具有非常不同的稀疏度 - 从只有弱相似性开始,它几乎是完全连接的,在 ~10k 节点之间有 ~50M 关系,而在强相似性时,~10k 之间的关系只有 ~20k节点(或更少)。无论如何,它总是真的很慢。我处理这个问题的最佳方法是什么?是否对关系类型和起始节点进行索引?我还没有找到关于这个问题的任何资源,而且令人惊讶的是还没有实现,因为这是一个非常标准的图形算法。我可以使用 scikit.learn 但我将仅限于内存中的距离矩阵:(