提问者:小点点

Cypher查询计算同一标签的两个neo4j节点之间的余弦分数


我正在尝试为特定用例编写Cypher查询,但我无法提出一个。

我有一个neo4j数据库。我以以下方式用节点和关系填充了它。(上下文:此数据库代表电子商务网站的查询和产品)

每个节点有以下两个标签之一

  1. 查询
  2. 产品

关系只存在于从Query节点到Products节点(表示用户输入查询后对该产品的点击)。边有一个分数,表示点击的总数。

我想定义一个分数来衡量任何两个查询节点之间的重叠。因此,对于每个查询节点,我定义了一个向量,其中组件总数等于产品总数。每个组件都等于查询和该产品之间边缘的分数。

我现在想计算这两个向量之间角度的余弦。但是我无法编写一个返回每个查询的余弦分数的密码查询,查询'对。

我能想到的最好的就是这个问题

MATCH (q1:Query {search_term:'sunglasses'})-[e1:INTERACTION
{event_type:'CLICK'}]->(p:Product)<-[e2:INTERACTION 
{event_type:'CLICK'}]-(q2:Query) 
WITH q1, q2, sqrt(sum(e1.score * e1.score)) as sq1, sqrt(sum(e2.score * 
e2.score)) as sq2, sum(e1.score * e2.score) as overlap_score
RETURN q1, q2, overlap_score/(sq1 * sq2) as cosine
ORDER BY cosine DESC

但是这个查询不计算向量之间角度的余弦,因为在计算每个向量的长度(上面查询中的sq1和sq2)时,它忽略了第二个查询具有0分量的那些分量。

我知道这个问题需要一些描述,但是我还没有找到解决这个问题的方法。任何帮助都很感激!


共1个答案

匿名用户

如果您检查此图表,我们可以轻松窃取和修改您正在寻找的查询。

您的查询将如下所示:

MATCH (p1:Query {search_term:'sunglasses'})-[x:INTERACTION
{event_type:'CLICK'}]->(p:Product)<-[y:INTERACTION 
{event_type:'CLICK'}]-(p2:Query) 

WITH  SUM(x.score * y.score) AS xyDotProduct,
      SQRT(REDUCE(xDot = 0.0, a IN COLLECT(x.score) | xDot + a^2)) AS xLength,
      SQRT(REDUCE(yDot = 0.0, b IN COLLECT(y.score) | yDot + b^2)) AS yLength,
      p1, p2
MERGE (p1)-[s:SIMILARITY]-(p2)
SET   s.similarity = xyDotProduct / (xLength * yLength)

看看APOC关于余弦相似度的留档