Rapport du challenge OpenData

Equipe

  • Corentin COURNAC
  • Mathieu DAURE
  • William DUCLOT
  • Pierre PRESENT

Avant toute chose : déploiement du projet

L'archive fournie ne contient que les données au format CSV. Ces données ne sont pas exploitables par notre programme pour le moment

Pour pouvoir faire fonctionner le projet correctement, le script ./launch.sh est fourni à la racine. Celui-ci s'occupera de générer les fichiers JSON nécessaires grâce au script Python collection/csvToJsonConverter.py, puis de démarrer un serveur simple sur le port 8000 grâce à la commande python -m SimpleHTTPServer 8000.

Il est possible de faire ces opérations indépendamment en lançant le script csvToJsonConverter.py depuis le dossier collection, puis en lançant la commande python -m SimpleHTTPServer 8000 depuis la racine du projet.

Il est important de noter que l'on n'a besoin de générer les données JSON qu'une seule fois. Le script utilise le module requests de python, qui n'est pas installé sur les ordinateurs de l'Ensimag. Si vous souhaitez le lancer depuis un ordinateur de l'Ensimag, une autre version du script utilisant ce module est fournie : collection/city_country_identifier.py-bufferonly. Il suffit de le renommer en collection/city_country_identifier.py. Le buffer sera fourni dans l'archive.

Il suffira ensuite d'ouvrir un navigateur et d'aller à l'adresse localhost:8000 pour lancer l'application

Présentation du projet

Notre projet a pour but de donner une vision globale de la provenance des œuvres issues de la collection des musées Tate.

Source des données

Les données proviennent du dépôt GitHub tategallery/collection, nous avons récupéré les données au format CSV soit 2 fichiers :

Ces fichiers contiennent environ 3 500 artistes et 70 000 œuvres.

La correction des données de localisation géographique est faite grâce à l'API JSON de geonames.org.
Pour retrouver le continent d'un code pays donné, nous utilisons le fichier countries.json de l'utilisateur github annexare.

Visualisation

L'idée est de représenter l'ensemble des œuvres présentes dans la collection sous la forme de packed circles, c'est à dire de cercles inclus les un dans les autres, regroupant les œuvres selon des critères de plus en plus fins.
Ainsi, on peut zoomer dans chaque cercle pour affiner de plus en plus les critères, jusqu'à visualiser les artistes et leurs œuvres. Ces critères, dans l'ordre, sont les suivants :

  • Continent
  • Pays
  • Ville
  • Artiste
Par exemple, pour accéder aux œuvres de Joseph Turner, on pourra cliquer sur le continent Europe, puis United Kingdom, puis London, puis Joseph Turner. On peut ainsi visualiser une sélection des œuvres de cet artiste, et accéder à la page dédiée à une œuvre sur le site du Tate Museum en cliquant sur sa vignette.

Technologies utilisées

  • Python : Pour le traitement des données CSV et la génération des fichier JSON dont nous avons besoin.
  • Javascript + bibliothèque D3.js : D3.js est une bibliothèque graphique pour manipuler, traiter et afficher des données sous plusieurs formats. Nous avons utilisés 2 types de représentations à partir de modèles existants :
    • Zoomable Circle Packing : Utilisé pour l'affichage de la répartition des artistes par localisation géographique.
    • Force-Directed Graph : Utilisé pour l'affichage des oeuvres d'un artiste, nous n'affichons que 40 oeuvres au maximum.

Traitements opérés

Génération des JSON

La librairie D3 peut lire assez simplement des fichiers CSV, néanmoins il est beaucoup plus simple pour générer des graphes hiérarchiques (tels que les packed circles) d'utiliser un fichier JSON, qui est par essence hiérarchique.
Nous effectuons donc un traitement des données grâce à un script Python qui va parser les données CSV pour en extraire les données dont nous avons besoin et les exporter dans plusieurs fichiers JSON. Tout d'abord on parse les données des artistes du fichier artist_data.csv dans des structures de données (dictionnaires) correspondant à la hiérarchie que l'on va chercher à obtenir dans le JSON : les continents sont un ensemble de pays, qui sont un ensemble de villes, qui sont un ensemble d'artistes, qui sont un ensemble d'œuvres. Une fois ces structures créées, on les parcourt pour extraire des données supplémentaires (ratio homme/femme, partition par ordre alphabétique).

Nous pouvons ensuite générer un fichier JSON qui contient cette répartition d'artistes et qui sera utilisé ensuite pour l'affichage des noeuds.

