ChatGPT pour aider à coder un projet de numérisation sur le jeu de rôle (1/)

Je me considère comme un « programmeur du dimanche ». J’ai appris Turbo Pascal au lycée au siècle passé. Récemment, j’ai travaillé sur de petits projets de programmation en R et en dot. Depuis un certain temps, j’ai eu l’ambition de numériser et d’analyser des textes en utilisant Python, mais j’ai été bloqué par un manque d’expertise personnelle et de soutien externe. C’est alors que ChatGPT est survenue…

Capture d’écran Spyder

Avantages de ChatGPT pour les chercheurs non-programmeurs

  • Disponible gratuitement depuis novembre 2022, cet outil requiert seulement un numéro de téléphone portable et un compte Gmail pour y accéder.
  • Il est suffisamment performant pour coder en Python, un langage adapté à la numérisation et la recherche de texte, même si vous n’avez aucune connaissance dans ce langage.
  • Il permet également de nombreuses interactions fluides pour clarifier vos besoins et il vous guide efficacement pour déboguer votre code en identifiant les erreurs.
  • De plus, cet outil est corvéable à merci, à tout moment de la journée ou de la nuit.

Inconvénients

  • Il est important d’avoir une compréhension minimale des concepts de base tels que les langages de programmation, le code informatique (variables, boucles, etc.), les formats de fichiers et le système d’exploitation pour tirer le meilleur parti de l’utilisation de ChatGPT. Si vous ne comprenez pas certains termes ou concepts, n’hésitez pas à demander des explications à ChatGPT pour apprendre.
  • Il peut arriver que ChatGPT propose du code pour des versions obsolètes de Python. Dans ce cas, reformulez votre demande et demandez-lui d’autres méthodes pour des fonctions plus récentes. Généralement, après environ 6 à 8 interactions, le bon code émerge et vous devez l’assembler vous-même.
  • En ce qui concerne l’utilisation de bouts de code, je considère important de citer mes sources. Dans ce cas de ChatGPT, c’est problématique car les sources qui ont servi à l’entraîner sont invisibilisées. Si vous ne savez pas à qui attribuer le code, vous pouvez au moins mentionner ChatGPT pour le travail accompli (voir billet auquel j’ai participé pour Zotero francophone). Citer ses sources est un aspect éthique important quand on utilise code open-source.

Comment ?

  • Pour commencer à coder en Python, il est recommandé d’installer Anaconda, qui est une plateforme open-source populaire pour la science des données. Vous pouvez télécharger Anaconda depuis le site web officiel et suivre les instructions d’installation.
  • Après l’installation d’Anaconda, vous pouvez utiliser l’IDE (environnement de développement intégré) Spyder pour écrire et exécuter votre code Python. Spyder est inclus dans l’installation d’Anaconda et est généralement prêt à être utilisé.
  • Il est également important d’installer les packages dont vous avez besoin au fur et à mesure que vous en avez besoin. Vous pouvez le faire en utilisant la commande pip dans l’invite de commande (ou terminal si vous utilisez un Mac ou Linux) ou en utilisant l’interface graphique de Anaconda Navigator.
  • Enfin, vous pouvez utiliser ChatGPT sur OpenAI ou Bing+ChatGPT de manière alternée pour obtenir de l’aide supplémentaire sur votre code. À mon niveau, les deux plateformes sont assez similaires en termes de fonctionnalités et de performances.

Objectifs du projet

  • Classer des PDF dans des dossiers.
  • Extraire et retravailler leurs métadonnées en Python et csv.
  • Extraire le texte intégral en Python et autres.
  • Verser les métadonnées et le texte intégral dans une base de données SQlite.
  • Jouer avec la base de données SQlite (aspect développé dans un prochain billet).

Problèmes rencontrés

