Alignement de wikidata avec le catalogue de la BnF

De Bibliopedia
Aller à : navigation, rechercher

Alignement de Wikidata et du catalogue de la BnF avec OpenRefine[modifier]

  • Auteur : Sylvain Machefert
  • Date : juillet 2017


Contexte[modifier]

Conversation à l'origine de cette expérience

En juin 2017, la BnF a ouvert un serveur SRU permettant d'accéder aux données de son catalogue. Cette ouverture intervenait juste après les élections législatives françaises et a été l'occasion de faire un état des lieux de la couverture par le fichier d'autorité de la BnF des députés à partir de leurs fiches sur wikidata. La conversation lancée sur Twitter avec Étienne Cavalié de la BnF et reproduite ci-contre m'a donné envie d'en savoir plus et d'en profiter pour tester le serveur SRU de la BnF en le combinant à OpenRefine.

Identification sur Wikidata des députés n'ayant pas d'attribut "Identifiant BnF"[modifier]

Chaque fiche wikidata pour un sujet donné comporte un certain nombres d'attributs avec pour chacun une ou plusieurs valeurs. Ces attributs sont des "propriétés" au sens wikidata, et il en existe plusieurs milliers. Parmi ces propriétés, de nombreuses concernent des identifiants d'autorité et parmi celles-ci, celle qui nous intéressent est la [https://www.wikidata.org/wiki/Property:P268 P268 : Identifiant bibliothèque nationale de France]. Elle permet d'aligner une fiche de personne sur wikidata avec la notice d'autorité en saisissant l'identifiant unique de la notice d'autorité sur le catalogue de la BnF.

Wikidata dispose d'un endpoint Sparql qui permet de faire des interrogations assez poussées sur le contenu de la base wikidata. La requête qui nous intéresse aujourd'hui est relativement simple (voir les exemples sur Wikidata pour se convaincre de la "relative" simplicité de celui-ci).

select ?depute ?nom ?idBnF ?ddn where {
?depute p:P39 ?statement.
?statement pq:P2937 wd:Q24939798.
OPTIONAL {?depute wdt:P268 ?idBnF} .
OPTIONAL {?depute wdt:P569 ?ddn} .
?depute rdfs:label ?nom.
FILTER (langMatches(lang(?nom), "fr"))}
Cliquez pour essayer !

Cette requête retourne une liste de députés ayant pour "fonction" (P39) ?statement avec ?statement ayant pour qualificatif "législature" (P2937) : "15e législature de la Cinquième République française" (Q24939798). On récupère de manière optionnelle l'identifiant BnF (P268) et la date de naissance qui nous sera utile pour un contrôle manuel vis-à-vis des fichiers BnF propriété P569) et on affiche tout cela.

Enrichissement du fichier via SRU[modifier]

À partir de là et avant que le travail décrit ici j'avais une liste de 477 députés (tous n'étaient pas encore correctement identifié comme députés de cette législature, on est bien à 577 aujourd'hui, restera à faire retourner le script), dont 381 sans notice d'autorité BnF signalé sur leur notice wikidata. J'ai extrait le fichier depuis le endpoint SPARQL au format CSV puis l'ai chargé dans OpenRefine.

L'idée étant de compléter, pour les députés sans identifiant BnF, les informations disponibles avec le résultat des interrogations du catalogue SRU sur la chaîne nom prénom. Le processus suivi est le suivant (je ne détaille pas les opérations effectuées, les personnes intéressées trouveront le Json du projet à la fin de l'article).

  • Limitation aux députés dans identifiant BnF sur wikidata
  • Interrogation du serveur SRU de la BnF pour récupérer les autorités correspondant au champ nom/prénom de notre fichier source : URL supprimée en attente d'ouverture oficielle]/SRU?version=1.2&operation=searchRetrieve&query=(aut.type%20any%20"pep%20org")%20and%20(aut.accesspoint%20all%20"' + value.escape("url") + '")%20and%20(aut.status=validated) (compléments envoyés par E. Cavalié: il faudrait plutôt aut.accesspoint adj "nom prenom" (voire aut.accessoint adj "nom prenom annee de naissance"). "Adj" permet de chercher l'expression exacte, qui pour un nom de personne correspond à l'expression "Nom Prenom Date de naissance - Date de mort")
  • Analyse du nombre de résultats pour se limiter aux lignes pour lesquelles le serveur ne retourne qu'un résultat, on ne s'embête pas avec les homonymies (même si on pourrait/devrait bien entendu...)
  • On transforme le résultat XML de la BnF en un json, plus facile à traiter dans OpenRefine.
  • On crée une colonne "BnF nom" en concaténant le nom et le prénom fourni par le serveur SRU pour comparer facilement avec le libellé côté wikidata
  • On crée une colonne "BnF date de naissance" pour vérifier facilement que c'est la même personne que sur wikidata
  • On crée une colonne "BnF bio" qui va encore une fois nous permettre de désambiguïser facilement.
  • Et enfin on crée une colonne Identifiant à partir du permalien ark proposé par la BnF. Wikidata a choisi d'utiliser pour identifiant des notices d'autorité BnF la partie située après ark:/12148/cb dans les ark.

Une fois ces opérations effectuées, on se retrouve avec 39 enregistrements potentiellement intéressants, il reste à faire un contrôle manuel avant import. Le contrôle manuel permet d'exclure un certain nombre de notice qui selon toute vraisemblance sont des homonymes (pour cause de dates de naissance grandement incompatible en particulier).

