Cypher查询:group to get top n,然后遍历所有元素并找到前n个成员的最短路径

时间:2015-06-25 20:59:28

标签: algorithm neo4j cypher

我试图减少包含值对的大表(数十亿条记录)的维度。每条记录都包含一个cookie和一个URL,例如

cookie                                  url
000006A0-AC89-4D96-8091-AAA16A7990CB    www.cnn.com
000006A0-AC89-4D96-8091-AAA16A7990CB    www.bbc.co.uk
000006A0-AC89-4D96-8091-AAA16A7990CB    www.ynetnews.com
00001490-7A5C-4944-B556-0BD5DF8A262A    www.webmd.com
00001490-7A5C-4944-B556-0BD5DF8A262A    www.health.com
00001490-7A5C-4944-B556-0BD5DF8A262A    www.juicingforperfecthealth.com
...                                     ...

大多数降维算法都是针对数值数据而设计的。 R' daisy可以计算分类变量的距离,但这肯定不会缩放。

由于缺乏更好的想法,我将数据加载到Neo4j中。我的计划是编写一个Cypher查询,将所有URL合并到几个主要组中。 Cookie与网址的关系visited

可以在访问次数中返回前n个网址:

MATCH (cookie)-[r:visited]->(url)
RETURN (url), count(url)
ORDER BY count(url) DESC
LIMIT 20

现在棘手的部分:迭代每个URL并返回最近的顶级URL(即具有最短路径的顶级URL)。结果如下:

url                                 closest_top_level_url
www.juicingforperfecthealth.com     www.webmd.com
www.ynetnews.com                    www.cnn.com
...                                 ...

您能告诉我如何在Cypher中编写此内容,或者建议采用更合理的方法来减少大量字符串对的维数吗?

1 个答案:

答案 0 :(得分:2)

您有cookieurl的二分图,因此根据定义,最接近的url节点必须距离visited两步之遥。

这意味着您可以获得最近的网址:

MATCH (cookie)-[r:visited]->(url)
WITH url, count(*) as freq
ORDER BY freq DESC
LIMIT 20
MATCH (url)<-[:visited]-(some_cookie)-[:visited]->(closest_top_level_url)
RETURN url, closest_top_level_url

'降低维度'是另一个问题,但不是一个问题,而是一个复杂的问题。这取决于你最终想要达到的目标。我想你想通过某种相似/不相似度量来聚类url个节点?即如果它们被相同的cookie访问,它们应该组合在一起?

你可以用二进制cookie x url矩阵和不同的聚类方法来做到这一点:https://stats.stackexchange.com/questions/86318/clustering-a-binary-matrix

在二分图上还有很多用于图聚类的方法。

更新

从技术上讲,您可以在评论中做出您的要求。我会首先在顶部网址上贴上标签:

MATCH (cookie)-[r:visited]->(url)
WITH url, count(*) as freq
ORDER BY freq DESC
LIMIT 20
SET url :Topurl

然后:

MATCH p = (some_url:url)-[:visited*]-(top_url:Topurl)
WITH top_url, some_url
ORDER BY length(p) desc
LIMIT 1
CREATE (some_url)-[:CLOSETO]-(top_url)

两个问题:如果您有数十亿行,那么前20个网址中的两个网址可能会非常长。此外,从一个Cookie到两个“远程”网址的单次访问会完全改变您的图表结构。