Nous associons ensuite les oeuvres du fichier artwork_data.csv à chaque artiste. Ceci permet ensuite de créer un fichier JSON par artiste avec une liste de ses oeuvres, nous avons limité le nombre d'oeuvres à 40 pour ne pas saturer la visualisation.

En plus de cela, il est nécessaire pour économiser de la puissance de calcul de générer un autre fichier JSON qui contient un tableau d'associations entre les noms des artistes et leur identifiant respectif. Ceci permet d'optimiser la fonction de recherche, qui n'ira donc que chercher dans ce fichier research.json plutôt que de parcourir toute la hiérarchie.

Visualisation

On utilise D3-hierarchy pour facilement utiliser le layout pack afin d'obtenir la visualisation sous forme de cercles imbriqués. Pour clarifier la visualisation, nous avons choisi de n'afficher qu'un seul niveau hiérarchique à la fois (dans un continent, on voit les pays mais pas les villes). Pour voir les niveaux inférieurs, il faut zoomer sur un cercle en cliquant dessus.
Pour ces effets de zooms et d'affichage, on utilise a la fois des propriétés SVG, des propriétés CSS et des traitements Javascript.

Gestion de la localisation

Les données utilisées ont la particularité de ne pas avoir de formalisme précis. Un lieu de naissance peut par exemple être indiqué par un couple "Ville, Pays", "Région, Pays", mais aussi par un simple mot étant "Pays", ou encore simplement "Ville".

Dans l'écriture des villes et des pays, un autre problème se pose. Ces deux éléments peuvent être écrits sous différentes langues. Nous pouvons trouver pour la Chine par exemple son écriture anglaise "China", mais nous pouvons le retrouver écrit comme "Zhonghua". La Grèce se retrouve ainsi parfois nommée "Ellás", qui est une façon peu orthodoxe d'écrire le nom de ce pays en Grec ancien avec des caractères modernes.

Pour palier à ce problème, nous utilisons l'API de GeoNames, très efficace pour retrouver le nom anglais d'un lieu géographique passé à l'API. Une succession de cas particuliers, mêlé à l'agencement des informations (couple d'information, information simple, ville ou pays selon les cas) a nécessité un long travail sur cette étape d'harmonisation des noms de localités, indispensable pour présenter un visuel de classification uniforme (on ne peut pas voir une bulle nommée "Greece", puis une autre nommée "Ellás").

Enfin, pour économiser des appels à l'API, nous utilisons une solution tout aussi efficace en terme de résultats, et surtout plus rapide, en utilisant un fichier JSON regroupant tous les pays du monde selon leur code pays (par exemple FR pour la France). Le code pays est récupéré à la volée dans l'étape précédente de l'appel à l'API GeoNames. Chaque pays a l'information du continent où elle se trouve.

Les appels à l'API prenant un temps non négligeable (moins d'une dizaine de minutes), nous avons mis en place un fichier buffer qui sauvegarde les résultats des appels à l'API selon la requête passée, en ne gardant que l'information de localisation nécessaire. Si une donnée est présente dans le buffer (écrit en JSON), la donnée sera récupérée dans ce fichier plutôt que grâce à un appel à l'API distante.

Partitionnement par ordre alphabétique

Le nombre de données étant très important, on peut se retrouver avec un grand nombre de "bulles" affichées à un niveau donné (beaucoup de villes dans un pays par example), ce qui rend la visualisation peu claire et informative. Nous avons fait le choix, lorsqu'il y a trop de données sur un niveau, de les grouper par intervalle alphabétique. Ce groupement se fait à partir d'un minimum de 10 données sur un niveau, et les intervalles sont construits pour équilibrer le nombre d'intervalles affichés et le nombre de données dans chaque intervalle : si l'on doit afficher 25 villes, on affichera 5 intervalles de 5 villes chacun.
Ces groupements peuvent se faire à tout niveau (sauf continents) : groupement de pays, de villes ou d'artistes.

Gestion de la recherche d'artiste

Après génération du fichier research.json, et de chaque fichier correspondant à l'artiste et ses oeuvres sous le format <id>.json, il nous a suffi de parcourir le tableau de noms des artistes en exécutant une distance de Levenshtein sur chaque nom, afin d'en trouver le plus proche. Une fois qu'on l'a trouvé, on récupère l'id de l'artiste, puis on lance le traitement d'affichage de ses oeuvres, comme si on avait cliqué dessus dans la hiérarchie du packed circles.

