Как выбрать случайные узлы DBPedia из SPARQL? - PullRequest
5 голосов
/ 15 апреля 2011

Как выбрать случайную выборку из DBpedia с использованием конечной точки sparql?

Этот запрос

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

(найден здесь ), кажется, работает нормально на большинстве SPARQLконечные точки, но на http://dbpedia.org/sparql он кэшируется (поэтому он всегда возвращает одни и те же 10 узлов).

Если я пытаюсь из JENA, я получаю следующее исключение:

Unresolved prefixed name: bif:rnd

И я не могу найти, что такое пространство имен 'bif'.

Есть идеи, как это решить?

Мулон

Ответы [ 6 ]

9 голосов
/ 15 апреля 2011

В 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

Но я думаю, что это еще менее вероятно, будет оптимизировано.

6 голосов
/ 15 апреля 2011

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, и ваш запрос будет намного более эффективным.

1 голос
/ 17 ноября 2016

Ни один из вышеперечисленных методов не работает с Jena / Fuseki, поэтому я сделал это по-другому:

SELECT DISTINCT ?s ?p ?o
{
  ?s ?p ?o.
  BIND ( MD5 ( ?s ) AS ?rnd)
}
ORDER BY ?rnd ?p
LIMIT 100

Очевидно, что это не выбирает случайные тройки, но набор первых k MD5-упорядоченных субъектов должен иметь соответствующие характеристики статистически значимой выборки (т. Е. Выборка является репрезентативной для всей популяции, особого смещения отбора нет) .

1 голос
/ 02 февраля 2016

Я столкнулся с той же проблемой, и ни одно из решений здесь не решило мою проблему. Вот мое решение; это было нетривиально и довольно взломать. На данный момент это работает для 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 выполнялся нормально.

Это работает только потому, что разработчики не зашли так далеко в своей статической оценке кода выражений. Они могли бы легко написать ветку для «умножить на ноль», но, увы, не сделали:)

1 голос
/ 18 апреля 2011

bif: rnd - это расширение, специфичное для Virtuoso, поэтому оно будет работать только снова, конечные точки Virtuoso SPARQL.

bif - это префикс встроенных функций Virtuoso, которые позволяют вызывать любую функцию Virtuoso.в SPARQL, где rnd является функцией Virtuoso для возврата случайных чисел.

0 голосов
/ 23 сентября 2016
SELECT ?s WHERE { 
    ?s ?p ?o . 
    bind(<SHORT_OR_LONG::bif:rnd> (10, ?s, ?p, ?o) as ?rid)
}
ORDER BY ?rid
LIMIT 10

Как насчет этого?

может быть лучше, чем . (http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VirtTipsAndTricksGuideRandomSampleAllTriples)

Вы просто привязываете случайный идентификатор (? Rid) к каждой строке привязки (? S? P? O), затем упорядочиваете результаты по случайному идентификатору.

...