« BottinBot1 » : différence entre les versions

De Wikipast
Aller à la navigation Aller à la recherche
 
(13 versions intermédiaires par le même utilisateur non affichées)
Ligne 6 : Ligne 6 :


Ce bot va extraire les données de ces annuaires et créer les pages dans wikipast. Le BottinBot1 que nous avons développé traite les données des années 1839 à 1848 [https://drive.google.com/open?id=1A6v_xDeul3HnPcsojaxYO2KgvIcbO8Dv]. Il peut bien entendu être utilisé pour traiter d'autres données.
Ce bot va extraire les données de ces annuaires et créer les pages dans wikipast. Le BottinBot1 que nous avons développé traite les données des années 1839 à 1848 [https://drive.google.com/open?id=1A6v_xDeul3HnPcsojaxYO2KgvIcbO8Dv]. Il peut bien entendu être utilisé pour traiter d'autres données.


== Description technique ==
== Description technique ==


=== Lecture du bottin ===
=== Lecture du bottin ===
Ligne 33 : Ligne 31 :
=== Exécution du BottinBot ===
=== Exécution du BottinBot ===


Le bot peut être lancé sur des données non processées ou bien des données préprocessées a moyen du flag <code>--pre_process</code> qui doit prendre les valeurs <code>1</code> pour effetuer le préprocessing  ou <code>0</code> pour indiquer que le fichier donné en entrée est déjà préprocessé et prêt à être uploadé sur wikipast.
Le bot peut être lancé sur des données non processées ou bien des données préprocessées a moyen du flag <code>--pre_process</code> qui doit prendre les valeurs <code>'1'</code> pour effetuer le préprocessing  ou <code>'0'</code> pour indiquer que le fichier donné en entrée est déjà préprocessé et prêt à être uploadé sur wikipast.


L'argument <code>--file_name</code> est utilisé pour indiquer un fichier CSV ou bien un fichier Pickle de données préprocessées.  
L'argument <code>--file_name</code> est utilisé pour indiquer un fichier CSV ou bien un fichier Pickle de données préprocessées.  
Ligne 42 : Ligne 40 :


Preprocessing :
Preprocessing :
<syntaxhighlight lang="bash">
$ python backend.py --file_name bottinbot1.csv --pre_process 1
</syntaxhighlight>


<code>$ python backend.py --file_name bottinbot1.csv --pre_process 1</code>
   
   
Upload only from pickle file :
Upload only from pickle file :
<source lang="bash">
 
$ python backend.py --file_name save.pkl --pre_process 0
<code>$ python backend.py --file_name save.pkl --pre_process 0</code>
</source>


== Stratégies adoptées ==
== Stratégies adoptées ==
Ligne 57 : Ligne 52 :
*Nous avons adopté une approche se basant sur un pré-processing des données pour réduire les erreurs d'orthographes et les erreurs d'OCR.
*Nous avons adopté une approche se basant sur un pré-processing des données pour réduire les erreurs d'orthographes et les erreurs d'OCR.


*Cette approche consiste en définir un seuil de rassemblement pour les chaines de caractères. Si deux chaines sont jugées semblables, la forme qui a apparaît à une fréquence plus élevée dans les données remplace l'autre.
*Cette approche définit un seuil de rassemblement pour les chaines de caractères. Si deux chaines sont jugées semblables, la forme la plus fréquente dans les données remplace l'autre.


*Vu que les rues ont des noms officiels avec un orthographes fixe, nous avons décidé homogénéiser leur écriture pour éliminer les éventuelles erreurs. Nous avons décidé de commencer par les traiter.
*Vu que les rues ont des noms officiels avec une orthographe fixe, nous avons décidé d'homogénéiser leur écriture pour éliminer les éventuelles erreurs. Nous avons décidé de commencer par les traiter.


*Ensuite, nous avons adopté une approche "Divide and Conquer" où on homogénéise l'écriture de chaque métier dans la même rue, et ensuite le nom ayant la même rue et le même métier.
*Ensuite, nous avons adopté une approche "Divide and Conquer" où on homogénéise l'écriture de chaque métier dans la même rue, et ensuite le nom ayant la même rue et le même métier.


*Après plusieurs tests sur des échantillons de nos données nous avons fixés un seuil de 80% pour les rues et les métiers, mais garder un seuil plus stricte de 90% pour les noms vu que c'est une donnée plus sensible.
*Après plusieurs tests sur des échantillons de nos données nous avons fixés un seuil de 80% pour les rues et les métiers, mais gardé un seuil plus stricte de 90% pour les noms vu que c'est une donnée plus sensible.


*A la fin de ce traitement, nous avons une liste de Dataframes, chaque Dataframe représente ce qu'on estime est une personne (même nom, même métier et même rue; tout cela après l'homogénéisation).
*A la fin de ce traitement, nous avons une liste de Dataframes, chaque Dataframe représente ce qu'on estime être une personne (même nom, même métier et même rue; tout cela après l'homogénéisation).
*On sauvegarde cette liste dans un fichier Pickle. pour les exécutions ultérieures il suffit de lire ce fichier et passer procéder à traiter la liste en résultant.
 
