比较平均值 - SPARQL

时间:2015-06-10 14:15:10

标签: sparql

有一个用户排名电影的数据集。需要找到与user1具有相似品味的用户。类似的口味定义如下:将genre的{​​{1}}的平均排名视为user1,将avgr1的同一流派视为user2,然后{{1和avgr2有相似的品味user1。到目前为止,我能够获得平均值之间的名称,类型和绝对值,但是用于比较的过滤不起作用。

user2

2 个答案:

答案 0 :(得分:3)

如果没有一些样本数据可以解答这些问题,那就非常困难。这里有一些示例数据,其中有两个用户在喜剧上排名相似,但浪漫排名不同:

@prefix : <urn:ex:>

:a :ranks [ :genre :comedy ; :value 2 ],
          [ :genre :comedy ; :value 3 ],
          [ :genre :comedy ; :value 3 ],
          [ :genre :romance ; :value 7 ],
          [ :genre :romance ; :value 8 ],
          [ :genre :romance ; :value 9 ].

:b :ranks [ :genre :comedy ; :value 3 ],
          [ :genre :comedy ; :value 3 ],
          [ :genre :comedy ; :value 4 ],
          [ :genre :romance ; :value 0 ],
          [ :genre :romance ; :value 1 ],
          [ :genre :romance ; :value 0 ].

这是一个查询,用于计算他们对流派的平均排名的差异:

prefix : <urn:ex:>

select ?user1 ?user2 ?genre (abs(avg(?value1)-avg(?value2)) as ?diff) {
  ?user1 :ranks [ :genre ?genre ; :value ?value1 ].
  ?user2 :ranks [ :genre ?genre ; :value ?value2 ].
  filter (str(?user1) < str(?user2)) #-- avoid duplicate user1/user2, user2/user1 results
}
group by ?user1 ?user2 ?genre
order by ?diff
---------------------------------------------------------
| user1 | user2 | genre    | diff                       |
=========================================================
| :a    | :b    | :comedy  | 0.666666666666666666666667 |
| :a    | :b    | :romance | 7.666666666666666666666667 |
---------------------------------------------------------

现在,您无法对聚合结果进行过滤,您必须使用 ,因此只能获取diff小于某个特定值的值,你这样做:

prefix : <urn:ex:>

select ?user1 ?user2 ?genre (abs(avg(?value1)-avg(?value2)) as ?diff) {
  ?user1 :ranks [ :genre ?genre ; :value ?value1 ].
  ?user2 :ranks [ :genre ?genre ; :value ?value2 ].
  filter (str(?user1) < str(?user2))
}
group by ?user1 ?user2 ?genre
having (?diff < 1)
order by ?diff
--------------------------------------------------------
| user1 | user2 | genre   | diff                       |
========================================================
| :a    | :b    | :comedy | 0.666666666666666666666667 |
--------------------------------------------------------

如果您不关心实际的差异,除非它低于阈值,您可以将表达式直接放在 中,并执行:

select ?user1 ?user2 ?genre {
  #-- ...
}
group by ?user1 ?user2 ?genre
having (abs(avg(?value1)-avg(?value2)) < 1)

答案 1 :(得分:0)

?在FILTER中未定义Rdiff - 在SELECT中的AS之前发生。

尝试使用在GROUP BY之后的HAVING。