如何从SPARQL中选择随机DBPedia节点?

时间:2011-04-15 13:15:23

标签: random sample sparql dbpedia

如何使用sparql端点从DBpedia中选择随机样本?

此查询

SELECT ?s WHERE { ?s ?p ?o . FILTER ( 1 > bif:rnd (10, ?s, ?p, ?o) ) } LIMIT 10

(找到here) 似乎在大多数SPARQL端点上都可以正常工作,但在http://dbpedia.org/sparql上它会被缓存(因此它总是返回相同的10个节点)。

如果我从JENA尝试,我会得到以下例外:

Unresolved prefixed name: bif:rnd

我找不到'bif'名称空间是什么。

关于如何解决这个问题的任何想法?

Mulone

7 个答案:

答案 0 :(得分:9)

在SPARQL 1.1中,您可以执行以下操作:

SELECT ?s
WHERE {
  ?s ?p ?o
}
ORDER BY RAND()
LIMIT 10

我不知道有多少商店会优化,甚至实现这一点。

  

[见下面的评论,这不太有用]

     

另一种选择是:

SELECT (SAMPLE(?s) AS ?ss)
WHERE { ?s ?p ?o }
GROUP BY ?s
     

但我认为更不可能进行优化。

答案 1 :(得分:6)

bif:rnd不是SPARQL标准,因此无法移植到任何SPARQL端点。您可以使用LIMIT,ORDER和OFFSET来模拟带有标准查询的随机样本。有点像...

SELECT * WHERE { ?s ?p ?o } 
ORDER BY ?s OFFSET $some_random_number$ LIMIT 10

其中some_random_number是您的应用程序生成的数字。这应该避免缓存问题,但这个查询反正非常昂贵,我不知道公共端点是否会支持它。

尽量避免像?s ?p ?o这样完全开放的模式,您的查询会更有效率。

答案 2 :(得分:1)

bif:rnd是Virtuoso特定的扩展,因此只能再次使用Virtuoso SPARQL端点。

bif是Virtuoso内置函数的前缀,它允许在SPARQL中调用任何Virtuoso函数,rnd是用于返回随机数的Virtuoso函数。

答案 3 :(得分:1)

我遇到了同样的问题,这里没有一个解决方案解决了我的问题。这是我的解决方案;这不是一件轻而易举的事。这适用于DBPedia,目前可用于其他SPARQL端点,但不保证可以用于将来的版本。

DBPedia使用Virtuoso,它支持RAND函数的未记录参数;该参数有效地指定了用于PRNG的范围。该游戏是为了让Virtuoso相信在计算每个结果行之前无法对输入参数进行静态评估,从而迫使程序为每个绑定评估RAND()

select * {
    ?s dbo:isPartOf ?o .  # Whatever your pattern is
    bind(rand(1 + strlen(str(?s))*0) as ?rid)
} order by ?rid

魔法发生在rand(1 + strlen(str(?s))*0),产生相当于rand();但是通过利用程序无法预测涉及某个变量的表达式的值这一事实迫使它在每场比赛中运行(在这种情况下,我们只是将IRI的长度计算为字符串)。实际表达并不重要,因为我们将其乘以0以完全忽略它,然后添加1以使rand正常执行。

这只能起作用,因为开发人员在表达式的静态代码评估中没有这么做。他们可以很容易地写一个“乘以零”的分支,但是他们没有:)

答案 4 :(得分:1)

上述方法都不适用于Jena / Fuseki,所以我以其他方式完成了这项工作:

.truck_slot{
    float:left;
    width:170px;
    cursor:pointer;
    margin:5px 8px;
}
.table_truck{
    width:100%;
    height: 155px;
    padding:0px;
    border:1px #CCCCCC solid;
    border-radius:10px;
    padding:2px;
    border-collapse: separate;
    border-spacing: 0px;
    box-shadow: 2px 2px 3px #999;
}
.table_truck td{
    font-family:Arial, Helvetica, sans-serif;
    color: #666;
}
.table_truck .truck_colo{
    height:100%;
    width: 55px;
    text-align: center;
    vertical-align: top;
    border-radius: 6px 0 0 6px;
    color: #FFF;
}
.table_truck .truck_time{
    font-size:13px;
    font-weight:bold;
    font-family: "Calibri", "Century Gothic", Century, Arial, "Arial Black";
}
.table_truck .truck_info{
    height:100%;
    vertical-align: top;
    color:#666;
}
.table_truck .truck_info .truck_info_div{
    height:90px;
    overflow:hidden;
}
.table_truck .truck_stop{
    border-radius: 0 6px 0 0;
    padding: 0 5px;
    color: #FFF;
    line-height:20px;
    font-size:13px;
    font-weight:bold;
}
.table_truck .truck_cont{
    height: 100%;
    vertical-align:middle;
}
.table_truck .truck_name{
    font-family:Arial, Helvetica, sans-serif;
    font-weight:bold;
    padding: 0 14px 0 3px;
    /*margin-bottom:10px*/
}
.table_truck .truck_para{
    font-family:Arial, Helvetica, sans-serif;
    font-weight:bold;
    padding-left:3px;
}

显然,这并没有选择随机三元组,但是第一批k个MD5序列的受试者的集合应该具有统计学上显着的样本的相关特征(即样本代表整个人口,没有特定的选择偏压)。

答案 5 :(得分:0)

SELECT ?s WHERE { 
    ?s ?p ?o . 
    bind(<SHORT_OR_LONG::bif:rnd> (10, ?s, ?p, ?o) as ?rid)
}
ORDER BY ?rid
LIMIT 10

这个怎么样?

&LT; SHORT_OR_LONG :: BIF:RND&GT;可能比&lt; bif:rnd&gt;更好。 (http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VirtTipsAndTricksGuideRandomSampleAllTriples

你只需将随机id(?rid)绑定到每一行绑定(?s?p?o),然后按随机id排序结果。

答案 6 :(得分:0)

经过大量的实验,我最终得到了以下解决方案,这些组合使用散列来避免对RAND()进行静态求值,而使用RAND()来避免仅使用散列而导致的选择偏差。

SELECT ?s WHERE {
  ?s ?p ?o .
  BIND(SHA512(CONCAT(STR(RAND()), STR(?s))) AS ?random) .
} ORDER BY ?random
LIMIT 1

用于从Wikidata中选择随机的山谷冰川:

SELECT ?item ?itemLabel ?random WHERE {
  ?item wdt:P31 wd:Q11762356 .
  BIND(SHA512(CONCAT(STR(RAND()), STR(?item))) AS ?random) .
  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE], en" . }
} ORDER BY ?random
LIMIT 1

Try it(该服务会缓存响应,您可以在运行查询之前仅做一个新注释就可以绕开它)