Alimentation de Wikidata[modifier]

La liste d'équivalence Entrée wikidata ←→ Id BnF peut être chargée assez simplement à l'aide de l'outil QuickStatements qui permet d'envoyer en série des instructions de création de données à wikidata à partir d'un fichier tabulé.

Traitements ultérieurs[modifier]

Extension à l'ensemble des députés[modifier]

En discutant sur Twitter de cette première réalisation un "wikidatien" s'est interrogé sur la pertinence d'étendre cela à l'ensemble des députés et cela s'est avéré une bonne idée :) L'opération la plus fastidieuse du test initial était le contrôle manuel de l'absence d'homonymie, la plupart des députés du moment n'ayant pas forcément leur date de naissance complétée côté BnF. En s'attaquant à l'historique on a cependant plus de chance d'avoir des notices d'autorité complètes et des dates de naissance présentes. L'idée est donc d'utiliser le SRU pour trouver les députés à partir de la chaine "Nom prénom année de naissance". On en loupe sûrement un certain nombre mais au moins ceux que l'on récupère ont une forte probabilité d'être les bons.

La requête SPARQL devient donc (je me rends compte après coup qu'elle peut être simplifiée mais je laisse celle que j'ai utilisée) :

select ?depute ?nom ?idBnF (YEAR(?ddn) as ?year) where {
?depute wdt:P39 wd:Q3044918 .
OPTIONAL {?depute wdt:P268 ?idBnF} .
OPTIONAL {?depute wdt:P569 ?ddn} .
MINUS { ?depute wdt:P268 [] } .
?depute rdfs:label ?nom.
FILTER (langMatches(lang(?nom), "fr"))}
Cliquez pour essayer !

On récupère 11 195 députés n'ayant pas d'identifiant BnF. À partir de cette liste on peut interroger le serveur SRU mais en utilisant l'index suggéré par Étienne Calavié avec donc une requête du type : 'http://##serveur SRU##/SRU?version=1.2&operation=searchRetrieve&query=(aut.type%20any%20"pep%20org")%20and%20(aut.accesspoint%20adj%20"' + value.replace(/^(.*) ([^ ]*)$/, "$2 $1").escape("url") + "+" + cells["year"].value+ '")' (en gros on inverse nom et prénom trouvés sur wikidata et on concatène l'année de naissance qui se trouve dans une autre colonne.

Le reste des opérations appliquées est le même et on se trouve avec 1034 nouveaux identifiants BnF qui ont le même nom + prénom + année de naissance que sur wikidata. On peut penser qu'ils correspondent au même personne. Pour limiter le risque d'erreurs, ont été importés :

  • 765 personnes dont la biographie BnF contient "député"
  • 86 personnes dont la biographie BnF contient "politique"

À partir de là il me reste 183 personnes pour lesquelles j'ai le même nom et prénom et la même année de naissance mais dont rien dans la bio n'indique qu'ils sont députés ou politique. Pour éviter d'introduire des doublons, j'ai donc repris ma requête SPARQL pour ajouter la date de naissance complète, je l'ai réinjecté dans mon fichier à coup de RECHERCHEV dans libreoffice (OpenRefine ne permet pas de le faire simplement à ma connaissance) et j'ai utilisé le champs date de la BnF pour en extraire la date de naissance sur 8 chiffres à l'aide de la requête GREL suivante : cells["BNF - Date de naissance"].value.strip().trim().replace(/^([^ ]*).*/, "$1") (ce champs a la forme " 17270307 18190112 "). À partir de là j'ai créé une "Custom text facet" : cells["DDN"].value==cells["DDN - BnF"].value qui me permet de trouver 79 nouveaux députés avec la même date de naissance au jour près entre BnF et Wikidata, on peut donc sans risque les importer.

Les 57 restants sont disponibles ici je pense qu'ils doivent pouvoir être importés sans trop de risque de création de doublon mais dans le doute je m'abstiens.

Test sur les écrivains français[modifier]

En partant du principe que tout écrivain français devrait avoir une notice d'autorité à la BnF, avec la requête suivante (1384 résultats) :

SELECT distinct ?s ?writer ?birthDate
WHERE
{
  {?s wdt:P106 wd:Q36180 .} 
  UNION 
  { ?s wdt:P106 wd:Q482980 . }
  UNION
  { ?s wdt:P106 wd:Q49757 . }
  
  ?s wdt:P569 ?birthDate . 
  ?s wdt:P27 wd:Q142
  OPTIONAL {
     ?s rdfs:label ?writer filter (lang(?writer) = "fr").
   }
  MINUS {
    ?s wdt:P268 []
  }
  FILTER (?birthDate >= "1800-01-01T00:00:00Z"^^xsd:dateTime) .
}
Cliquez pour essayer !

on peut appliquer les mêmes principes que précédemment et on se retrouve avec 233 nouveaux identifiants à ajouter à wikidata. Il reste donc 1151 notices de nature "écrivain", "auteur" ou "poète" de nationalité française et qui n'ont pas d'identifiant BnF, sûrement des manques à combler mais l'automatisation semble atteindre ses limites ici.

Compléments[modifier]

  • Plus d'exemples d'utilisation d'OpenRefine sur OpenRefine : exemples
  • Fichier JSON des opérations pour OpenRefine, à appliquer via Undo/Redo > Apply :