【问题标题】:Boosting recommendation results in Neo4j在 Neo4j 中提升推荐结果
【发布时间】:2015-10-12 17:23:51
【问题描述】:

我正在尝试使用 Neo4j 实现一个推荐算法,这与page 上的实现类似。

现在我有一个简单的社交示例,用户可以:

  • 关注其他用户
  • 游戏
  • 居住在一个国家

这个想法是根据其他用户是否是朋友的朋友、玩相同的游戏、居住在相同的国家和/或关注相关用户来制定朋友建议算法。

除了后者,使用上面页面中的示例很容易实现,如下所示:

MATCH (origin)-[r1:FOLLOWS|PLAYS|LIVES_IN]-(c)-[r2:FOLLOWS|PLAYS|LIVES_IN]-(candidate)
WHERE type(r1)=type(r2) AND NOT (source)-[:FOLLOWS]->(candidate)  
RETURN candidate, SUM(ROUND(r2.weight) AS boost
ORDER BY boost DESC LIMIT 10

但是,一次完成整个事情的唯一可行方法是与另一个查询进行联合并处理结果。大致如下:

THE_QUERY_ABOVE

UNION

MATCH (origin)<-[r:FOLLOWS]-(candidate)
RETURN candidate, r.weight as boost

WITH candidate, boost
RETURN DISTINCT candidate, SUM(boost)
ORDER BY boost DESC LIMIT 10

但据我所知,Cypher 尚无法对UNION 结果进行后处理...

因此,我的问题是:这可能在单个查询中实现吗?以及如何?

如果是,是否有一种可能的解决方案,我不必在关系中指定权重,以避免在我想更改优先级时必须更改所有关系?强>

干杯!

【问题讨论】:

    标签: neo4j cypher union social-networking recommendation-engine


    【解决方案1】:

    你可以使用“可选匹配”

    【讨论】:

    • 嗨@Mvde。这也不是这个用例的完美匹配,因为可选匹配仍然需要发生其他匹配。我正在尝试做的是类似于每条路径的 OPTIONAL MATCH ......但将两个匹配链接在一起仍然很困难
    • 你可以使用 Match(origin) 可选 match(origin)-[]->() 等等还是我错了?
    • 这不是那么简单的@Mvde。这里的挑战是聚合不同OPTIONAL MATCH 路径的结果,如您在@cybersam 的solution 中所见
    【解决方案2】:

    [编辑]

    OPTIONAL MATCH (origin)-[r1:FOLLOWS|PLAYS|LIVES_IN]-(c)-[r2:FOLLOWS|PLAYS|LIVES_IN]-(candidate)
    WHERE type(r1)=type(r2) AND NOT (origin)-[:FOLLOWS]->(candidate)
    WITH origin,candidate,(
      CASE
      WHEN candidate IS NOT NULL THEN [{ candidate: candidate, boost: SUM(ROUND(r2.weight))}]
      ELSE NULL END ) AS res1
    OPTIONAL MATCH (candidate)-[r3:FOLLOWS]->(origin)
    WITH (
      CASE
      WHEN candidate IS NOT NULL THEN [{ candidate: candidate, boost: SUM(ROUND(r3.weight))}]
      ELSE NULL END )+ res1 AS res2
    UNWIND res2 AS result
    RETURN result.candidate AS candidate, SUM(result.boost) AS boost
    ORDER BY boost DESC 
    LIMIT 10;
    

    这对你有用吗? 如果这不起作用,您可以share a console 提供示例数据吗?

    它使用 2 个 OPTIONAL MATCH 子句共享相同的 origincandidate 节点。每个OPTIONAL MATCH 子句处理您的OR 案例之一,将该案例的结果放入地图集合(或NULL,如果匹配失败)。接近尾声时,集合(包含具有相同结构的地图)被组合并展开为单独的行。最后,将candidate 值相同的行的boost 值相加,返回前10 个结果(按提升值)。

    【讨论】:

    • 嗨@cybersam。感谢您的快速回复。但是,您提供的解决方案并不是我想要的。那只会找到遵循原点和所有其他东西的候选人......我正在寻找的是一个 OR,这意味着我希望任何可能关注原点的用户都能提高他的推荐分数。
    • 差不多有@cybersam ...但我也想返回遵循原点而没有其他内容的用户......你这样做的方式只返回那些用户如果他们在第一个optional match 中被匹配为候选人...我尝试将第二个candidate 更改为candidate2 但它返回了一些奇怪的结果...如果您愿意,我可以与您共享一个控制台...
    • 控制台会有所帮助。
    • 这是console@cybersam。结果应该是 (Agent Smith:20,Cypher:14,Niobe:11,The Architect:10) 但是是 (Agent Smith:50,The Architect:30,Cypher:28, Niobe:22) 相反...我怀疑第二个OPTIONAL MATCH 正在生成重复的提升或其他东西...无论如何,在您当前的解决方案中,结果是正确的,但您缺少只关注的用户起源(在这种情况下,建筑师)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多