【问题标题】:Optimizing DBSCAN for neo4j in Cypher / Python在 Cypher / Python 中为 neo4j 优化 DBSCAN
【发布时间】:2012-09-19 21:49:21
【问题描述】:

您好,我一直在尝试为 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 关系,而在强相似性下,只有 ~20k 关系在约 10k 个节点(或更少)之间。无论如何,它总是真的很慢。我处理这个问题的最佳方法是什么?是否对关系类型和起始节点进行索引?我还没有找到关于这个问题的任何资源,而且令人惊讶的是还没有实现,因为这是一个非常标准的图形算法。我可以使用 scikit.learn 但我将仅限于内存中的距离矩阵:(

【问题讨论】:

  • 可能是因为 neo4j 针对图遍历进行了优化,而不是主要用于图插入/编辑。我在某处看到了 neo4j 和其他图形数据库引擎在数据处理速度方面的比较,并且 neo4j 非常缓慢。另一方面,它在图遍历的速度上优于其他人

标签: python cluster-analysis neo4j dbscan


【解决方案1】:

有一些使用索引的 DBSCAN 实现。我不知道,所以我无法确定您的方法是否有效。您可能需要预先计算的东西实际上是图的稀疏版本,只有在 epsilon 阈值内的边。

我想指出的是,显然您的数据集中有不同的密度,因此您可能想改用 OPTICS,它是 DBSCAN 的一种变体,它取消了 epsilon 参数(也没有需要区分“核心”节点,因为每个节点都是某个 epsilon 的核心节点)。不要使用 Weka 版本(或浮动的受 weka 启发的 python 版本)。它们是一半 OPTICS 和一半 DBSCAN。

当您有可用的有效排序更新堆时,OPTICS 会非常快。

【讨论】:

  • 是的,我看过 OPTICS,但我想我会在更简单的算法上咬牙切齿(也找不到不是 Weka 的好算法,但我会更加努力) . scikit 实现适用于我的直接用例,但图形数据库实现具有持久性增量更新的潜力。进行 epsilon 阈值处理并不是很有用,因为我需要两个级别,虽然它可以节省重复检测的时间,但它不会用于模糊聚类(语言/文档类型检测)。我宁愿有一个适用于两者的实现。
【解决方案2】:

您使用的是哪个版本的 neo4j?

在 1.8 之前,性能一直不是 cypher(而是语言)的设计目标 查看最近的快照 (1.9-SNAP)。

还要确保您的热数据集不只是从磁盘加载(否则您测量磁盘 io),因此您的 memory mapped settings 和 JVM 堆足够大。

您可能还想查看 Neo4j 企业版的 GCR 缓存,它具有较小的内存占用。

您的查询中count(x) 的基数是多少?如果它太小,您有太多的小交易正在进行。取决于您运行的 python 嵌入式或 REST 使用更大的 tx-scope 或 REST-batch-operations

您已经在使用非常棒的参数。您的 rel 类型的可变性是什么?

是否有机会与我们 (Neo4j) 共享您的数据集/生成器和代码,以便我们进行性能测试?

【讨论】:

  • 感谢您的提示! count(x) 的基数变化很大——我至少检查每个节点一次(在核心集中),所以通常它很小(0-10),但对于某些核心节点,它会更大,~100-具体1000。理想情况下,我希望能够只返回具有未标记传出链接的节点,因为这会大大减少小基数查询。我将权重离散化为不同的链接类型,因为我不知道如何以有效的方式查询 r.weight
  • 另外,我很乐意分享数据 + 源代码,但在我有时间为您打包之前,必须至少获得一种聚类方法。 DBSCAN 不是“真正”正确的事情,我认为 OPTICS 可能适用于我的数据,但我可能只是要使用 HDP,这样我就可以拥有重叠的集群。
  • 随意分享您认为合理的任何内容。我们也可以在 Neo4j google group 上继续这个讨论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多