0

我正在尝试解决一个简单的问题:根据为产品评级计算的欧几里德距离计算用户与用户的相似度。

我正在使用这样的查询

SELECT U1.UserId, U2.UserId
FROM (
  MATCH 
  {class:User, as: U1, where: (UserId=12345) } -rate-> {class:Product, as:P},
  {class:User, as: U2, where: (UserId<>12345)} -rate-> {as:OP},
  RETURN U1, U2, P, OP
)

我现在将为每一对(用户 U1,用户 U2)计算一个结果,该结果表示普通产品的评分之间的距离。

用户常用产品示例

U1,Product,Rating
1, xxx, 5 
2, xxx, 2
1, yyy, 10 
2, yyy, 8

所以我会计算 Sqrt((5-2)^2 + (10-8)^2) 作为距离

这是否可以通过 OrientDB 上的单个查询来实现。Neo4J 提供 WITH 语句来操作 Cypher Query 中的连续实例。

非常感谢您为我们提供的所有帮助。

谢谢罗伯托

4

1 回答 1

0

首先,我将重写 MATCH 语句以返回两个用户和一个产品的评分距离:

MATCH 
  {class:User, as: U1, where: (UserId=12345) }.outE("rate"){as:r1}.inV(){class:Product, as:P},
  {class:User, as: U2, where: (UserId<>12345)}.outE("rate"){as:r2}.inV(){as:P},
RETURN U1, U2, (r1.rating - r2.rating) * (r1.rating - r2.rating) as squareDistance, P

然后你可以使用一些外部 SELECT 来进行计算:

SELECT U1, U2, P, sqrt(squareSum) as distance from (
  SELECT U1, U2, P, sum(squareDistance) as squareSum from (
    MATCH...
  ) GROUP BY U1, U2, P
)

这里唯一的问题是OrientDB没有内置的sqrt()函数,所以你必须用javascript编写自己的sqrt()。这很简单,因为在 js 函数中你可以使用 Java 类,所以函数体就是

return java.lang.Math.sqrt(x);
于 2017-02-01T09:29:10.933 回答