*On sauvegarde cette liste dans un fichier Pickle. Pour les exécutions ultérieures il suffit de lire ce fichier et passer à la phase de téléversement des pages sur wikipast.


*En outre, nous avons éliminé les points dans le champ "number", ainsi que les caractères spéciaux dans les noms.
*En outre, nous avons éliminé les points dans le champ "number", ainsi que les caractères spéciaux dans les noms.
Ligne 72 : Ligne 68 :
=== Stratégie pour les erreurs d'homonymie ===
=== Stratégie pour les erreurs d'homonymie ===


Nous avons choisi de nommer les pages de façon précise :


<code>{nom} - {métier} ({rue})</code>


=== Stratégie pour les erreurs d'OCR ===
Selon nous une personne est donc charactérisée par la même rue, le même métier et le même nom.


Pour les personnes qui possèdent le même nom nous avons crée une page de désambiguïsation :


<code>{nom} (homomymie)</code>
Avec cette méthode nous pensons éviter les erreurs d'homonymie. Il est toute fois possible qu'une personne dont la description du métier change se retrouve avec deux pages différentes. Mais nous avons considéré que c'était plus correct que de risquer de fusionner des personnes différentes.


== Évaluation des performances ==
== Évaluation des performances ==


=== Évaluation des performances techniques ===
=== Évaluation des performances techniques ===
Le gros du travail de notre bot est dans le pre-processing, il met environ une heure 25 minutes pour traiter le Dataframe original et le sauvegarder dans le fichier Pickle.
*Le traitement pre-processing de notre bot met environ 1 heure 25 minutes pour traiter le Dataframe original et le sauvegarder dans le fichier Pickle. Sachant que cette opération ne nécessite pas d'interactions réseau, le temps d'exécution est relativement long. C'est parce que la méthode de nettoyage est de l'ordre O(N^2 * M) où N est le nombre de chaines uniques dans le champ que l'on veut nettoyer et M est le nombre total d'entrées dans le DataFrame
*Sachant qu'on utilise cette méthode pour nettoyer trois champs différents (rue, métier et nom), le coût de calcul est très important


=== Évaluation du nombre de pages générées et modifiées ===
=== Évaluation du nombre de pages générées et modifiées ===
Ligne 87 : Ligne 90 :


== Analyse critique ==
== Analyse critique ==
 
*L'approche de pre-processing adoptée, lourde en calculs comme elle est, nous a permis de réduire le nombre de pages erronées qui auraient été sur le site.
 
*Le critère stricte que nous avons choisi pour définir une personne (même nom, rue et métier) a amené à certains cas d'homonymie qui auraient pu être évités avec des critère plus souples.
*Le fait que nous avons pas adopté la même convention que les autres groupes pour les titres de pages a introduit un nombre important de page doublons dans [[wikipast | WikiPast]]. Pratiquement notre recherche ne tombe jamais sur une page que nous n'avons pas créée nous mêmes.


