2011-04-15 16 views
5

¿Cómo puedo seleccionar una muestra aleatoria de DBpedia usando el punto final sparql?¿Cómo seleccionar nodos de DBPedia aleatorios desde SPARQL?

Esta consulta

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

(encontrado here) parece que funciona bien en la mayoría de los puntos finales de SPARQL, pero en http://dbpedia.org/sparql se pone en caché (por lo que siempre devuelve los mismos 10 nodos).

si trato de Jena, me sale el siguiente excepción:

Unresolved prefixed name: bif:rnd 

Y no puedo encontrar el lo que el espacio de nombres 'BIF' es.

¿Alguna idea sobre cómo solucionar esto?

Mulone

Respuesta

6

bif:rnd no es estándar SPARQL y por lo tanto no es portátil a cualquier SPARQL endpoint. Puede usar LIMIT, ORDER y OFFSET para simular una muestra aleatoria con una consulta estándar. Algo así como ...

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

Dónde some_random_number es un número que se genera por la aplicación. Esto debería evitar el problema de almacenamiento en caché, pero esta consulta es de todos modos bastante costosa y no sé si los puntos finales públicos lo soportarán.

Trate de evitar los patrones completamente abiertos como ?s ?p ?o y su consulta será mucho más eficiente.

+0

Supongo que el problema con su solución es que el orden de selección no cambia, por lo que no es realmente aleatorio. Tal vez podría mejorar su "aleatoriedad" reuniendo muestras de diferentes consultas, algo así como (consulta con desplazamiento x1) UNIÓN (consulta con desplazamiento x2) UNIÓN (consulta con desplazamiento xn) UNIÓN. – Mulone

+2

Mi orden de selección no es aleatoria, pero un DESPLAZAMIENTO sobre un número aleatorio le dará una muestra aleatoria. Es el DESPLAZAMIENTO lo que debe generarse al azar. –

8

En SPARQL 1.1 que puede hacer:

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

No sé cuántos improvisada tienda de optimizará, o incluso poner en práctica esta todavía sin embargo.

[ver comentario más abajo, esto no funciona bastante]

Una alternativa es:

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

Pero yo pensaría que es incluso menos probabilidades de ser optimizado.

+0

En realidad, el segundo no funcionará, SAMPLE() devuelve un valor arbitrario. pero no al azar. –

+1

rand() no está disponible en todos los puntos finales sparql :-( – Mulone

+0

Solo agregaría 'DISTINCT': SELECT DISTINCT? S –

1

bif: rnd es una extensión específica de Virtuoso y, por lo tanto, solo volverá a funcionar los puntos finales Virtuoso SPARQL.

bif es el prefijo de Virtuoso Built In Functions que permite llamar a cualquier función Virtuoso en SPARQL, siendo rnd una función Virtuoso para devolver números aleatorios.

0

Me encontré con el mismo problema y ninguna de las soluciones aquí solucionó mi problema. Aquí está mi solución; no fue trivial y bastante pirata. Esto funciona para DBPedia a partir de ahora, y puede funcionar para otros puntos finales SPARQL, pero no se garantiza que funcione para versiones futuras.

DBPedia utiliza Virtuoso, que admite un argumento no documentado para la función RAND; el argumento especifica efectivamente el rango a usar para el PRNG.El juego consiste en engañar a Virtuoso en la creencia de que el argumento de entrada no puede ser estática evaluado antes se calcula cada fila, lo que fuerza el programa para evaluar RAND() para cada unión:

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

La magia sucede en rand(1 + strlen(str(?s))*0) que genera el equivalente de rand(); pero lo fuerza a funcionar en cada partido explotando el hecho de que el programa no puede predecir el valor de una expresión que involucra alguna variable (en este caso, simplemente calculamos la longitud del IRI como una cadena). La expresión real no es importante, ya que la multiplicamos por 0 para ignorarla por completo, luego agregamos 1 para hacer que rand se ejecute normalmente.

Esto solo funciona porque los desarrolladores no llegaron tan lejos en su evaluación de código estático de expresiones. Podrían haber escrito fácilmente una rama para "multiplicar por cero", pero lamentablemente no lo hicieron :)

1

Ninguno de los métodos anteriores funciona con Jena/Fuseki, por lo que lo he hecho de otra manera:

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

Obviamente, esto no selecciona al azar triples, pero el conjunto de la primera k MD5 los sujetos ordenados deben tener características relevantes de una muestra estadísticamente significativa (es decir, la muestra es representativa de toda la población, no existe un sesgo de selección particular).

Cuestiones relacionadas