Lorsque l'on a recherché un artiste, l'algorithme positionne automatiquement la représentation en packed circles au bon endroit. Ainsi, on peut remonter pour voir la ville et le pays de l'artiste concerné.

Problèmes rencontrés

Dans un premier temps nous affichions tous les niveaux d'imbrication et chaque élément indépendamment sans regroupement. Mais etant donné que le nombre de pays, de villes et d'artistes est assez important le navigateur avait beaucoup de mal à afficher l'ensemble des informations et cela était illisible.
Nous avons donc tout d'abord choisi de n'afficher qu'un seul niveau d'imbrication à la fois en masquant l'intérieur d'un noeud tant qu'on ne clique pas dessus. Ensuite la granularité était encore trop fine pour les 3 niveaux d'imbrication donc nous les avons regroupés par intervalle, suivant leur ordre alphabétique.

Certains artistes, comme Joseph Mallord William Turner, ont beaucoup d'oeuvres répertoriées, contrairement à d'autres, ce qui fait que certains noeuds étaient trop grands comparés aux autres avec peu d'oeuvres. Nous avons donc appliqué une taille du noeud en fonction de la racine carrée du nombre d'oeuvres.

Architecture

L'architecture du projet est la suivante :

  • / : la racine. Elle contient les 2 fichiers html, ainsi que le script launch.sh
  • /js : contient tous les fichiers Javascript nécessaires au bon fonctionnement du site web
  • /css : contient le fichier style.css, qui contient le style des pages web ainsi que de ce rapport
  • /assets : contient quelques images qui seront affichées lors de la présentation des tableaux. Une pour les tableaux dont l'image n'est pas disponible à cause du copyright, une pour représenter les artistes de sexe masculin et une pour représenter les artistes de sexe féminin.
  • /collection : contient les 2 fichiers artist_data.csv et artwork_data.csv, quelques fichiers .json nécessaires à la détermination du pays, et plus important, les scripts nécessaires à la conversion de ces données en multiples fichiers json. C'est dans ce dossier que seront générées les données concernant les artistes et leur géolocalisation, ainsi que celui permettant de faciliter la recherche.
  • /collection/artists : ce dossier contiendra de nombreux fichiers json (un par artiste), générés par les scripts python. Ces fichiers contiennent les graphes représentant l'artiste et ses oeuvres.

Bonus

Sur une note plus mathématique, nous avons voulu "jouer" avec ces données du Tate Museum en mettant en pratique des outils vu dans un autre cours : la mesure de similarité et le clustering.
L'idée est de calculer et visualiser le degré de similarité entre œuvres. Ceci se fait en 3 phases :

  • Pré-traitement en python, en lisant l'ensemble des fichiers JSON fournis par le Tate, extrayant pour chaque œuvre les données qu'on peut comparer. On exporte en CSV ces données (une ligne par œuvre).
  • Traitement avec le langage R, outil extrêmement puissant qui nous permet de faire une matrice de dissimilarité comparant chaque paire d'œuvre.
    • On commence par créer une Dataframe, c'est a dire une matrice dont les colonnes ont différents types (artiste, année, dimensions...), chaque ligne étant une œuvre.
    • On calcule la matrice de dissimilarité pour chaque couple d'œuvres. Pour cela, on calcule la dissimilarité pour chaque colonne puis on fait la moyenne. On utilise différentes methodes pour calculer ces dissimilarités puisque les colonnes sont de différents types (numérique, ordinal ou nominal).
    • On fait une segmentation hiérarchique ascendante pour obtenir une structure hiérarchique qu'on peut exporter en JSON.
  • Visualisation grâce à D3, sous la forme d'un dendrogramme (arbre hiérarchique regroupant les œuvres les plus similaires).
Si vous voulez re-générer les données, il vous faudra récupérer les données JSON du dossier artworks/ du github du Tate Museum et les placer dans collection/artworks/. Ainsi, un utilisateur appréciant une œuvre pourrait aller chercher les œuvres similaires grâce à cet arbre.
Après avoir lancé le script launch.sh (qui lance donc un serveur python), on peut visualiser cet arbre à l'adresse http://localhost:8000/tree.html. Il est a noter que cette visualisation pourrait être beaucoup plus poussée et précise, mais ce n'est que le résultat d'expériences par curiosité, que nous avons inclu en ouverture sur ce jeu de données !