== Code ==
== Code ==
Le code est disponible sur GitHub[https://github.com/aalshabaan/SHSBottin_1]
Le code est disponible sur GitHub[https://github.com/aalshabaan/SHSBottin_1]

Dernière version du 20 mai 2020 à 10:24

Résumé des fonctionnalités

En 2019, l’équipe du DHLAB a effectué une extraction de 4 Million d’adresses dans les anciens annuaires de la ville de Paris.

Di Lenardo, I., Barman, R., Descombes, A., Kaplan F. (2019). Repopulating Paris: massive extraction of 4 Million addresses from city directories between 1839 and 1922, Digital Humanities conference DH2019, Utrecht, Pays-Bas, [1]

Ce bot va extraire les données de ces annuaires et créer les pages dans wikipast. Le BottinBot1 que nous avons développé traite les données des années 1839 à 1848 [2]. Il peut bien entendu être utilisé pour traiter d'autres données.

Description technique

Lecture du bottin

On utilise la librairie Pandas pour lire les données dans le fichier CSV qui nous a été accordé et les organiser dans un objet DataFrame.

A première vue, nous avons 390223 entrées dans notre fichier CSV. Celles-ci sont des entrées entre l'année 1839 et 1848.

Nous avons choisi de ne pas prendre les lignes contenant des valeurs NaN, ceci nous a amené à ne traiter que 389599 entrées. Soit une perte de 0.15%

Vérification d'existence

Avant de créer une page nous nous assurons toujours si elle n'existe pas auparavant. Si elle n'existe pas, la page est créée sinon elle est simplement modifiée en rajoutant la donnée au bon endroit chronologiquement.

Tri automatique croissant par date

Les données sont triées par ordre croissant de date, un algorithme (sort_year) s'occupe de réordonner les entrées. L'algorithme consiste à séparer le texte de la page par ligne et de détecter les dates des événements déjà existants. Ensuite on parcourt la liste d'années pour détecter où l'insertion se fait (ligne précédant l'endroit où l'on veut insérer la donnée). Enfin on ne modifie l'ancien texte de la page qu'en insérant la nouvelle donnée au bon endroit dans l'ancien texte.

Desambiguation

Lors de la création d'une nouvelle page, un en-tête redirigeant vers une page d'homonymie de nom est crée/modifiée. La page d'homonymie permet de désambiguïser quant aux entrées présentant le même nom mais pas la même adresse ou le même travail par exemple.

Exécution du BottinBot

Le bot peut être lancé sur des données non processées ou bien des données préprocessées a moyen du flag --pre_process qui doit prendre les valeurs '1' pour effetuer le préprocessing ou '0' pour indiquer que le fichier donné en entrée est déjà préprocessé et prêt à être uploadé sur wikipast.

L'argument --file_name est utilisé pour indiquer un fichier CSV ou bien un fichier Pickle de données préprocessées.

Note : le fichier .pkl généré par le bot est nommé save.pkl

Exemple d'utilisation

Preprocessing :

$ python backend.py --file_name bottinbot1.csv --pre_process 1

Upload only from pickle file :

$ python backend.py --file_name save.pkl --pre_process 0

Stratégies adoptées

Stratégie générale

  • Nous avons adopté une approche se basant sur un pré-processing des données pour réduire les erreurs d'orthographes et les erreurs d'OCR.
  • Cette approche définit un seuil de rassemblement pour les chaines de caractères. Si deux chaines sont jugées semblables, la forme la plus fréquente dans les données remplace l'autre.
  • Vu que les rues ont des noms officiels avec une orthographe fixe, nous avons décidé d'homogénéiser leur écriture pour éliminer les éventuelles erreurs. Nous avons décidé de commencer par les traiter.
  • Ensuite, nous avons adopté une approche "Divide and Conquer" où on homogénéise l'écriture de chaque métier dans la même rue, et ensuite le nom ayant la même rue et le même métier.
  • Après plusieurs tests sur des échantillons de nos données nous avons fixés un seuil de 80% pour les rues et les métiers, mais gardé un seuil plus stricte de 90% pour les noms vu que c'est une donnée plus sensible.
  • A la fin de ce traitement, nous avons une liste de Dataframes, chaque Dataframe représente ce qu'on estime être une personne (même nom, même métier et même rue; tout cela après l'homogénéisation).
  • On sauvegarde cette liste dans un fichier Pickle. Pour les exécutions ultérieures il suffit de lire ce fichier et passer à la phase de téléversement des pages sur wikipast.
  • En outre, nous avons éliminé les points dans le champ "number", ainsi que les caractères spéciaux dans les noms.

Stratégie pour les erreurs d'homonymie

Nous avons choisi de nommer les pages de façon précise :

{nom} - {métier} ({rue})

Selon nous une personne est donc charactérisée par la même rue, le même métier et le même nom.

Pour les personnes qui possèdent le même nom nous avons crée une page de désambiguïsation :

{nom} (homomymie)

Avec cette méthode nous pensons éviter les erreurs d'homonymie. Il est toute fois possible qu'une personne dont la description du métier change se retrouve avec deux pages différentes. Mais nous avons considéré que c'était plus correct que de risquer de fusionner des personnes différentes.

Évaluation des performances

Évaluation des performances techniques

  • Le traitement pre-processing de notre bot met environ 1 heure 25 minutes pour traiter le Dataframe original et le sauvegarder dans le fichier Pickle. Sachant que cette opération ne nécessite pas d'interactions réseau, le temps d'exécution est relativement long. C'est parce que la méthode de nettoyage est de l'ordre O(N^2 * M) où N est le nombre de chaines uniques dans le champ que l'on veut nettoyer et M est le nombre total d'entrées dans le DataFrame
  • Sachant qu'on utilise cette méthode pour nettoyer trois champs différents (rue, métier et nom), le coût de calcul est très important

Évaluation du nombre de pages générées et modifiées

Analyse critique

  • L'approche de pre-processing adoptée, lourde en calculs comme elle est, nous a permis de réduire le nombre de pages erronées qui auraient été sur le site.
  • Le critère stricte que nous avons choisi pour définir une personne (même nom, rue et métier) a amené à certains cas d'homonymie qui auraient pu être évités avec des critère plus souples.
  • Le fait que nous avons pas adopté la même convention que les autres groupes pour les titres de pages a introduit un nombre important de page doublons dans WikiPast. Pratiquement notre recherche ne tombe jamais sur une page que nous n'avons pas créée nous mêmes.

Code

Le code est disponible sur GitHub[3]