forked from Madouck/wikidata_sparql_rzine
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.Rmd
1956 lines (1376 loc) · 102 KB
/
index.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "*Spatio-temporal Wikidata*. Exploration de données ouvertes et liées du web 3.0"
subtitle: "Histoire de cadre : élaboration d'une trajectoire spatio-temporelle"
date: "`r Sys.Date()`"
author:
- name: Raphaëlle KRUMMEICH
affiliation: IDEES, UMR6266 - université de Rouen Normandie, CNRS
- name: Hugues PECOUT
affiliation: Géographie-cités, UMR8504 - CNRS
- name: Sébastien REY-COYREHOURCQ
affiliation: IDEES, UMR6266 - université de Rouen Normandie, CNRS
image: "figures/Rplot.png"
logo: "figures/rzine.png"
output:
rzine::readrzine:
highlight: kate
number_sections: true
csl: Rzine_citation.csl
bibliography: biblio.bib
nocite: |
@*
link-citations: true
github: "rzine-reviews/wikidata_sparql_rzine"
# gitlab: "https://gitlab.huma-num.fr/gt-notebook/workshop/workshop_3_decembre_2021/atelier_notebooks"
doi: "xx.xxx/xxxx.xxxxxxx"
licence: "by-nc-sa"
# Only Creative Commons Licence
# 5 possible choices : "by-nd", "by", "by-nc-sa", "by-nc","by-sa"
---
```{r configuration, include=FALSE}
## Global options
knitr::opts_chunk$set(echo=TRUE,
cache=FALSE,
prompt=FALSE,
comment=NA,
message=FALSE,
warning=FALSE,
class.source="bg-info",
class.output="bg-warning")
```
> Cet article est le fruit d'un dialogue interdisciplinaire entre membres du [GT Notebook](https://gt-notebook.gitpages.huma-num.fr/site_quarto/){target="_blank"} initié dans le cadre d'un [atelier](https://gt-notebook.gitpages.huma-num.fr/workshop/workshop_3_decembre_2021/slide2html-3-dec/){target="_blank"} proposé à la [*Journée d’études normande sur les données de la recherche*](https://www.unicaen.fr/evenement/journee-detude-normande-sur-les-donnees-de-la-recherche/){target="_blank"} qui s'est déroulée en décembre 2021. L'association de plusieurs compétences et disciplines a abouti à ce *notebook*. Il présente une analyse exploratoire reproductible de données ouvertes et liées d'un fragment de graphe Wikidata, interrogeables sous la forme de triplets RDF. Les enjeux d'un tel processus inter-disciplinaire sont esquissés en conclusion. Une ébauche des requêtes SPARQL élaborées a fait l'objet d'une présentation et d'échanges au sein des [Ateliers du Web Sémantique](https://les-ateliers-du-web-semantique.gitpages.huma-num.fr/les-ateliers-du-web-semantique/){target="_blank"} au printemps 2021.
# Introduction {-}
Cet article présente une exploration du graphe Wikidata (cf. [parties 1.2](#standard-rdf-du-w3c) et [3](#exploration-du-graphe-wikidata)) et le traitement des données extraites (cf. [parties 2](#packages-et-données) et [4](#exploration-spatiale)).
Du requêtage en langage SPARQL (cf. [partie 1.3](#le-langage-sparql)) au traitement et à la représentation des données issues du graphe Wikidata, ce document présente, étape par étape, l'ensemble de la chaîne de traitement réalisée. Le processus exploratoire, parfois itératif, a été conservé afin de mieux comprendre l'approche réflexive des auteurs et autrice. Le *notebook* retranscrit les démarches scientifique et méthodologique adoptées.
Le schéma organisant ces données est esquissé dans la [partie 1](#wikimédia-wikidata-w3c). Afin de permettre une reproduction des traitements et des résultats présentés, les données automatiquement collectées au `r format(Sys.time(), "%d %B %Y")` et utilisées dans ce document sont mises à disposition (cf. [partie 2.2](#données-collectées)). L'idée de départ conduit à la démarche suivante en 3 étapes :
- requêter les données (ou suivre des chemins) du graphe Wikidata,
- identifier certaines des modalités du graphe pouvant comporter une dimension spatiale et temporelle et ainsi,
- reconstruire et représenter une ou des trajectoires dans le temps et l'espace.
Compte-tenu du [formalisme](https://www.wikidata.org/wiki/Wikidata:WikiProject_Ontology/Modelling){target="_blank"} et de l’hétérogénéité des données non supervisées de Wikidata, deux images d'objet sont choisies pour l'étude : un artiste-peintre et une de ses peintures, exposée au sein de musées ou d'institutions culturelles dans le monde. Pour reproduire partiellement l'expérimentation, un exemple d'exploration du graphe Wikidata pour diverses images d'artistes-peintres est proposée dans la [partie 7](#à-vous-dexplorer).
<br/><br/>
---
*NB : le terme "image" utilisé dans ce document correspond à une sémantique de l'individu présent dans l'espace numérique sous la forme de données et de métadonnées en relation avec d'autres images d'objet, selon @hui_induction_2015. En ce sens, les œuvres elles-mêmes, photographiées ou scannées etc. sous les formes de fichiers d'extension .jpg .png etc. sont désignées par le terme d'"illustration" ou de fichiers. Pour simplifier le discours, l'image d'individu est désignée par l'individu lui-même : par exemple, l'image du peintre Johannes Vermeer, l'entité Wikidata de valeur [`Q41264`](https://www.wikidata.org/wiki/Q41264){target="_blank"} définie par ses relations dans l'espace numérique, est désignée par Johannes Vermeer ou Vermeer. Le fichier .jpg Wikidmédia de son auto-portrait supposé, fragment de l’œuvre intitulée «l'Entremetteuse», est une illustration représentant le peintre.*
---
# Wikimédia, Wikidata & W3C
## Données ouvertes et liées du graphe Wikidata
Wikidata est une base de connaissances libre, éditée de manière collaborative et hébergée par la [fondation Wikimedia](https://wikimediafoundation.org/fr/){target="_blank"}. Son contenu étant placé sous [licence CC0](https://creativecommons.org/publicdomain/zero/1.0/deed.fr){target="_blank"} (« Transfert dans le Domaine Public »), elle permet de centraliser l'accès aux données utilisées par différents [projets Wikimedia](https://www.wikimedia.fr/les-projets-wikimedia/){target="_blank"} (@frwiki:186068284).
Les informations saisies dans Wikidata sont des données ouvertes “brutes” multilingues non-supervisées qui sont liées, notamment aux articles de l'encyclopédie contributive Wikipedia. Wikidata est à différencier de l'ontologie DBpedia^[DBpedia est une ontologie permettant de traduire Wikipedia en dépôts de données définis dans le cadre de description des ressources du standard *Ressources Description Framework* (RDF) du *World Wide Web Consortium*^[Le **World Wide Web Consortium**, abrégé par le sigle **W3C**, est un organisme de standardisation à but non lucratif, fondé en octobre 1994 chargé de promouvoir la compatibilité des technologies du *World Wide Web* telles que HTML5, HTML, XHTML, XML, RDF, SPARQL, CSS, XSL, PNG, SVG, MathML et SOAP.] (W3C)] (figure 1) au sens où l'ontologie sous-jacente de Wikidata n'est pas formalisée à priori - ce qui est le cas de DBpedia, mais elle émerge des usages et pratiques de la communauté Wikidata. En effet, les deux dispositifs à vocation encyclopédique diffèrent dans leurs finalités initiales. DBpedia est un effort de la communauté scientifique pour extraire des informations structurées du projet encyclopédique Wikipedia et les lier à d'autres formalismes de données du web sémantique. Wikidata est un dispositif de *curation*^[Le terme de *curation* est un anglicisme désignant une activité de type archivistique ou de conservation muséale ou patrimoniale qui a pour objectif de décrire et de classer des objets pour les conserver et les rendre accessibles, le cas échéant. Le terme est issu du domaine médical au sens de prendre soin en opérant une stratégie curative. La *curation* de données peut-être décrite comme une activité de description d'une donnée ou plus précisément d'une ressource du web au moyen de métadonnées, c'est à dire de produire des données sur des données. Cette activité s'appuie en général sur des normes ou des règles de l'art des divers métiers. Dans le champ du catalogage informatique, une des plus anciennes normes est le Dublin Core.] ou d'annotation de données par les contributeurs et contributrices de Wikipedia ou Wikidata.
```{r figure 1, out.width="80%", fig.align = 'center', echo=FALSE, purl = FALSE }
knitr::include_graphics('figures/wikidata_vs_dbpedia.png')
```
<center>
*Figure 1 : Principales différences entre des données Wikipedia (DBpedia) et des données Wikidata. Dbpedia est la façon dont Wikipedia est traduit en dépôts de triplets RDF statique. <br/>Source : [Wikidata-Basics | Wikidata Hackathon event for the Festival of Creative Learning, 2018](https://thinking.is.ed.ac.uk/wikidata-basics/faq-and-further-reading/){target="_blank"}*
</center>
<br/>
La base Wikidata fournit un support à de nombreux autres sites et services au-delà des seuls projets de Wikimedia. Son contenu est exporté dans des formats standards et peut être lié ou aligné à d'autres ensembles de données ouvertes sur le Web des données^[Le **Web de données** (*linked data*, en anglais) est une initiative du *World Wide Web* Consortium^[Le **W3C** est un organisme de standardisation à but non lucratif, fondé en octobre 1994 chargé de promouvoir la compatibilité des technologies du *World Wide Web* telles que HTML5, HTML, XHTML, XML, RDF, SPARQL, CSS, XSL, PNG, SVG, MathML et SOAP.] visant à favoriser la publication de données structurées sur le Web, non pas sous la forme de silos de données isolés les uns des autres, mais en les reliant entre elles pour constituer un réseau global d'informations.]. Wikidata offre ainsi un large domaine d'informations générales sur notre univers ou ses représentations et des liens vers d'autres graphes ou bases de données. Il contient à ce jour plus de 100 millions d'items.
<br/>
La dynamique de création collective de ce projet encyclopédique peut être [saisie à l'oreille](http://listen.hatnote.com/#wikidata){target="_blank"} grâce à l'application développée par Stephen LaPorte et Mahmoud Hashemi.
<br/>
## Standard RDF du W3C
Le RDF (*Resource Data Framework*) est un cadre général de modélisation utilisé pour décrire formellement les ressources du Web via leurs métadonnées afin de permettre le traitement par inférence de telles descriptions. Développé par le W3C^[Le **World Wide Web Consortium** (**W3C**) est un organisme de standardisation à but non lucratif fondé en 1994 et chargé de promouvoir la compatibilité des technologies du Web], le RDF est le formalisme de base du [Web sémantique](https://fr.wikipedia.org/wiki/Web_s%C3%A9mantique){target="_blank"}.
Au sein de ce paradigme, un document ou une ressource consiste en un ensemble de triplets^[Un **triplet** est un groupe formé par trois éléments dont chacun appartient à un ensemble distinct.], chacun associant un sujet, un prédicat et un objet :
- le «sujet» du prédicat représente la ressource à décrire,
- le «prédicat» représente un type de propriété applicable à cette ressource,
- l'«objet» représente une donnée, une autre ressource ou une valeur associée à la propriété (ou prédicat).
Le sujet et l'objet, dans le cas où ce sont des ressources, peuvent être identifiés par un identifiant unique de la ressource (URI^[Un **URI** (*Uniform Resource Identifier*, en français "Identifiant unique de ressource") est une chaîne qui fait référence à une ressource. Les plus courantes sont les URL, qui identifient une ressource en donnant son emplacement sur le Web. Au contraire, les URN font référence à une ressource grâce à son nom, dans un environnement donné, par exemple le code ISBN d'un livre.]), une valeur ou être des nœuds anonymes. Le prédicat est nécessairement identifié par un URI.
Par exemple, la déclaration "Bob s'intéresse à Mona Lisa" est formalisée de la manière suivante :
```{r figure 2, out.width="70%", fig.align = 'center', echo=FALSE, purl = FALSE }
knitr::include_graphics('figures/triplet.png')
```
<center>
*Figure 2 : Exemple de représentation des composantes génériques d'un triplet RDF. </br> Source : [W3C](https://www.w3.org/TR/rdf11-primer/){target="_blank"}*
</center>
</br>
Un dépôt de triplets RDF ainsi formé correspond à un multigraphe orienté étiqueté : chaque triplet correspond alors à une arête orientée dont l'étiquette est le prédicat, le sujet est le nœud source et l'objet est le nœud cible (figure 3).
</br>
```{r figure 3, out.width="70%", fig.align = 'center', echo=FALSE, purl = FALSE }
knitr::include_graphics('figures/triplet_mona_lisa.png')
```
<center>
*Figure 3 : Exemple de graphe formé par plusieurs triplets RDF. </br> Source : [W3C](https://www.w3.org/TR/rdf11-primer/){target="_blank"}*
</center>
</br>
## Le langage SPARQL
SPARQL^[**SPARQL** est acronyme récursif qui signifie **S**PARQL **P**rotocol **A**nd **R**DF **Q**uery **L**anguage (@frwiki:194953405). Plusieurs langages de requête destinés à interroger les graphes RDF ont été développés, mais le langage SPARQL est développé par le W3C de sorte à devenir un standard.] (prononcé *sparkle*, en anglais : « étincelle ») est à la fois un langage de requête et un protocole qui permettent de rechercher, d'ajouter, de modifier ou de supprimer des triplets RDF disponibles à travers le Web. Aujourd'hui, le Web de données (représenté par le [nuage du *Linked Open Data*](http://lod-cloud.net/){target="_blank"} ou [ses domaines](http://lod-cloud.net/#subclouds){target="_blank"}) est interrogeable via des centaines de services SPARQL qui mettent à disposition de plus en plus de graphes de données ouvertes et liées comme c'est le cas du projet plurilingue Wikidata (@frwiki:194953405).
**Vocabulaire ou espace de noms**
Dans Wikidata les entités et leurs coordonnées spatiales et temporelles sont modélisées selon les fragments de graphes lisibles par l'humain et la machine dans divers formats^[Les formats d'écriture sont des normes ou standards adoptés dans le domaine avec une syntaxe spécifique à chacun] : XML, json, turtle etc. Ceux-ci comprennent des classes instanciées et liées entre elles par des prédicats (ou relations). Pour Wikidata comme pour d'autre modèles de données, il existe un vocabulaire spécifique. En général, les ontologies du web sémantique disposent d'un vocabulaire décrit au sein d'[espaces de noms](https://www.w3.org/TR/xml-names/){target="_blank"} associés au micro-monde décrit.
Par exemple, pour modéliser les données des réseaux sociaux, il existe un vocabulaire dédié ["Friend of a friend (FOAF)"](http://xmlns.com/foaf/spec/){target="_blank"} ; pour les ressources bibliographies, la BnF mobilise notamment le vocabulaire ["Functional Requirements for Bibliographic Records" (FRBR)](https://www.iflastandards.info/fr/frbr/frbrer.html){target="_blank"} élaboré par la Fédération internationale des associations et institutions de bibliothèques (IFLA) etc. Un autre exemple est l'ontologie du domaine associée à la diffusion de la musique fondée en 2002 avec l'initiative MusicBrainz [@swartz_2002], "corne d'abondance des communs" musicaux, déployée avec l'émergence du web.<br/>
L'espace de nom de l'ontologie de Wikipedia, DBpedia est accessible à cette URL : [https://dbpedia.org/ontology/](https://dbpedia.org/ontology/){target="_blank"}. <br/>
**Préfixes et requêtes**
À chaque vocabulaire utilisé pour construire la requête sont associés différents préfixes^[Un **préfixe** est une modalité de simplification d'écriture faisant référence à un *espace de noms* (qui est une page HTML ou un fichier en turtle par exemple), voir notamment https://www.w3.org/wiki/TheUsualPrefixes]. Dans le cas présenté, la déclaration du vocabulaire mobilisé (celui de Wikidata notamment) est intégrée aux *packages* utilisés. Toutefois, en général, il est nécessaire de le préciser dans l'entête de la requête SPARQL, sous une certaine forme :
```!sparql
PREFIX préfixe: <espace de nom>
```
Les éléments d'un triplet prennent alors la forme suivante :
```!sparql
prédicat = préfixe:propriété
domaine/co-domaine = préfixe:entité
```
Le préfixe est, en quelque sorte, la déclaration de "la langue" dans laquelle il faut lire "la classe" (entité ou propriété) qui le suit. En langage naturel, on pourrait l'écrire ainsi : `en:city`, `fr:ville`, `de:burg`,`es:cuidad` etc. avec la déclaration de l'espace numérique où est défini cette langue : `PREFIX en:<http://malangueanglaisequejutilise.en/#`, par exemple.
Cela permet non seulement de simplifier l'écriture :
```!sparql
<http://malangueanglaisequejutilise.en/#>:city
```
en
```!sparql
en:city
```
mais aussi de résoudre les questions de définition ou de polysémie des termes.
Classiquement, pour rechercher des entités qui ont pour [type](https://www.w3.org/TR/rdf-schema/#ch_type){target="_blank"}, dans le vocabulaire RDF (rdf), celui d'une [ville](https://dbpedia.org/ontology/city){target="_blank"}, dans le vocabulaire DBpedia (dbo), on peut écrire le triplet sous la forme suivante :
```!sparql
?city rdf:type dbo:city .
```
sous réserve de déclarer en tête de la requête SPARQL les préfixes des vocabulaires DBpedia et RDF :
```!sparql
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
```
Puis, si on souhaite connaître leur [pays](https://dbpedia.org/ontology/country){target="_blank"} de rattachement, dans le vocabulaire DBpedia, on peut écrire un second triplet :
```!sparql
?city dbo:country ?country .
```
Au sein des deux triplets, le point d'interrogation `?` permet de préciser, dans la requête, quelles sont entités recherchées : des objets de type ville (`dbo:city`) dans la variable `?city` et leur pays respectif (`dbo:country`) dans la variable `?country`.
Avec la déclaration des espaces de noms et la simplification de la syntaxe utilisant des préfixes, il est possible d'interroger des graphes (bases de données dites NoSQL^[Le terme NoSQL est utilisé pour désigner des bases de données qui ne sortent du paradigme des bases de données relationnelles]) au moyen d'un protocole Sparql sur un Point de Présence (SPARQLEndPoint) au sein d'un réseau HTTP.</br>
Dans la suite, plusieurs [préfixes Wikidata](https://www.wikidata.org/wiki/EntitySchema:E49){target="_blank"} spécifiques aux entités et aux types de propriétés sont utilisés. Dans le cadre de notre étude, le tableau suivant récapitule les classes et propriétés utilisées, ainsi que quelques préfixes du schéma Wikidata utilisés pour former les triplets :
| classe ou propriété | préfixe | exemple(s) de chemin | label Wikidata |
|-|-|------|----|
| P31 | `wdt` | ?identifiant **wdt:P31** ?naturedelelement | [nature de l’élément](https://www.wikidata.org/wiki/Property:P31){target="_blank"} |
| Q5 | `wd` | ?identifiant wdt:P31 **wd:Q5** | [être humain](https://www.wikidata.org/wiki/Q5){target="_blank"} |
| P373 | `wdt` | ?identifiant **wdt:P373** 'Johannes Vermeer' | [a pour catégorie](https://www.wikidata.org/wiki/Property:P373){target="_blank"}|
| P18 | `wdt` | ?identifiant **wdt:P18** ?image | [a pour image](https://www.wikidata.org/wiki/Property:P373){target="_blank"} |
| P170 | `wdt`, `ps` | ?oeuvre **wdt:P170** wd:Q41264 OU <br> ?oeuvreSt **ps:P170** wd:Q41264| [créé par](https://www.wikidata.org/wiki/Property:P170){target="_blank"} <br> (Q41264 identifie le peintre Johannes Vermeer)|
| P276 | `wdt`, `p` | ?oeuvre **wdt:P276** ?lieu OU <br> ?oeuvre **p:P276** ?lieuSt | [a pour lieu](https://www.wikidata.org/wiki/Property:P276){target="_blank"} |
| P625 | `wdt` | ?musee **wdt:P625** ?coord | [coordonnées](https://www.wikidata.org/wiki/Property:P625){target="_blank"} |
| P580 | `pq` | ?lieuSt **pq:P580** ?dated | [a pour date de début](https://www.wikidata.org/wiki/Property:P580){target="_blank"} |
| P582 | `pq` | ?lieuSt **pq:P582** ?datef | [a pour date de fin](https://www.wikidata.org/wiki/Property:P582){target="_blank"} |
| label, language | `wikibase` | SERVICE wikibase:label { <br> bd:serviceParam wikibase:language "[AUTO_LANGUAGE], fr,en".} | *syntaxe du service de nom et de langue de l'API WikidataQueryService* |
Dans le cas où le prédicat de Wikidata est utilisé avec le préfixe `p`, `ps` ou `pq`, la donnée associée est une assertion (spécifiée dans la tableau par le suffixe -St), c'est à dire un autre triplet. Ces spécificités du graphe Wikidata sont abordées dans la [partie 3](#exploration-du-graphe-wikidata).
# *Packages* et données
## *Packages* utilisés
Les *packages* utilisés pour réaliser l'ensemble de la chaîne de traitement présenté dans ce document sont les suivants :
</br>
- `wikidataR`^[[`WikidataR`](https://cran.r-project.org/web/packages/WikidataR/index.html){target="_blank"} est développé par Thomas Shafee, Os Keyes, Serena Signorelli, Alex Lum, Christian Graul et Mikhail Popov (développeur de `WikidataQueryServiceR`), membre de la Fondation Wikimédia. Il est maintenu par Thomas Shafee de l'université australienne La Trobe de l'état Victoria.] (et son extension `WikidataQueryServiceR`) : permet d'écrire une requête pour interroger le graphe de données Wikidata au moyen d'une Interface de Programmation d’Application (API) pour le service de requêtes Wikidata en langage SPARQL^[ Le [service de collecte des données de Wikidata en langage SPARQL](https://query.wikidata.org/){target="_blank"} offre une solution très complète en première approche (exemples, assistant de requêtes, diversité des représentations etc.). Toutefois, dans une dynamique d'exploration du graphe Wikidata, l'utilisation de R facilite la compréhension, l'archivage et la reproductibilité des différentes requêtes spécifiques réalisées. Pour cette raison, nous utilisons le *package* [`WikidataR`](https://www.rdocumentation.org/packages/WikidataR/versions/2.3.3){target="_blank"} ou alternativement [`WikidataQueryServiceR`](https://cran.r-project.org/web/packages/WikidataQueryServiceR/index.html){target="_blank"} qui est un *package* ayant des fonctionnalités plus développées.] ;
- `rnaturalearth` : met à disposition les données géographiques de [Natural Earth](https://www.naturalearthdata.com/){target="_blank"} ;
- `sf` : permet la gestion et la manipulation de données géographiques vectorielles ;
- `dplyr` : pour la manipulation des données ;
- `mapview` : pour l'affichage interactif de données géographiques (repose sur la librairie [JavaScript Leaflet](https://leafletjs.com/){target="_blank"}) ;
- `tmap` : pour la création de cartes thématiques ;
- `ggplot2` : permet la production de graphiques basés sur la grammaire graphique [@wilkinson05] ;
- `av` : génère des vidéos à partir d'images ou de graphiques R ;
- `patchwork` : permet de combiner plusieurs graphiques `ggplot2` dans la fenêtre graphique ;
- `jpeg` : permet l'import, l'enregistrement et l'affichage des images matricielles (format bitmap) ;
Vous pouvez utiliser les lignes de code suivantes pour installer ces *packages* :
```{r installation des packages, eval=TRUE, echo=TRUE, include=TRUE, message=FALSE, warning=FALSE}
# Liste des packages du CRAN nécessaires
liste_packages <- c("WikidataR",
"WikidataQueryServiceR",
"remotes",
"rnaturalearth",
"sf",
"dplyr",
"mapview",
"tmap",
"ggplot2",
"av",
"patchwork",
"jpeg")
# Packages à installer
liste_packages_a_installer <- liste_packages[!(liste_packages %in% installed.packages()[,"Package"])]
# Installation des packages manquants
install.packages(liste_packages_a_installer)
```
<div class="alert alert-danger" role="alert">Le *package* `glitter` développé par Lise Vaudor permet l'écriture de requêtes SPARQL dans un formalisme proche de pratiques associées au langage R sans maîtriser la syntaxe SPARQL, pour sonder divers graphes (dont Wikidata). Celui-ci n'est pas disponible sur le CRAN.</div>
L'ensemble des informations du système d"exploitation et des versions de *packages* utilisés pour générer ce *notebook* est disponible en <a href="#info-session">fin de document</a>.
<br />
## Données collectées
Plusieurs sources de données sont utilisées pour ce travail exploratoire :
1) des données issues du graphe Wikidata ;
2) une couche géographique [Natural Earth](https://www.naturalearthdata.com/){target="_blank"} ;
3) et des fonds de carte accessibles via [Leaflet](https://rstudio.github.io/leaflet/basemaps.html){target="_blank"}.
**Afin de maximiser la reproductibilité du code présenté, les jeux de données 1 et 2 ont été archivés et sont disponibles au téléchargement :**
<br/>
<p class="center">[<span style="font-size: 230%;" class="glyphicon glyphicon-download-alt"></span> <br/> Télécharger les données](https://github.com/rzine-reviews/wikidata_sparql_rzine/raw/main/data.zip)</p>
<br/>
<div class="alert alert-success" role="alert"><b>Wikidata est un graphe de données ouvertes et liées, régulièrement mis à jour. Une requête réalisée à deux dates différentes est susceptible de renvoyer un résultat différent.</b></div>
<br/>
# Exploration du graphe Wikidata
Voici quelques éléments basiques du langage SPARQL permettant d'[interroger la base de données Wikidata](https://www.wikidata.org/wiki/Wikidata:Data_access#How_can_I_get_data_out_of_Wikidata?){target="_blank"} :
- la clause [`SELECT `]((https://www.w3.org/TR/sparql11-query/#select){target="_blank"}) des données interrogées renvoies les variables spécifiques (avec `COUNT`, renvoi le nombre des ces données ou avec `GROUP_CONCAT`, les concatène au sein d'une collection, regroupées par `GROUP BY` et triées par `ORDER BY`),
- qui, accompagnée de la clause [`WHERE { }`]((https://www.w3.org/TR/sparql11-query/#where){target="_blank"}), les lie à l'interrogation de propriétés et données associées, suivant les chemins du graphe,
- avec un service WikiLabel spécifique au point d'accès *Wikidata Query Service*, du fait du caractère plurilingue de certaines données du graphe Wikidata, permettant de limiter le résultat à la langue choisie (`wikibase:language`) du label (`wikibase:label`) associé à l'entité ou la propriété recherchée,
- ou encore avec la fonctionnalité `OPTIONAL` de la clause `WHERE` qui permet de renvoyer les variables même si les données liées aux propriétés ne sont pas instanciées (nœuds vides),
- et les différents préfixes associés aux spécificités des propriétés simples, directes et indirectes etc. des fragments de graphe de Wikidata ([+d'info](https://linkeddatafragments.org/){target="_blank"}).
<br/>
Afin de permettre une bonne compréhension des requêtes réalisées pour la collecte de données sans entrer dans le détail de la syntaxe propre à SPARQL, celles-ci sont formulées de la manière suivante :
````markdown
SELECT données interrogées, comptage ou concatenage WHERE
{
chemins principaux du graphe
chemins optionnels du graphe
service Wikilabel
}
groupe et ordonne
````
<br />
## Modèle des données : artistes-peintres et trajectoires de leurs œuvres{.tabset}
Le fragment de graphe de l'image Wikidata d'une peinture, objet du processus exploratoire, est illustré sous la forme d'un tableau dans la figure 4 ci-dessous.
```{r figure 4, out.width="80%", fig.align = 'center', echo=FALSE, purl=FALSE}
knitr::include_graphics("figures/wikidata_page_description.png")
```
<center>
*Figure 4 : Représentation tabulaire d'une entité Wikidata avec les principaux termes utilisés. Les déclarations de localisation ou du créateur (statements en jaune sur le schéma) peuvent utiliser des valeurs (en vert) et des qualificatifs (qualifiers, en orange), ici associés aux données de lieux et aux laps de temps. <br/> Source : [Wikidata]((https://www.wikidata.org/wiki/Wikidata:Introduction){target="_blank})*
</center>
</br>
Pour plus d'informations, vous pouvez consulter l'[introduction à Wikidata](https://www.wikidata.org/wiki/Wikidata:Introduction/fr){target="_blank"} ou la [page Wikibase](https://www.mediawiki.org/wiki/Wikibase/Indexing/RDF_Dump_Format){target="_blank"} dédiée au formalisme du dépôt de données Wikidata.
Après plusieurs explorations, nous avons décidé de nous intéresser, dans une première étape, au peintre néerlandais du 17e siècle, **Johannes Vermeer**.
Les fonctions `find_item` et `find_property` du *package* `WikidataR` permet d'interroger le graphe à partir d'une chaîne de caractère.
```{r load_wikidataR, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
# Chargement du package WikidataR
library(WikidataR)
```
### 1. Entités liées à "Johannes Vermeer" {-}
Il est par exemple possible de collecter les entités (*item*) correspondant à la chaîne de caractère "Johannes Vermeer" :
```{r requete find_item, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
# Chercher les entités du graphe Wikidata correspondant à "Johannes Vermeer"
resultat_item <- find_item("Johannes Vermeer")
print(resultat_item)
```
Une seule entité de valeur `Q41264` parmi les dix collectées semble correspondre à l'image au sens de [@hui_induction_2015] de l'objet Johannes Vermeer, le peintre recherché. Le résultat de la requête `find_item` est composé d'un ensemble d'informations (`$id`, `$repository`, etc.).
```{r affichage entite, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
resultat_item[[1]]
```
Le champ `match` correspond à la chaîne de caractère recherchée : il est de `$type` label, en`$language` *en*, sous forme de `$text` *Johannes Vermeer*.
<br />
### 2. Propriétés liées à "artiste" {-}
Pour connaître les propriétés (*properties*) associées à celle des termes "artiste" ou "peintre" par exemple, on utilise `find_property`.
```{r affichage propriete artiste, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
find_property("artiste")
```
### 3. Propriétés liées à "peintre" {-}
```{r affichage propriete peintre, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
resultat_property <- find_property("peintre")
print(resultat_property)
```
La propriété associée au terme choisi "peintre" (`P170`) semble être celle liant un créateur à son œuvre ou autre objet. On comprend comment ce terme est lié à cette propriété dans le modèle de Wikidata en explicitant le champ `$match` :
```{r affichage propriete champ match, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
resultat_property[[1]]$match
```
La chaîne de caractère "peintre" est une forme textuelle `$text` de `$type` "alias" de la propriété `P170`, dans la langue française.
## {-}
<br />
## Déterminer l'identifiant Wikidata d'un peintre {.tabset}
Ces premières investigations du graphe permettent de comprendre que pour collecter de manière précise des données spatio-temporelles associées aux œuvres créées par Johannes Vermeer, les modalités d'interrogation nécessitent d'identifier de manière suffisamment explicite l'entité recherchée telle qu'elle est modélisée au sein du fragment de graphe (figure 5).
```{r figure 5, out.width="75%", fig.align = 'center', echo=FALSE, purl = FALSE }
knitr::include_graphics('figures/modele_interroge.png')
```
<center>
*Figure 5 : Schéma des triplets de données d'entrée et de sortie du fragment de graphe Wikidata exploré. La clause `SELECT` s'applique aux éléments figurés en données en sortie. Les propriétés et objets associés (en entrée ou sortie), c'est-à-dire les chemins du graphe, sont insérés dans l’accolade de `WHERE`.*
</center>
</br>
Formalisation de la requête de recherche d'identifiant :
```
Sélection de(s) identifiant(s) où {
l'identifiant est de type humain; # chemin principal
et il entre dans la catégorie "Johannes Vermeer"; # chemin principal (fin)
}
```
Conversion de la requête en SPARQL, et assignation de la chaîne de caractère dans un objet :
```{r requete_sparql, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
query <- "SELECT ?identifiant WHERE \
{ \
?identifiant wdt:P31 wd:Q5; \
wdt:P373 'Johannes Vermeer'; \
}"
```
A l'aide de la fonction `query_wikidata` du *package* `WikidataR`, nous commençons dans un premier temps par obtenir l'identifiant Wikidata du peintre. Il est possible de réaliser la même requête avec le *package* `WikidataQueryServiceR`.
```{r packageSPARQL sparql wikidataR, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
# Chargement des packages nécessaires
library(WikidataR)
library(WikidataQueryServiceR)
```
### WikidataR {-}
Exécution de la requête avec `WikidataR` :
```{r requete sparql wikidataR, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
data1_WR <- WikidataR::query_wikidata(query)
```
**Données récupérées :**
```{r requete sparql result1, eval=TRUE, echo=FALSE, include=TRUE, warning=FALSE, message=FALSE}
## Affichage du résultat
DT::datatable(data1_WR)
```
```{r inscription des donnees relatives au peintre 1, eval=TRUE, echo=FALSE, include=FALSE}
write.csv(x = data1_WR, file = "data/data1_WR.csv", row.names = FALSE)
data1_WR <- read.csv("data/data1_WR.csv", row.names = NULL)
```
### WikidataQueryServiceR {-}
Exécution de la requête avec `WikidataQueryServiceR` :
```{r requete sparql WikidataQueryServiceR, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
data1_WQSR <- WikidataQueryServiceR::query_wikidata(query)
```
**Données récupérées :**
```{r requete sparql result2, eval=TRUE, echo=FALSE, include=TRUE, warning=FALSE, message=FALSE}
DT::datatable(data1_WQSR)
```
```{r inscription des donnees relatives au peintre, eval=TRUE, echo=FALSE, include=FALSE}
write.csv(x = data1_WQSR, file = "data/data1_WQSR.csv", row.names = FALSE)
data1_WQSR <- read.csv("data/data1_WQSR.csv", row.names = NULL)
```
## {-}
<div class="alert alert-success" role="alert">Le résultat renvoyé par cette requête nous permet de vérifier que l'image de l'objet Johannes Vermeer est bien identifiée dans Wikidata :
- par la valeur "Q41264", résultat de la requête réalisée avec le *package* `WikidataR` ;
- et par l'identifiant uniforme de ressource [https://www.wikidata.org/wiki/Q41264](https://www.wikidata.org/wiki/Q41264){target="_blank"} pour `WikidataQueryServiceR`.
Avec `WikidataR`, on obtient une valeur de la base de données sous la forme d'une chaîne de caractère commençant par Q suivi d'un nombre à plusieurs chiffres.
En utilisant `WikidataQueryServiceR`, on obtient un identifiant uniforme de ressource sur un réseau (ou URI pour *Uniform Resource Identifier*) qui adopte une syntaxe associée à la norme d'internet. Un URI permet d'identifier une ressource de manière pérenne (même si celle-ci est déplacée ou supprimée).</div>
<br />
## Lister les œuvres du peintre et trouver leurs localisations géographiques
Dans cette seconde étape, on se propose de lister les œuvres de Johannes Vermeer avec leurs localisations. Au sein du graphe Wikidata, on fait l'hypothèse que les coordonnées de la localisation d'une œuvre, c'est à dire la valeur `point(x,y)`, sont celles du musée ou de l'institution au sein de laquelle l'œuvre est actuellement exposée ou située. Afin d'obtenir cette localisation à partir de l'identifiant du peintre, on trace un premier chemin du graphe tel qu'illustré dans la figure 6.
```{r figure 6, out.width="75%", fig.align = 'center', echo=FALSE, purl = FALSE }
knitr::include_graphics('figures/modele_interroge_qualifier_a.png')
```
<center>
*Figure 6 : Entités, valeurs et propriétés simples du graphe Wikidata mobilisées pour la localisation des œuvres de Johannes Vermeer. La valeur `point(x,y)` donne les coordonnées géographiques dans le système de référence World Geodetic System ([WGS84](https://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf)). Le nom des œuvres et des musées (suffixe "Label") est obtenu par le service `wikibase:label` du package `WikidataQueryServiceR`, dans la langue `wikibase:language` choisie ou la fonction `sqp_label` du package `glitter`.*
</center>
</br>
### Construction des requêtes {.tabset}
#### WikidataR {-}
```
Sélectionner les données oeuvre, musée et coordonnées telles que {
l'oeuvre a pour peintre Johannes Vermeer; # chemin principal
en option {
l'oeuvre est localisée dans un musee # chemin optionnel
ce musée a pour localisation les coordonnées # chemin optionnel
}
}
```
```{r requete sparql des musees WikidataR, eval=TRUE, echo=TRUE, message=FALSE, warning=FALSE, include=TRUE}
query <- "SELECT ?oeuvre ?musee ?coord WHERE \
{ \
?oeuvre wdt:P170 wd:Q41264 . \
OPTIONAL \
{ \
?oeuvre wdt:P276 ?musee .
?musee wdt:P625 ?coord \
} \
}"
## Exécution de la requête
data2_WR <- WikidataR::query_wikidata(query)
```
**Données récupérées :**
```{r requete sparql des musees WikidataR result, eval=TRUE, echo=FALSE, message=FALSE, warning=FALSE, include=TRUE}
DT::datatable(data2_WR)
```
```{r inscription des données sur les oeuvres 1, eval=TRUE, echo=FALSE, include=FALSE}
write.csv(x = data2_WR, file = "data/data2_WR.csv", row.names = FALSE)
data2_WR <- read.csv("data/data2_WR.csv", row.names = NULL)
```
#### WikidataQueryServiceR {-}
```
Sélectionner les noms des données oeuvre, musée et les coordonnées telles que {
l'oeuvre a pour peintre Johannes Vermeer; # chemin principal
en option {
l'oeuvre est localisée dans un musee # chemin optionnel
ce musée a pour localisation les coordonnées # chemin optionnel
}
en langue anglaise (en) # service Wikilabel
}
```
```{r requete sparql oeuvres de Vermeer et musées, eval=TRUE, echo=TRUE, message=FALSE, warning=FALSE, include=TRUE}
query_label <- "SELECT ?oeuvreLabel ?museeLabel ?coord WHERE \
{ \
?oeuvre wdt:P170 wd:Q41264 . \
OPTIONAL \
{ \
?oeuvre wdt:P276 ?musee .
?musee wdt:P625 ?coord \
} \
SERVICE wikibase:label \
{ \
bd:serviceParam wikibase:language \"[AUTO_LANGUAGE], en \". \
} \
}"
## Exécution de la requête
data2_WQSR <- query_wikidata(query_label)
```
**Données récupérées :**
```{r requete sparql des musees WikidataQueryServiceR result, eval=TRUE, echo=FALSE, message=FALSE, warning=FALSE, include=TRUE}
DT::datatable(data2_WQSR)
```
```{r inscription des données sur les oeuvres, eval=TRUE, echo=FALSE, include=FALSE}
write.csv(x = data2_WQSR, file = "data/data2_WQSR.csv", row.names = FALSE)
data2_WQSR <- read.csv("data/data2_WQSR.csv", row.names = NULL)
```
<br />
## Premiers éléments d'analyse exploratoire
### Quelques constats sur le graphe et les données
On constate que les données (non supervisées) du graphe Wikidata concernant les lieux d'exposition des œuvres de Vermeer et leurs coordonnées géographiques sont hétérogènes :
- certaines œuvres semblent n'avoir aucune localisation, l'information n'étant pas disponible dans le graphe Wikidata tel qu'interrogé (voir ci-dessous),
- d'autres semblent être liées à des lieux correspondant à des données d'une autre nature qu'un musée ou institution (par exemple, *Frick Collection* ou *Gallery of Honour*),
- enfin, parmi les œuvres localisées, certaines présentent plusieurs localisations de nature différente (par exemple, l'œuvre "A Young Woman Standing at a Virginal"), et dans certains cas, plusieurs fois le même musée avec éventuellement des coordonnées très légèrement distinctes (par exemple, "The Geographer" au *Städel Museum*).
Pourquoi ? Plusieurs hypothèses peuvent être esquissées, outre la question des différentes langues qui peuvent générer des doublons :
- un même musée peut avoir plusieurs coordonnées géographiques renseignées (plusieurs couples du `Point(x,y)` très proches, par exemple pour le *Städel Museum*),
- la localisation d'une œuvre peut conduire à une entité qui n'est ni un musée ni une institution culturelle mais le nom d'une collection (par exemple *The Frick Collection*) ou d'une salle d'un musée etc.,
- une même œuvre peut être située dans plusieurs musées (ou plusieurs fois dans un même musée), peut-être à des périodes différentes.
Ces constats sont liés non seulement au caractère non supervisé et collectif (hétérogène, voire lacunaire) de la production des données, mais aussi à la complexité de la saisie des données dans le graphe Wikidata. En effet, les modalités d'interrogation du graphe Wikidata sont multiples, en fonction notamment de la profondeur du graphe qui est sondée et de la qualité de l'affectation de valeurs à ses instances.
La série de requêtes présentées jusqu'à présent interroge les entités Wikidata renseignées au moyen des valeurs simples du prédicat de localisation, c'est à dire avec le préfixe `wdt`. Pour aller plus en profondeur dans le graphe, vérifier la qualité de l'information de localisation et déterminer sa composante temporelle, il est nécessaire d'entrer plus en détail dans une autre forme d'instanciation du graphe, spécifique à Wikidata, à savoir les valeurs complexes ou déclarations (voir notamment la figure 7).
<br/>
```{r figure 7, out.width="70%", fig.align = 'center', echo=FALSE, purl=FALSE}
knitr::include_graphics("figures/Wikibase_Indexing_RDF Dump Format - MediaWiki.png")
```
<center>
*Figure 7 : Extrait du graphe de Wikidata avec les ensembles de relations entre entités au moyen des propriétés simples (préfixe `wdt`) et les relations au sein des déclarations au moyen des propriétés directes spécifiques (préfixes `p`, `ps` ou `pq`) utilisées infra. </br> Source : [Wikibase](https://www.mediawiki.org/wiki/Wikibase/Indexing/RDF_Dump_Format)*
</center>
<br />
### Le corpus des œuvres de (`P170`) Johannes Vermeer selon Wikidata{.tabset}
Pour bien comprendre la différence entre l'interrogation "en surface" du graphe et celle "en profondeur", on sonde deux modalités de la propriété `P170 créé par` dont le peintre Vermeer est l'objet pour identifier le corpus de ses œuvres.
#### Valeurs simples ou "quasi-vérités" {-}
```
Sélectionner les données oeuvre et leur nom telles que {
l'oeuvre a pour créateur le peintre Johannes Vermeer; # chemin principal
en langue anglaise (en) # service Wikilabel
}
par ordre décroissant # ordonne
```
```{r requete sparql nombre d oeuvres attribuées à Vermeer en valeur simple, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
query_valeur_simple <- "SELECT ?oeuvre ?oeuvreLabel WHERE \
{ \
?oeuvre wdt:P170 wd:Q41264 \
SERVICE wikibase:label \
{ \
bd:serviceParam wikibase:language \"[AUTO_LANGUAGE], en \". \
} \
} \
ORDER BY DESC( ?oeuvre )"
## Exécution de la requête
resultats_oeuvres_valeur_simple <- WikidataQueryServiceR::query_wikidata(query_valeur_simple)
```
Nombre d’œuvres associées avec une valeur simple :
```{r Nombre oeuvres associées avec une valeur simple, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
nrow(resultats_oeuvres_valeur_simple)
```
#### Valeurs complexes ou déclarations {-}
```
Sélectionner les données oeuvre et leur nom telles que {
l'oeuvre est liée à une assertion de création au peintre Johannes Vermeer; # chemin principal
en langue anglaise (en) # service Wikilabel
}
par ordre décroissant # ordonne
```
```{r requete sparql nombre d oeuvres attribuées à Vermeer par asertion, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
query_declaration <- "SELECT ?oeuvre ?oeuvreLabel WHERE \
{ \
?oeuvre p:P170/ps:P170 wd:Q41264
SERVICE wikibase:label \
{ \
bd:serviceParam wikibase:language \"[AUTO_LANGUAGE], en \". \
} \
} \
ORDER BY DESC( ?oeuvre )"
## Exécution de la requête
resultats_oeuvres_exhaustif <- WikidataQueryServiceR::query_wikidata(query_declaration)
```
Nombre d’œuvres associées avec une assertion exhaustive :
```{r nombre d oeuvres attribuées à Vermeer par asertion, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
nrow(resultats_oeuvres_exhaustif)
```
### {-}
La requête effectuée sur le graphe renvoie 2 résultats différents :
- le premier cas correspond à la propriété `prop/direct/P170` qui associe l'identifiant aux valeurs simples (préfixe `wd`), c'est à dire avec le préfixe `wdt`: on compte 38 œuvres pour Vermeer (Q41264);
- le second cas correspond à la propriété `prop/statement/P170` (préfixe `p`) qui associe l'identifiant à une assertion (préfixe `wds`, soient un ou plusieurs triplets) dont les termes sont acheminés au moyen du préfixe `ps` : le graphe compte alors 44 œuvres pour Vermeer, soit un écart de 6 œuvres.
En différenciant les modalités d'interrogation associées aux différents types de prédicats d'attribution des œuvres à Vermeer, il est possible de connaître la liste de ces œuvres objets d'une assertion au sein du fragment de graphe Wikidata, qui ne sont pas des valeurs simples, voir figure 7) :
```{r identification des oeuvres attribuées par assertion et non par valeur simple, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
subset(resultats_oeuvres_exhaustif, !oeuvre %in% resultats_oeuvres_valeur_simple$oeuvre)
```
Cette différence de résultat peut conduire à poursuivre l'investigation du corpus tel que modélisé et instancié dans le graphe Wikidata. Par exemple, pour connaître la nature de la relation de ces œuvres au peintre Johannes Vermeer (sont-elles réellement de Vermeer ?), il est possible de sonder le fragment de graphe sur d'autres valeurs, notamment au moyen :
- de prédicats qualifiant l'attribution de l'œuvre dans le champ d'histoire de l'art (dits *qualifiers* avec le préfixe `pq:`) comme par exemple : `P1777 à la manière de`, `P1778 faux imitant`, `P1778 d'après une œuvre de`, `P1774 atelier de` et `P1775 suiveur de` Johannes Vermeer,
- mais aussi d'autres chemins du graphe Wikidata qui permettent de préciser la qualité de l'information non supervisée comme par exemple le rang (`wikibase:rank`) de l'assertion d'attribution (`ps:P170`) de l'œuvre à Vermeer.
Ces autres chemins du graphe Wikidata concernant "la main" du peintre ou plus généralement la qualité des informations collectées, ne sont pas développés ici.
La pertinence de l'usage des prédicats de qualification sera démontrée dans la suite avec l'exemple de la localisation au sein d'une valeur complexe spatio-temporelle de l'œuvre choisie pour notre cas d'étude, mobilisant la propriété `P276` de lieu.
</br>
### Choisir l'œuvre de Vermeer qui a le plus voyagé {.tabset}
La qualité de l'information de localisation est déterminante dans notre démarche. Celle-ci peut avoir plusieurs valeurs dans le graphe Wikidata, comme nous l'avons montré dans le tableau au [paragraphe précédent](#quelques-constats-sur-le-graphe-et-les-données). Elle peut avoir des formes différentes, dont celle d'une assertion, c'est à dire une localisation complexe dans l'espace et le temps, selon le modèle de Wikidata.
Pour choisir l'œuvre de Vermeer qui a le plus voyagé, nous allons voir ici que des modalités d'interrogation avec deux prédicats de lieu, c'est à dire ceux construits à partir de la propriété `P276`, donnent des résultats très différents.
#### "à la surface" du graphe {-}
```
Sélectionne le nom des données oeuvre et compte leur nombre de coordonnées distinctes telles que {
l'oeuvre a pour créateur le peintre Johannes Vermeer; # chemin principal
localisation un musée. # chemin principal
ce musée a pour localisation les coordonnées # chemin principal (fin)
en langue anglaise (en) # service Wikilabel
}
pour chaque nom d'oeuvre # groupe
par ordre décroissant # ordonne
```
```{r requete sparql identification du nombre de localisation par oeuvre en valeur simple, eval=TRUE, echo=TRUE, message=FALSE, warning=FALSE, include=TRUE}
query <- "SELECT ?oeuvreLabel \
(COUNT(DISTINCT?coord) AS ?count) WHERE \
{ \
?oeuvre p:P170/ps:P170 wd:Q41264 ; wdt:P276 ?musee . \
?musee wdt:P625 ?coord \
SERVICE wikibase:label \
{ \
bd:serviceParam wikibase:language \"[AUTO_LANGUAGE], en \".\
} \
} \
GROUP BY ?oeuvreLabel \
ORDER BY DESC(?count)"
# Exécution de la requête
metadonnees_localisation_oeuvres_valeur_simple <- WikidataQueryServiceR::query_wikidata(query)
```
**Données récupérées :**
```{r result identification du nombre de localisation par oeuvre en valeur simple, eval=TRUE, echo=FALSE, message=FALSE, warning=FALSE, include=TRUE}
DT::datatable(metadonnees_localisation_oeuvres_valeur_simple)
```
#### dans la partie "immergée" du graphe {-}
```
Sélectionne le nom des données oeuvre et compte leur nombre de coordonnées distinctes telles que {
l'oeuvre est liée à une assertion de création au peintre Johannes Vermeer; # chemin principal
de localisation au musée. # chemin principal
ce musée a pour localisation les coordonnées # chemin principal (fin)
en langue anglaise (en) # service Wikilabel
}
pour chaque nom d'oeuvre # groupe
par ordre décroissant # ordonne
```
```{r requete sparql identification du nombre de localisation par oeuvre par assertion, eval=TRUE, echo=TRUE, message=FALSE, warning=FALSE, include=TRUE}
query <- "SELECT ?oeuvreLabel \
(COUNT(DISTINCT?coord) AS ?count) WHERE \
{ \
?oeuvre p:P170/ps:P170 wd:Q41264 ; p:P276/ps:P276 ?musee . \
?musee wdt:P625 ?coord \
SERVICE wikibase:label \
{ \
bd:serviceParam wikibase:language \"[AUTO_LANGUAGE], en \". \
} \
} \
GROUP BY ?oeuvreLabel \
ORDER BY DESC(?count)"
# Exécution de la requête
metadonnees_localisation_oeuvres <- WikidataQueryServiceR::query_wikidata(query)
```
**Données récupérées :**
```{r result2 sparql identification du nombre de localisation par oeuvre par assertion, eval=TRUE, echo=FALSE, message=FALSE, warning=FALSE, include=TRUE}
DT::datatable(metadonnees_localisation_oeuvres)
```
### {-}
On le comprend ici, dans le cas d'une requête limitée aux valeurs simples, il n'est pas possible d'identifier les localisations réelles successives des œuvres. Les valeurs associées sont d'une autre nature.
Par contre, en mobilisant l'information de localisation complexe "réelle", c'est à dire fondée sur des chemins adaptés du graphe, l'œuvre intitulée "Dame assise au virginal" (entité [Q4660880](http://www.wikidata.org/entity/Q4660880){target="_blank"}) est, selon Wikidata, l'œuvre de Johannes Vermeer qui a le plus voyagé pour être exposée. Cela signifie que cette instance de la classe œuvres possède le plus grand nombre de valeurs associées au prédicat "a pour lieu" [p:P276/ps:P276](https://www.wikidata.org/wiki/Property:P276){target="_blank"} dans les déclarations exhaustives de localisation désignant des musées ou institutions. Leurs coordonnées sont des valeurs simples données par le prédicat [wdt:P625](https://www.wikidata.org/wiki/Property:P625){target="_blank"}.
Ce constat ouvre une nouvelle perspective en matière d'analyse exploratoire. Nous allons donc nous intéresser à la trajectoire spatio-temporelle de cette œuvre.
<br />
## Troisième requête SPARQL : déclaration spatiale et temporelle
Comme illustré dans la figure 8, la localisation spatio-temporelle d'une entité est déclarée au moyen d'un prédicat direct ([p:P276](https://www.wikidata.org/wiki/Property:P276){target="_blank"}), qui permet l'accès à une forme complexe de localisation de l'œuvre choisie :
- dont les valeurs du prédicat `ps:P276` sont des lieux (géographiques et institutionnels) caractérisés par l'ensemble des déclarations de localisations spatiales `point(x,y)`, valeurs du prédicat `wdt:P625` ;
- dont les valeurs des prédicats de type [*qualifiers*](https://www.wikidata.org/wiki/Help:Qualifiers){target="_blank"} de la déclaration `?lieu` donnent des périodes temporelles (date de début : [`pq:P580`](https://www.wikidata.org/wiki/Property:P580){target="_blank"}, date de fin: [`pq:P582`](https://www.wikidata.org/wiki/Property:P582){target="_blank"}) ou date/point dans le temps de l’évènement associé [`pq:P585`](https://www.wikidata.org/wiki/Property:P585){target="_blank"}.
```{r figure 8, out.width="75%", fig.align = 'center', echo=FALSE, purl = FALSE }
knitr::include_graphics('figures/modele_interroge_qualifier_b.png')
```
<center>
Figure 8 : *Classes et propriétés spécifiques de Wikidata mobilisées pour la localisation spatio-temporelle dans le cas d'une déclaration (statement).*
</center>
</br>
### Construction des requêtes
#### La circulation spatio-temporelle de l'oeuvre
Pour connaître les modalités de circulation de l'œuvre dans divers musées et institutions, la requête SPARQL ci-dessous collecte les déclarations relatives aux lieux d'exposition ([P276](https://www.wikidata.org/wiki/Property:P276){target="_blank"}) et la période pendant laquelle l'œuvre ([Q4660880](http://www.wikidata.org/entity/Q4660880){target="_blank"}) semble y avoir été présente. .
```
Sélectionne le nom des données musée, dates et coordonnées telles que {
l'oeuvre choisie est localisée directement au lieu. # chemin principal
ce lieu est lié dans une assertion de localisation à un musée; # chemin principal
est lié dans une assertion de temporalité à une date de début; # chemin principal
est lié dans une assertion de temporalité à une date de fin. # chemin principal
ce musée a pour localisation les coordonnées . # chemin principal
en langue anglaise (en) # service Wikilabel
}
```
```{r requete sparql identification de la trajectoire spatio-temporelle de l oeuvre choisie, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE , out.width="50%",fig.align = 'center', purl = FALSE}
query <- "SELECT ?museeLabel ?dated ?datef ?coord WHERE \
{ \
wd:Q4660880 p:P276 ?lieu . \
?lieu ps:P276 ?musee ;
pq:P580 ?dated ;
pq:P582 ?datef . \
?musee wdt:P625 ?coord . \
SERVICE wikibase:label \
{ \
bd:serviceParam wikibase:language \"[AUTO_LANGUAGE], en \". \
} \
}"
## Exécution de la requête
data3_WQSR <- WikidataQueryServiceR::query_wikidata(query)
```
**Données récupérées :**
```{r result metadata, eval=TRUE, echo=FALSE, message=FALSE, warning=FALSE, include=TRUE}
DT::datatable(data3_WQSR)
```
**Enregistrement et (ré)import des données :**
```{r inscription des données de trajectoire, eval=TRUE, echo=TRUE, include=TRUE}
# Enregistrement des données en format csv
write.csv(x = data3_WQSR, file = "data/data3_WQSR.csv", row.names = FALSE)
# Import du fichier de données enregistrées
data3_WQSR <- read.csv("data/data3_WQSR.csv", row.names = NULL)
```
#### L'illustration de l'œuvre
La requête ci-dessous permet d'obtenir l'illustration (figure 9) de l'œuvre ciblée ([P18](https://www.wikidata.org/wiki/Property:P18){target="_blank"})
```
Sélectionner la donnée image telle que {
l'oeuvre choisie a pour image une représentation numérique . # chemin principal
}
```
```{r requete image, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE , out.width="50%",fig.align = 'center', purl = FALSE}
query_image <- "SELECT ?image WHERE \
{ \
wd:Q4660880 wdt:P18 ?image \
}"
## Exécution de la requête
image_oeuvre <- WikidataQueryServiceR::query_wikidata(query_image)
```
**Enregistrement de l’image de l’œuvre :**
```{r enregistrement de l image collectée de l oeuvre, eval=TRUE, echo=TRUE, include=TRUE, warning=FALSE, message=FALSE}
download.file(url = image_oeuvre[[1]],
destfile = 'data/images/Q4660880.jpg',
mode = 'wb')
```
```{r figure 9, echo=FALSE, out.width="60%",fig.align = 'center', purl = FALSE }
knitr::include_graphics("data/images/Q4660880.jpg")
```
<center>
*Figure 9 : Illustration de l'œuvre "A Young Woman Seated at the Virginals" de Johannes Vermeer, 1670*
</center>
</br>
<div class="alert alert-success" role="alert">
Les trois requêtes SPARQL ont ainsi permis de collecter respectivement :
1) <b>l'identifiant associés à Johannes Vermeer</b> dans Wikidata (***data1_WR***) ;
2) <b>les œuvres du peintre Johannes Vermeer et leurs localisations</b> (musée + coordonnées) (***data2_WQSR***) ;
3) <b>les informations de localisation (nom du musée, coordonnées et dates) des lieux où a été exposée l’œuvre intitulée "A Young Woman Seated at the Virginals" de Johannes Vermeer</b> (***data3_WQSR***).
Nous pouvons maintenant exploiter les dimensions spatiale et temporelle de ces données collectées.</div>
<br/>
# Exploration spatiale
Les données non-supervisées collectées nécessitent toujours d'être contrôlées et nettoyées avant d'être exploitées. De plus, les données obtenues comportent des coordonnées géographiques qui permettent de les convertir en véritable couche géographique afin de les cartographier et ainsi d'exploiter leur dimension spatiale.
## Les œuvres de Johannes Vermeer
Les données issues de la seconde requête SPARQL (*data2_WQSR*) listent l'ensemble des œuvres de Vermeer et leurs localisations respectives (nom du musée et coordonnées géographiques quand elles existent) selon Wikidata. Avant de les cartographier, quelques traitements sont nécessaires :
1) Suppression des doublons et des œuvres sans aucune localisation renseignée ;
2) Calcul du nombre d'œuvres par musée (localisation) ;
3) Géoréférencement^[Le **géoréférencement** est l'un des principes fondamentaux des systèmes d'information géographiques (SIG) et de la cartographie assistée par ordinateur (CAO). Un objet géographiques est référencé lorsque l'on lui attribut une localisation (coordonnées géographiques) et une forme (géométrie : point, ligne ou surface).] des musées abritant des œuvres de Vermeer.
### Nettoyage des données
Dans cette partie, nous allons uniquement nous intéresser à la dimension spatiale des données collectées, sans prendre en compte la dimension temporelle. Si aucune coordonnée géographique n'est renseignée (cf. [partie 3.3](#lister-les-œuvres-du-peintre-et-trouver-leurs-localisations-géographiques)), nous ne prendrons pas en compte le musée recensé. En revanche, nous considérons l'ensemble des localisations comportant des coordonnées géographiques, peu importe la temporalité qui leur est associée.
Commençons par supprimer les localisations (musée ou institution) qui ne sont pas associées à des coordonnées géographiques dans Wikidata :
```{r nettoyage des données de localisation, eval=TRUE, echo=TRUE, include=TRUE}
data2_WQSR <- data2_WQSR[!is.na(data2_WQSR$coord), ]
```
Nous pouvons ensuite supprimer les doublons, que l'on peut expliquer par le fait qu'une œuvre ait pu être exposée à plusieurs reprises dans un même musée, ou qu'un même lieu ait pu être renseigné par plusieurs couples de coordonnées géographiques dans Wikidata.
Pour cela, nous utilisons la fonction `duplicated`, appliquée au couple "nom de l'œuvre + lieu d'exposition"
```{r nettoyage des doublons, eval=TRUE, echo=TRUE, include=TRUE}
data2_WQSR <- data2_WQSR[!duplicated(data2_WQSR[, c("oeuvreLabel", "museeLabel")]), ]
```
<div class="alert alert-danger" role="alert">
En cas de doublons, seul un couple de coordonnées géographiques est retenu. Ce choix est justifié car, après vérification manuelle, **il s'agit en fait de coordonnées géographiques semblables (quelques mètres de différences), différenciées par un niveau de précision (nombre de chiffres après la virgule...)**.
Exemple : voir les deux couples de coordonnées géographiques renseignées pour le [***Städel Museum***](https://www.wikidata.org/wiki/Q163804){target="_blank"} dans Wikidata.</div>
**Affichage des données filtrées : **
```{r affichage des données filtrées, eval=TRUE, echo=FALSE, include=TRUE}
DT::datatable(data2_WQSR)
```
<br/>
### Regroupement par musée
Plusieurs œuvres semblent avoir été exposées dans les mêmes lieux. Afin de cartographier les musées ayant exposé différentes œuvres de Johannes Vermeer, nous réalisons un regroupement des œuvres par intitulé des musées (*musee*), tout en calculant le nombre d'œuvres que chacune de ces institutions a exposées au cours du temps.
```{r regroupement par musee et histogramme, eval=TRUE, echo=TRUE, include=TRUE}
library(dplyr)
nb_oeuvres_musee <- data2_WQSR |>
group_by(musees = museeLabel, coords = coord) |>
summarise(nb_oeuvres = n())
```
Histogramme de répartition des musées en fonction du nombre d'œuvres de J.V. exposées :
```{r graphique regroupement par musee et histogramme, eval=TRUE, echo=TRUE, include=TRUE}
library(ggplot2)
ggplot(nb_oeuvres_musee, aes(x = nb_oeuvres)) +
geom_histogram(binwidth=1, color="white") +
scale_y_continuous(n.breaks = 8) +
xlab("Nombre d'œuvres exposées") +
ylab("Nombre de musées")
```
<center>
Graphique 1 : **Distribution du nombre d'œuvres de Johannes Vermeer exposées par musée**
</center>
### Géoréférencement
La variable 'coords' contient les coordonnées géographiques des musées dans le format **WKT**^[Le format **Well-known text**, abrégé en **WKT**, peut se traduire par « texte bien lisible ». C'est un format standard en mode texte utilisé pour représenter des objets géométriques vectoriels issus des systèmes d’information géographique (SIG), mais aussi des informations s’y rattachant, tels les références de systèmes de coordonnées.]. En utilisant le *package* `sf`, il est simple de construire des données géographiques vectorielles. Pour cela, nous utilisons les fonctions `st_as_sfc` et `st_as_sf`.
```{r georéférencement, eval=TRUE, echo=TRUE, include=TRUE}
library(sf)
# Création d'objets géographiques ponctuels à partir des coordonnées stockées en WKT
geometry <- st_as_sfc(nb_oeuvres_musee$coords, crs = 4326)
# Création d'une couche géographique vectorielle (attributs des musées + géométries)
musee_geo <- st_as_sf(nb_oeuvres_musee, geometry)
```
La table de données a été transformée en couche géographique manipulable avec R ([objet `sf`](https://r-spatial.github.io/sf/articles/sf1.html){target="_blank"}), où chaque musée comporte une géométrie (point localisé dans l'espace, dans le [système géographique de référence WGS84](https://fr.wikipedia.org/wiki/WGS_84){target="_blank"}).
```{r affichage des données géoréférencées, eval=TRUE, echo=FALSE, include=TRUE}
DT::datatable(musee_geo)
```