J’ai eu besoin du nombre d’entités distinctes décrites dans dbpedia-fr. Nous allons voir un problème à prendre en compte lors de l’utilisation des données liées faisant appel à des points d’accès publics.
Ma première tentative a été d’obtenir cette information avec la requête
select count(distinct ?r) where { ?r ?p ?l }
mais celle-ci échouait systématiquement sur un timeout.
Alors que si je me limitais à compter les triplets avec
select count(?r) where { ?r ?p ?l }
j’obtenais
185404575
Nandana Mihindukulasooriya m’a indiqué l’outil Loupe pour connaître des statistiques sur des jeux de données, mais je voulais pouvoir obtenir l’information directement par programme en interrogeant la source que j’utilisais: ici, DBPedia-Fr, mais potentiellement avec une méthode applicable à d’autres jeux de données.
Hugh Williams m’a indiqué que ma requête était fortement consommatrice de ressources (dans l’implémentation de Virtuoso qui héberge DBPedia et qui, semble-t-il passe par la construction d’une très grande table de hashage). Il m’a signalé que DBPedia (anglais) propose une description à jour de son jeux de données suivant les principes proposé par la note technique sur VoID: VoID pour DBPedia; cela évite que des requêtes lourdes à traiter soient effectuées de façon répétitives pour obtenir ces informations. Mais la version française ne propose pas cela à la date de rédaction de ce billet.
John Walker m’a proposé de réécrire ma requête de la façon suivante:
select (count(?s) as ?c) where { select distinct ?s where { ?s ?p []} }
il semble que cette écriture consomme moins de ressources, et j’obtiens le résultat attendu:
10515620
Pourquoi cette écriture est plus efficace que l’autre? Elle me semble sémantiquement équivalente; il faudrait donc comprendre le détail de la façon dont elle est implémentée pour imaginer quelle écriture est préférable. A ce sujet, on trouve un chapitre entier sur l’optimisation de requêtes dans le très bon livre de Bob du Charme sur SPARQL.
Alasdair J G Gray me signale le rapport Dataset Descriptions: HCLS Community Profile et en particulier la section 6.6 où des exemples de statistiques à obtenir sur des jeux de données sont présentés avec les requêtes SPARQL qui permettent de les obtenir.
Les résultats ci-dessous correspondent à l’application de ces requêtes à DBPedia-Fr.
Description | Requete | Resultat |
---|---|---|
Number of triples | SELECT (COUNT(*) AS ?triples) { ?s ?p ?o } | 185404575 |
Number of distinct typed entities | SELECT (COUNT(DISTINCT ?s) AS ?entities) { ?s a [] } | 6015375 |
Number of distinct subjects | SELECT (COUNT(DISTINCT ?s) AS ?distinctSubjects) { ?s ?p ?o } | time out |
Number of distinct properties | SELECT (COUNT(DISTINCT ?p) AS ?distinctProperties) { ?s ?p ?o } | 20321 |
Number of distinct non-literal objects | SELECT (COUNT(DISTINCT ?o ) AS ?distinctObjects){ ?s ?p ?o FILTER(!isLiteral(?o)) } | time out |
Number of distinct classes | SELECT (COUNT(DISTINCT ?o) AS ?distinctClasses) { ?s a ?o } | 442 |
Number of distinct literal objects | SELECT (COUNT(DISTINCT ?o) AS ?distinctLiterals) { ?s ?p ?o filter(isLiteral(?o)) } | time out |
Number of graphs in the data set | SELECT (COUNT(DISTINCT ?g ) AS ?graphs) { GRAPH ?g { ?s ?p ?o }} | 14 |
Les mêmes requêtes appliquées à DBPedia donnent:
Description | Requete | Resultat | Donnes VoID |
---|---|---|---|
Number of triples | SELECT (COUNT(*) AS ?triples) { ?s ?p ?o } | 438038746 | 438038866 |
Number of distinct typed entities | SELECT (COUNT(DISTINCT ?s) AS ?entities) { ?s a [] } | rien | |
Number of distinct subjects | SELECT (COUNT(DISTINCT ?s) AS ?distinctSubjects) { ?s ?p ?o } | rien | 33996245 |
Number of distinct properties | SELECT (COUNT(DISTINCT ?p) AS ?distinctProperties) { [] ?p ?o } | 64119 | 64119 |
Number of distinct non-literal objects | SELECT (COUNT(DISTINCT ?o ) AS ?distinctObjects){ ?s ?p ?o FILTER(!isLiteral(?o)) } | rien | 164615518 (?) |
Number of distinct classes | SELECT (COUNT(DISTINCT ?o) AS ?distinctClasses) { [] a ?o } | 370680 | 370680 |
Number of distinct literal objects | SELECT (COUNT(DISTINCT ?o) AS ?distinctLiterals) { ?s ?p ?o filter(isLiteral(?o)) } | 29883287 | |
Number of graphs in the data set | SELECT (COUNT(DISTINCT ?g ) AS ?graphs) { GRAPH ?g { ?s ?p ?o }} | 19 | |
Number of distinct objects | 164615518 |
Pour obtenir certains résultats, il a fallu augmenter le temps accordé à la requête pour être traitée; pour d’autres, la requête proposée dans le document ci-dessus a été un peu modifiée. DBPedia ne provoque pas de ‘time out’, mais renvoie une réponse vide quand il n’a pas pu traiter la requête (voir discussion ici). Les gestionnaires de DBPedia proposent de ne pas considérer leur serveur comme serveur de production et d’en installer une copie si on veut des résultats plus garantis; en effet, ils doivent faire face à une grande masse d’utilisateurs et ne peuvent offrir une totale garantie de service. Il en résulte que certaines requêtes, même en augmentant le délai de traitement, on n’obtient pas de résultat.
On constate néanmoins que DBPedia fait un usage beaucoup plus intensif des classes que DBPedia-Fr. Je reviendrais sur l’usage des classes dans un prochain billet.
Nous avons vu ici des contournements à certains problèmes de délai de traitement de certaines requêtes; mais ces contournements ne marchent pas toujours, même sur des requêtes qui paraissent simples et d’usage élémentaire (compter certains types d’éléments dans un jeu de données).
Mise à jour du 20/4/2018
Kingsley Idehen me pointe sur
https://medium.com/virtuoso-blog/dbpedia-usage-report-as-of-2018-01-01-8cae1b81ca71
et plus précisément à la section Virtuoso « Anytime Query » qui montre comment DBPedia ajoute un en-tête dans la réponse pour donner une alerte sur les résultats incomplets lorsque le timeout est atteint