Avec les fichiers PDFs

  • Dans mon corpus de PDFs, il est très courant de rencontrer des noms de fichiers avec des caractères problématiques. En effet, ils peuvent avoir été nommés à partir d’encodages ou de systèmes d’exploitation très hétérogènes (depuis 2000 environ et de partout sur la planète). Il est recommandé de renommer les fichiers pour une meilleure identification et organisation.
  • Les méthodes de production de PDF peuvent également varier considérablement, ce qui peut rendre difficile leur traitement. Certains fichiers peuvent contenir des images numérisées sans OCR, tandis que d’autres peuvent contenir du texte électronique ou avoir déjà été soumis à une reconnaissance optique de caractères (OCR). Il est important de prendre en compte ces différences lors de la manipulation des fichiers pour garantir des résultats précis.
  • Il peut également arriver que certains fichiers PDF soient protégés par des verrous électroniques, ce qui empêche toute modification ou manipulation. Dans ce cas, vous pouvez essayer de trouver des outils pour supprimer les verrous électroniques, ou demander l’autorisation de l’auteur ou du propriétaire des fichiers.
  • Enfin, certains fichiers PDF peuvent être bugués ou corrompus, ce qui peut causer des problèmes lors de leur manipulation. Il est recommandé de tester les fichiers pour détecter les erreurs et les problèmes, et de prendre les mesures nécessaires pour résoudre ces problèmes.
  • Rajouter des lignes de codes pour « tester » les PDFs et les mettre de côté en cas de bogue a constitué une partie non négligeable et frustrante du codage informatique.

Avec Python

  • Je ne sais toujours pas…
    • Comment fonctionnent les environnements, kernels, etc. (voir XKCD)
    • Comment mettre à jour Python et le reste.
    • Si tout tournera bien et identiquement dans 5 ou 10 ans.
    • Comment lancer Adobe Acrobat sur des fichiers PDF depuis Python (du coup, j’ai abandonné pour le mieux et ça m’a fait simplifier le flux de travail ainsi qu’apprendre à utiliser pyTesseract).

Structure des dossiers et fichiers

  • Yragatheque
    • A
      • Apocalypse World
        • Apocalypse World 1st ed
          • Apocalypse World 1st ed.pdf
        • Apocalypse World 2nd ed
          • Apocalypse World 2nd ed.pdf
    • B
      • Bunnies & Burrows
        • archives
          • HomebrewB&B.pdf
        • 1st ed
          • B&B1sted.pdf
        • GURPS ed
          • GURPS B&B.pdf
      • _Baguettes & Fromages
        • B&F2e.pdf
    • _working_directory
    • _corrupted

Explications :

  • Les scripts ne traitent que les fichiers PDF.
  • Les fichiers PDF placés dans les répertoires archives sont ignorés (ex: HomebrewB&B.pdf est ignoré).
  • Les fichiers PDF placés dans les répertoires précédés du caractère _ sont ignorés (ex: B&F2e.pdf est ignoré).
  • Yragatheque est le niveau le plus haut. C’est la racine de l’arbre de la collection des PDFs.
  • A, B, C,… sont le 2e niveau. C’est la classification alphabétique de tous les jeux.
  • Apocalypse Word est au 3e niveau. À ce niveau se trouvent les noms des jeux.
  • Tous les niveaux en dessous (4e niveau et au-delà) sont des éditions, ou des gammes, ou des sous-classifications.
  • _working_directory contient les fichiers csv produits, les listes d’autorité et la base de données SQLite.
  • _corrupted contient tous les fichiers PDFs et fichiers associés (yaml, rawtext,…) qui n’ont pu être traité (non ouvert car corrompus, pages internes illisibles,…).

Scripts et flux de numérisation

