【问题标题】:sparql: randomly select one connection for each nodesparql:为每个节点随机选择一个连接
【发布时间】:2015-03-17 15:23:27
【问题描述】:

我有以下数据:

<node:1><urn:connectTo><node:2>
<node:1><urn:connectTo><node:3>
<node:1><urn:connectTo><node:4>
<node:2><urn:connectTo><node:10>
<node:2><urn:connectTo><node:11>
<node:2><urn:connectTo><node:12>
<node:3><urn:connectTo><node:21>
<node:3><urn:connectTo><node:13>
<node:3><urn:connectTo><node:41>
<node:3><urn:connectTo><node:100>
<node:4><urn:connectTo><node:119>
<node:4><urn:connectTo><node:120>

如您所见,每个节点都有多个连接。我想为每个节点随机选择一个连接。我怎样才能做到这一点?我尝试了以下查询,但都没有解决问题:

  1. select ?currentNode ?nextNode where {
      ?currentNode ?p ?nextNode
      BIND(RAND() AS ?orderKey)
    }
    ORDER BY ?orderKey
    LIMIT 1
    
  2. select ?currentNode SAMPLE(?nextNode) as ?nextNode1
    where {
      ?currentNode ?p ?nextNode
    }
    GROUP BY ?currentNode
    

    注意:结果给出了每个节点的第一个连接,但不是随机的

  3. select ?currentNode ?nextNode (COUNT(?nextNode) AS ?noOfChoices)
    where {
      ?currentNode ?p ?nextNode
      BIND(RAND() AS ?orderKey)
    }
    GROUP BY ?currentNode
    ORDER BY ?orderKey
    OFFSET (RAND()*?noOfChoices)
    LIMIT 1
    

【问题讨论】:

  • 样品肯定是要走的路。您是否尝试过将 1) 与 2) 混合使用?即随机排序,然后分组抽样。 (我怀疑我们处于未定义行为的领域)
  • 对带有 rand 的子查询的结果使用 sample 可以获得您想要的结果,至少在使用 Apache Jena 时是这样。但是,我认为这种行为是有保证的。

标签: random rdf sparql semantic-web


【解决方案1】:

sample aggregate 返回组内的个人:

Sample 是一个集合函数,它从 多集传递给它。 … 例如,给定 Sample({"a", "b", "c"})、"a"、"b" 和 "c" 都是有效的返回值。注意 Sample() 不需要对于给定的输入是确定性的, 唯一的限制是输出值必须存在于输入中 多集。

这将是一个类似的查询:

prefix node: <node:>
prefix urn: <urn:>

select ?source (sample(?_target) as ?target) where {
  ?source urn:connectTo ?_target
}
group by ?source

---------------------
| source | target   |
=====================
| node:1 | node:2   |
| node:2 | node:10  |
| node:3 | node:13  |
| node:4 | node:119 |
---------------------

当然,正如您所注意到的,实现只需要返回一个任意个体。这很容易每次都相同。您可以在子查询中进行一些排序,并希望随机化目标的顺序以便从 sample 中获得不同的结果,但不要求结果的顺序来自子查询也被保留。看起来像这样:

prefix node: <node:>
prefix urn: <urn:>

select ?source (sample(?_target) as ?target) where {
  { select ?source ?_target {
      ?source urn:connectTo ?_target
    }
    order by rand() }
}
group by ?source

这似乎适用于 Apache Jena。以下是重复调用的结果:

---------------------
| source | target   |
=====================
| node:1 | node:2   |
| node:2 | node:11  |
| node:3 | node:100 |
| node:4 | node:120 |
---------------------

---------------------
| source | target   |
=====================
| node:1 | node:3   |
| node:2 | node:11  |
| node:3 | node:13  |
| node:4 | node:120 |
---------------------

---------------------
| source | target   |
=====================
| node:1 | node:3   |
| node:2 | node:10  |
| node:3 | node:21  |
| node:4 | node:119 |
---------------------

---------------------
| source | target   |
=====================
| node:1 | node:3   |
| node:2 | node:10  |
| node:3 | node:100 |
| node:4 | node:119 |
---------------------

【讨论】:

  • 你好约书亚,你是男人!!!你的询问真的帮助了我。非常感谢!只是另一个一般性问题:有没有办法根据其他类型的分布而不是均匀分布(这是我们所说的“随机”?)对结果进行采样。感觉 Sparql 不提供这样做的灵活性。
  • @daydayup 我不知道。它仍然是一个相对年轻的标准,并且该标准不包括很多功能。然而,许多实现提供了额外的功能或方法来实现扩展。您可以查看实施文档。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
相关资源
最近更新 更多