Géocodage de la base SIRENE

Les nouveautés et mises à jour sont en fin d’article…

La base SIRENE de l’INSEE est disponible en opendata depuis ce matin (5 janvier 2017).

Elle contient des adresses pour chaque établissement, c’est même 3 versions de l’adresse qu’elle contient. Une version “déclarée”, une version “géographique” et une version “normalisée” issue d’une traitement RNVP (Redressement, Normalisation, Validation Postale).

J’avais déjà géocodé ce fichier en préparation du hackathon opensirene qui s’était tenu le 15 novembre 2016, mais là c’est le grand jour, les données “du jour, à jour”. Voici les principales étapes… (et les scripts sont sur github)

Remise en forme du fichier

Le fichier diffusé par l’INSEE est au format CSV, mais un peu en dehors des canons… encodage ISO (et pas UTF8), des quotes en veux-tu en voilà (ils prennent presque 2Go) et une dénormalisation des libellés qui prend elle aussi beaucoup de place.

Une fois ce nettoyage fait (avec csvclean et csvcut de csvkit), on obtient un fichier CSV deux fois moins lourd (4.2Go au lieu de 8.5).

Pour paralléliser la suite des traitements, je le scinde aussi en un fichier par département (avec csvgrep) car vu la volumétrie il faut vraiment tirer au mieux parti de capacité de traitement parallèle des machines actuelles (dans mon cas une workstation bi-Xéon 6 coeurs, soit 24 coeurs en hyperthreading).

Premier géocodage : la BAN

Mon premier géocodage a tout simplement utilisé le moteur “addok” développé à Etalab par Yohan Boniface. Il est très performant car il fonctionne exclusivement en RAM vu qu’il est basé sur Redis , une base de données clé-valeur.

Je charge donc la BAN dans une instance locale d’addok ce qui m’évite de charger inutilement l’instance publique disponible sur adresse.data.gouv.fr

Les premiers résultats sont corrects, mais un nombre non négligeable d’adresses est situé dans des lieux dits sans numérotation et là la BAN montre sa limite car elle ne contient que des adresses numérotées. Si un lieu-dit n’a aucune adresse numérotée, il n’apparaît pas du tout dans la BAN.

Deuxième géocodage: BAN+BANO

Je décide donc de monter une seconde instance d’addok en parallèle (j’ai 96Go de RAM sur ma machine… heureusement car environ 36Go sont pris par ces deux bases), mais cette fois-ci avec BANO, la base produite par OpenStreetMap France, qui elle contient les lieux-dit même sans numéro. Elle est moins complète sur les adresses numérotées, mais le mix des deux permet d’obtenir une couverture bien meilleure.

Pour combiner les résultats, j’écris un script python qui va interroger les deux bases, comparer les résultats et sélectionner celui qui semble le plus proche de l’adresse initiale. En effet, certaines adresses sont plus ou moins complètes, avec ou sans numéro, avec ou sans type de voie. Ceci permet de mieux cibler ce qu’on espère obtenir comme résultat du géocodeur : une adresse numérotée, une rue, un lieu-dit ?

Le résultat est bien meilleur mais il y a encore quelques manques réguliers, sur des adresses qui n’en sont pas vraiment car elles indiquent plutôt un point d’intérêt comme “MAIRIE” ou “BOURG”.

Troisième géocodage: BAN+BANO+POI

Les Points d’Intérêts ajoutés sont peu nombreux :

  • la position des mairies issues du fichiers des services publics de la DILA,
  • la position des chef-lieu de communes issus du “Registre Général des Communes” que l’IGN publiait il y a quelques années mais qui n’existe plus (sauf erreur).

Le résultat est encore un petit peu meilleur même si on n’est pas encore à 100%.

Une amélioration est encore possible de ce côté en complétant avec la localisation de ZAC, ZI, centres commerciaux, gares, station de métro, etc.

Le traitement complet

Les fichiers préparés sont géocodés en parallèle, sur 24 threads, en prenant les plus volumineux en premier car Paris à lui tout seul met 6h20. C’est d’ailleurs la durée totale du géocodage.

Le script python sort un log qui permet de suivre l’avancement, mais aussi des statistiques sur les géocodages obtenus, ainsi que les adresses qui n’ont pas pu être géocodées (dans ce cas, on indique le chef-lieu de la commune dans le fichier géocodé).

Le résultat est disponible pour l’instant sur http://212.47.238.202/geo_sirene/last/ avant que ceci soit industrialisé.

Si vous détectez des problèmes dans le géocodage, vous pouvez les signaler en ouvrant une “issue” sur github et n’hésitez pas aussi à proposer vos améliorations des scripts via des pull-requests et pourquoi pas des améliorations sur addok ou les données BAN, BANO, les POI… bref collaborons !

Nouveautés

A partir du stock d’octobre 2017, le géocodage s’appuie sur une troisième source de données: les Points d’Intérêt (POI) d’OpenStreetMap.

Le code ajouté est visible sur github.

Ceci permet d’avoir une localisation pour les adresses situées en “MAIRIE” (et ses déclinaisons comme “LA MAIRIE” ou “HOTEL DE VILLE”).

De même pour “GARE” et ses déclinaisons. Un traitement spécial a aussi été ajouté pour les centres commerciaux car un nombre non négligeable d’adresse de commerce sont juste rédigées “CENTRE COMMERCIAL MACHIN”.

Un ultime géocodage sur les POI est fait mais le résultat n’est conservé que si le score est élevé.

Pour ces adresses géocodées grâce à des POI, la colonne type indique poi ou poi.xxx, xxx identifie le type POI et l’id est l’URL de l’objet OpenStreetMap correspondant.