我正在尝试解决一个简单的问题:基于为产品评级计算的欧几里德距离来计算用户到用户的相似度。
我正在使用这样的查询
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查询中的连续实例。
非常感谢您能为我们提供的所有帮助。
Thx Roberto
发布于 2017-02-01 17:29:11
首先,我会重写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 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);
https://stackoverflow.com/questions/41966792
复制相似问题