OrientDB - 计算用户相似度

时间:2017-01-31 20:21:53

标签: orientdb orientdb2.2

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

我正在使用此类查询

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中的连续实例。

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

THX 罗伯特

1 个答案:

答案 0 :(得分: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);