Les fichiers nommés 00-nom sont des scripts Python.

  • Préparation :
    • PARAMETERS : contient l’adresse du dossier dans lequel se trouve la collection des PDFs.
    • 00-createWorkingDir : création du dossier _working_directory s’il n’existe pas.
    • 01-permission : parcours tous les dossiers et donne les droits en lecture-écriture partout
    • 02-purge : supprime les fichiers .yaml , .rawtext et .ocrtext qui peuvent subsister de traitements précédents
    • 03-rename : normalise les noms de fichiers (supprime les accents, les caractères spéciaux, remplace les espaces par des traits, etc.)
  • Métadonnées :
    • 10-pdf2yaml : créé un fichier .yaml du même nom que le fichiers pdf, au même emplacement, avec comme variables :
      • path = chemin absolu du fichier pdf
      • name = nom du fichier sans .pdf
      • size = poid du pdf en Mb
      • pages = nombre de pages du pdf
      • game = nom du dossier de 3e niveau
      • line = nom des dossiers de 4e niveau et+
    • 11-yaml2csv
      • Écrit un fichier metadata.csv à partir de tous les fichiers .yaml de toute la collection.
      • À cette étape, on peut modifier le fichier metadata.csv pour y ajouter des colonnes (et donc des nouvelles variables yaml), modifier le contenu, etc. Il est recommandé de faire une sauvegarde du fichier modifié (exemple : metadata.backup.csv) pour ne pas écraser toutes ces modifications manuelles.
    • 12-csv2yaml
      • Prend le contenu du fichier metadata.csv et réécrit tous les fichiers .yaml de la collection avec le nouveau contenu.
  • Numérisation :
    • 30-pdf2rawtext
      • Créé un fichier .rawtext de même nom que le pdf au même emplacement, contenant l’extraction du texte si le fichier pdf est au format numérique ou s’il y a une couche d’OCR extractible. Si l’extraction ne fonctionne pas ou pose problème, un fichier est créé tout de même mais vide.
    • 34-OCR-byTesseract
      • Certains fichiers pdf sont récalcitrants à l’extraction mentionnée précédemment. Alors, si le fichier .rawtext est vide ou tout petit, on lance une numérisation via Tesseract qui va créer un fichier .orctext au même endroit que le fichier pdf. C’est un processus assez long.
  • Exportation :
    • 40-yamlntext2sqlite
      • On envoie le fichier .yaml, accompagné du fichier .rawtext ou .ocrtext (le plus gros) correspondant, dans une base de données SQlite nommée TTRPG_LLM.sqlite
    • 50-reportSQlite
      • On créé un rapport de la base de données.
    • 51-searchSQlite
      • On cherche une chaîne de caractère dans la base de données.

Prochainement

  • Les scripts Python sont dans GitHub à https://github.com/pmartinolli/pyTTRPG_LLM 
  • Je travaillerai les données dans SQlite pour repérer quel jeu cite quel jeu et pour tenter de produire des rapports d’observation intéressants.
  • Pour le moment, les colonnes supplémentaires ajoutées dans le fichier metadata.csv et exportées dans les fichiers .yaml ne sont pas intégrées dans la base SQLite.
    • Exemple : edition, langue
    • Il serait intéressant d’incorporer un travail de reconciliation avec Wikidata sur le fichier metadata.csv pour récupérer :
      • pour la colonne game : le QID de la famille de jeu (cela devrait être presque du 100%)
      • pour chaque document moissonné : le QID de l’édition de ce document (plus rare).

La première partie de ce billet a été partiellement retouchée par ChatGPT Mar 23 Version le 21 avril 2023. Billet modifié le 11 mai 2023.

Commentaire de ChatGPT à propos de ce billet :

« C’est génial que vous ayez pu utiliser ChatGPT pour progresser dans votre projet de numérisation et de fouille de texte en Python ! ChatGPT peut être une excellente ressource pour apprendre de nouvelles compétences en programmation ou résoudre des problèmes techniques. En tant que programmeur du dimanche, il est normal de ne pas avoir une expertise approfondie dans tous les aspects de la programmation, mais il est important de continuer à apprendre et à s’améliorer. ChatGPT peut vous aider à combler ces lacunes et à vous permettre de réaliser vos projets de manière autonome. N’hésitez pas à poser des questions et à explorer de nouvelles idées avec ChatGPT pour continuer à progresser dans votre parcours de programmation. »

(sic transit gloria mundi)

Fouille de texte dans les éditions de D&D (Étape 1 : choisir l’extraction pdf)

Cet essai est un bac à sable pour expérimenter un flux de données et leur traitement en fouille de texte (text mining). Cette première partie compare différentes méthodes pour sortir des données des pdf.

Les fichiers pdf sont extrêmement hétérogènes. Cela va du fichier produit professionnellement et électroniquement au fichier numérisé à la main dans un garage avec plein de bugs dans la structure.

Flux de données

1. Sélection du corpus des données

Seuls les livrets ou la boîte de base de chaque édition de D&D sont sélectionnées.

2. Récolte des différentes éditions en pdf

Cette récolte a été effectuée par des moyens que les lois sur la propriété intellectuelle réprouve. Je brave le risque en me disant que je fais ça dans un but purement académique.

3. Renommage des fichiers

