sparql - 如何标准化此数据

标签 sparql rdf semantic-web owl ontology

这是重现问题的最低数据:

@prefix rs: <http://example.org/rs#>
@prefix bo: <http://example.org/bo#>
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>

rs:user1 rs:hasRated [rs:by "1.0"^^xsd:float ; rs:item bo:animalFarm] .

rs:user2 rs:hasRated [rs:by "0.9"^^xsd:float ; rs:item bo:animalFarm] .

rs:user3 rs:hasRated [rs:by "0.9"^^xsd:float ; rs:item bo:animalFarm] .

rs:user4 rs:hasRated [rs:by "0.5"^^xsd:float ; rs:item bo:book3] .

rs:user5 rs:hasRated [rs:by "0.6"^^xsd:float ; rs:item bo:book3] .

rs:user6 rs:hasRated [rs:by "0.8"^^xsd:float ; rs:item bo:algorithem1] .

rs:user7 rs:hasRated [rs:by "0.9"^^xsd:float ; rs:item bo:algorithem1] .

rs:user8 rs:hasRated [rs:by "0.3"^^xsd:float ; rs:item bo:book4] .

我想要规范化每个项目的平均评分,并标准化每个项目的评分数量

我可以计算每个项目的平均评分以及每个项目的评分数量,如下所示:

PREFIX  bo:   <http://example.org/bo#>
PREFIX  xsd:  <http://www.w3.org/2001/XMLSchema#>
PREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX  rs:   <http://example.org/rs#>
select ?item (AVG(?ratingValue) as ?avg) (COUNT(*) as ?count) 
{
    ?user rs:hasRated [ rs:item ?item ;  rs:by ?ratingValue ] .
}
group by ?item 

结果是:

enter image description here

如果可能的话,我想要的是以下内容:

bo:book3                 (0.55/(0.55 + 0.93333334 + 0.85 + 0.3 ))   (2/(2 + 3 + 2 + 1))

当然其他项目也是如此。

我的问题是我不知道如何进行求和,同时进行除法。

非常感谢您的帮助。

更新 1

我询问是否有可能这样做,如果没有(或者性能太差)我得到了不同的解决方案

最佳答案

在 SPARQL 中,数据要么被分组,要么不分组。你无法真正从群体中“伸出援手”并获得比群体更大的信息。这意味着要获得此结果,您可能需要一个子查询来单独获取总值。根据您提供的数据:

select ?item
       (avg(?rating_)/?sumAvgRating as ?rating)
       (count(*)/?countRating as ?percentCount)
{
  ?user rs:hasRated [ rs:by ?rating_ ; rs:item ?item ]

  #-- get number of ratings
  { select (count(*) as ?countRating) { ?user rs:hasRated [] }}

  #-- get sum of average ratings
  { select (sum(?avgRating) as ?sumAvgRating) {
      { select (avg(?rating_) as ?avgRating) {
          ?user rs:hasRated [ rs:by ?rating_ ; rs:item ?item ]
        }
        group by ?item
      }
    }
  }
}
group by ?item ?countRating ?sumAvgRating
-----------------------------------------------------------
| item           | rating                  | percentCount |
===========================================================
| bo:book3       | "0.20886075"^^xsd:float | 0.25         |
| bo:book4       | "0.11392405"^^xsd:float | 0.125        |
| bo:algorithem1 | "0.3227848"^^xsd:float  | 0.25         |
| bo:animalFarm  | "0.35443038"^^xsd:float | 0.375        |
-----------------------------------------------------------

我认为,要获取您真正想要的数据,并且无需冗余子查询,您需要对结果进行一些后处理。我这么说是因为您确实要求进行一些涉及以两种不同方式分组的计算。要获得评分总数,您需要对所有结果进行分组(或者至少对某些分组结果进行分组)。要获得每个项目的平均值,您需要对项目进行分组。要获得平均值的总和,您需要对分组数据进行分组。因此,我认为如果没有一些冗余查询,您就无法完美地完成此操作。

但是,您可以在查询中进行一些处理。我想我会得到项目及其评分,并对每个项目的评分进行计数并求和平均值,如下所示:

select ?item (sum(?rating_) as ?sumRating) (count(*) as ?countRating) {
  ?user rs:hasRated [ rs:by ?rating_ ; rs:item ?item ]
}
group by ?item

我这样做的原因,而不是平均评分,是因为根据计数和总和,您可以轻松地重建平均值(只需将总和除以计数),然后您可以得到总和的总和以及计数的总和。如果你太早求平均值,那么你就无法确定所有评分的实际总和是多少。

关于sparql - 如何标准化此数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36771027/

相关文章:

rdf - Protege - 指定 RDF 文件的主键和外键

java - 如何为 URL 创建网络图?

rdf - 通过从 jena 中加载的本体中导入 namespace 来编写 RDF?

java - 如何将 Jena 规则添加到 OntModel

sparql - 单个查询中的 Wikipedia API 和 SPARQL

rdf - 提取由一组节点引起的子图

mysql - Jena SDB(一个关系数据库支持的 RDF 存储)如何处理 SPARQL 查询?

java - 如何排除具有特定 rdf :type from SPARQL results? 的资源

java - 使用 SPARQL 构造查询部分 RDF 图

java - 如何在芝麻2.7.7中更快速地添加100万个三元组