Old Dungeons & Dragons (1974 ed.)
1974-odd-mnm : booklet no.1, Men & Magic
1974-odd-mnt : booklet no.2, Monsters & Treasures
1974-odd-unw : booklet no.3, The Underworld & Wilderness
Adventures
1974-odd-rs : reference sheet

D&D boxed set Holmes ed. (1977)
1977-ddholmes-box

D&D Moldvay ed. (1981)
1981-ddmoldvay-basic : Basic boxed set
1981-ddmoldvay-expert : Expert boxed set

D&D BECMI Mentzer ed. (1983)
1983-ddbecmi-b : Basic boxed set
1983-ddbecmi-e : Expert boxed set
1983-ddbecmi-c : Companion boxed set
1983-ddbecmi-m : Master boxed set
1983-ddbecmi-i : Immortal boxed set

Advanced Dungeons & Dragons (1979)
1979-add1-mm : Monster Manual
1979-add1-phb : Player’s Handbook
1979-add1-dmg : Dungeon Master Guide

Advanced Dungeons & Dragons 2nd (1989)
1989-add2-phb : Player’s Handbook
1989-add2-dmg : Dungeon Master Guide
1989-add2-mm : Monstrous Compendium vol.1

Advanced Dungeons & Dragons 2nd Revised ed. (1995)
1995-add2r-phb : Player’s Handbook
1995-add2r-dmg : Dungeon Master Guide
1995-add2r-mm : Monster Manual

Dungeons & Dragons 3rd ed. (2000)
2000-dd3-phb : Player’s Handbook
2000-dd3-dmg : Dungeon Master Guide
2000-dd3-mm : Monster Manual

Dungeons & Dragons 3.5 ed. (2003)
2003-dd35-phb : Player’s Handbook
2003-dd35-dmg : Dungeon Master Guide
2003-dd35-mm : Monster Manual

Dungeons & Dragons 4th ed. (2008)
2008-dd4-phb : Player’s Handbook
2008-dd4-dmg : Dungeon Master Guide
2008-dd4-mm : Monster Manual

Dungeons & Dragons 5h ed. (2014)
2014-dd5-phb : Player’s Handbook
2014-dd5-dmg : Dungeon Master Guide
2014-dd5-mm : Monster Manual

4. Déplacement de tous les fichiers

Tous les pdfs sont placés dans un dossier \pdfraw à la racine du projet.

5. Préparation des pdf : OCR

Je lance une reconnaissance de caractères (OCR) dans les pdf numérisés qui n’ont pas encore reçu ce traitement. Il y en a peu (2 seulement).

Avec le logiciel Adobe Acrobat 2017 : Passe à 600 dpi. Traitement en lot possible mais la sélection des fichiers à reconnaître doit être faite manuellement.

Dans le logiciel PDF Converter Elite 5, l’OCR se fera toute seule lors de l’exportation (étape 6). Cela va même plus loin puisque ce dernier ignore les OCR effectuées et enregistrées précédemment et il refait les siennes (ça prend un temps fou du coup : 5h).

6. Exportation des PDF aux format TXT et XML.

Quand l’option est disponible, je choisis l’encodage UTF-8.

Avec Adobe Acrobat 2017

  • TXT (brut, plain).
  • TXT (accessible, acessible).
  • XML 1.0 : sans images.

Traitement en lot décevant : 1) automatisation possible via le créateur d’Actions mais beaucoup trop de fenêtres intermittentes stoppant le processus et demandant des clics de validation; 2) quelques erreurs de transcriptions au format txt; 3) le format txt (Accessible) ignore beaucoup contenus de fichiers (0 Ko ou 3 Ko); 4) le format XML 1.0 est mal formé (très dur de le charger dans R) et contient plein d’erreurs.

Avec Calibre 4.13

Traitement en lot décevant aussi (le processus est facile et continu mais l’exportation échoue pour plusieurs PDF). Paramétrage nécessaire pour garder le nom de fichier original.

Avec le package pdftools de R Studio

Globalement bon et rapide, mais il y a des erreurs et je n’arrive pas à identifier où car les logs d’erreurs ne le disent pas (mentions de PDF error: read ICCBased color space profile error et PDF error: not an ICC profile, invalid signature).

Syntaxe du code R pour charger les données :

# install.packages("pdftools")
library(pdftools)

# make a list of all pdf files in pdfraw folder
files <- list.files(path="pdfraw", pattern="*.pdf", full.names=TRUE)

# put all the files into a bigdata variable
bigdata <- lapply(files, pdf_text)

Avec PDF Converter Elite 5

Traitement en lot en continu. Comme mentionné précédemment : le logiciel lance un OCR sur tous les fichiers pdf numérisés, même ceux avec déjà une couche OCR.

Tableau de comparaison des exportations

Acrobat 2017 Calibre 4.13 pdftools PDF Conv. 5
logiciel propriétaire libre libre propriétaire
formats xml 1.0 / txt:plain / txt:acessible txt txt txt
flux du traitement batch interrompu constamment quelques interruptions continu continu
durée du traitement : 33 fichiers, 1Go total 30 min. / 30 min. / 30 min. 14 min. 2 min. 5h
nb mots total du corpus (6 756 pages) en millions 5,07 (c) / 4,68 (a) / 2,54 (a) 3,44 (a) 5,53 (b) 4,69 (a)
fichiers ignorés (ou dont +95% est manquant) 0 / 4 / 33 11 1 6

Méthodes de calcul du nombre de mots du corpus

(a)

Calculé avec le logiciel Notepad++ et son plugin Combine 1.0 (à installer et qui combine tous les fichiers ouverts dans le logiciel dans un nouveau fichier).
Puis avec l’option Affichage (View) > Résumé (Summary) sur le nouveau fichier combiné.

(b)

Calculé en exportant les données de R Studio avec le script suivant :

#install.packages("erer")
library(erer)
write.list(bigdata,"output.txt")

Et ensuite avec l’option Affichage (View) > Résumé (Summary) sur le fichier output.txt (vu le volume j’ai ignoré le mot result mais il aurait pu être enlevé en multiremplacement dans NP++ pour un corpus plus petit, voir plus bas).

Bonus : un script R pour sortir les fichiers txt procédés par pdftools dans un dossier /pdfexports/pdftools :

library(pdftools)
files <- list.files(path="pdfraw", pattern="*.pdf", full.names=TRUE)
nb_files <- length(files)
for(i in 1:nb_files) {
  onefile <- pdf_text(files[i]) #1 
  x <- gsub("pdfraw/","",gsub(".pdf","",files[i])) #2
  write(onefile,file=paste("pdfexports/pdftools/",x, ".txt", sep="")) #3
}
# 1. process (i) pdf file into onefile
# 2. strip the path and the .pdf to keep the core name
# 3. write a txt file in the subdirectory
# How to encode in utf-8?

(c)

J’ai tenté de charger les xml générés par Acrobat dans R Studio et créer un fichier compilé mais il y a beaucoup de messages d’erreur.

library(readr)
files <- list.files(path="pdfexports/acrobat_xml", pattern="*.xml", full.names=TRUE)
bigdata_xml <- lapply(files, read_csv)
# ici on s'aperçoit de plein de messages d'erreur
library(erer)
write.list(bigdata_xml,"output_xml.txt")

Du coup, j’ai combiné tous les fichiers xml comme dans le point (a). Puis, toujours dans NP++, je multiremplace (Ctrl+H) en mode Expressions régulières :
<[^>]*<[^>]*>[^>]*>|<[^>]*> par rien.
Enfin, j’utilise l’option Affichage (View) > Résumé (Summary) pour compter le nombre de mots.

Moralité

  1. Le format pdf est un format atroce pour faire de la fouille de texte.
  2. pdftools de R Studio est rapide, gratuit mais il peut manquer des choses dans des pdf mal formés.
  3. Les exportations xml 1.0 de Acrobat ne sont pas bien formatées, en tout cas pas assez bien pour les charger aisément dans R Studio. Celle en plain txt est meilleure car moins verbeuse. Dans tous les cas, c’est fastidieux de cliquer à la main pour tous les fichiers.
  4. PDF Converter Elite 5 semble faire une exportation correcte et fluide tant qu’on le laisse tourner pendant la nuit.

Prochaine étape

Je vais faire une analyse plus qualitative des exportations en comparant les différents corpus de txt extraits.


Ce billet a été pré-rédigé dans HackMD puis exporté en html. Je le conseille vivement.

Rechercher dans OpenEdition Search

Vous allez être redirigé vers OpenEdition Search