InferenceBot/CheckerBot
Le code pour InferenceBot est disponible sur https://github.com/mj2905/InferenceBot. Il suffit de lancer le fichier python main.py.
La déduction est un principe en intelligence artificielle qui permet d’obtenir de nouvelles informations en se basant sur des faits, et des règles déjà établies. C’est donc tout naturellement vers cette technique que nous nous sommes orientés lors du choix pour ce projet d’humanités digitales : le bot d’inférence. Pour ce faire, nous avons divisé le projet en trois parties, chacune pouvant être modulée, afin de pouvoir être étendue par la suite :
- Le “wiki scraping” (récupération des informations), qui nous permet de lire directement récupérer des informations en provenance du wiki. En l'occurrence, pour notre bot, ces informations correspondent aux différents faits qui seront utilisés pour déduire d’autres faits.
- Le moteur d’inférence, qui va inférer des informations à partir de ce qui lui est fourni en entrée.
- Le “wiki writer” (écriture des informations sur le wiki) qui va écrire les faits déduits, considérés comme utiles, dans le wiki.
Le wiki scraping
Le bot va tout d’abord visiter la page du wiki contenant toutes les pages, afin de collecter autant d'adresses url que possible. Par la suite, il va regrouper les adresses, afin d’ouvrir plusieurs connexions en simultané à travers plusieurs threads en parallèle, afin d’accélérer l’obtention d’information. Une fois que les threads ont fini leur tâche, le bot va analyser séquentiellement les données, afin de chercher les potentiels événements utilisables. Cette recherche séquentielle n’affecte pas beaucoup les performances, le gros du temps de travail étant utilisé pour effectuer les requêtes web. Une fois le travail terminé nous obtenons une liste contenant un tableau de sets. Chaque tableau correspond au résultat du scraping pour une seule page, et chaque set correspond aux concepts qui ont été correctement extraits de la page.
Ainsi, la classe du scraper cherche des concepts dans les pages. Ces concepts sont des éléments apparaissant dans les pages considérées comme importantes. Un exemple de concept serait la rencontre entre deux personnes. Pour chaque concept, il y a différents éléments à définir :
keyword : le mot-clef utilisé pour identifier les concepts utiles, find : la liste des tags dans lesquels le concept est identifié extract : l’objet correspondant au concept
Le moteur d’inférence
Ici, il s’agit d’obtenir des faits à partir d’autres faits et règles. Nous avons utilisé un algorithme d’intelligence artificielle appelé “chaînage avant”, qui nous permet d’effectuer ces déductions. L’algorithme a la forme suivante :
Q = faits existants Solutions = liste vide Règles = règles existantes tant que Q n’est pas vide: fait = premier élément de Q si fait n’est pas dans Solutions: ajouter fait à Solutions # Vérifie si des règles sont déclenchées par le nouveau fait. pour chaque règle dans Règles: si le fait satisfait une des conditions de règle, et que l’ensemble des faits déduits (Solutions) peut satisfaire l’ensemble des autres conditions de cette même règle: ajouter la conclusion de la règle à Q renvoyer Solutions
Cet algorithme utilise plusieurs éléments de base : Les faits, qui sont des éléments basique dans notre algorithme, et qui peuvent contenir des variables. Des exemple de faits seraient : père(Paul, Pierre) ou oncle(?A, Jean) avec ?A une variable. Les règles, qui suivent la logique des prédicats, et doivent appartenir à l’ensemble des clauses de Horn. Cet ensemble correspond à tout prédicat sous la forme d’une disjonction de littéraux qui sont tous négatifs, sauf au plus un des littéraux qui peut être positifs. Cela nous permet d’avoir des règles de la forme not(A) or not(B) or … or Z, ce qui peut être réécrit sous la forme (A et B et …) => Z. Nous commençons donc à comprendre comment et pourquoi nous pouvons ajouter la conclusion de la règle (notre Z) à l’ensemble des faits déduits, si l’ensemble des conditions de cette règle (A, B, …) sont satisfaites.
De plus, comme des variables sont impliquées dans nos règles (en effet, nous ne savons pas à l’avance pour qui/quoi ces règles s’appliqueront), nous devons utiliser un algorithme d’unification, qui va pouvoir mettre ensemble deux faits qui peuvent être unifiés, à la manière d’une reconnaissance de motif (pattern matching), et renvoyer l’association des variables identifiées comme définies.
Le wiki writer
Cette étape nous permet de directement écrire sur le wiki les informations utiles obtenues. Etant donné qu’un grand nombre de faits sont déduits, même des faits intermédiaires sans doutes inutiles, il faut pouvoir trier ce qui est obtenu. Ainsi, nous disons que par défaut, aucun fait n’est écrit, sauf certains spécifiés. C’est pour cette raison que nous ne retrouvons en sortie que les faits Erreur de date, Erreur de recontre, Erreur d’élection… Par la suite, étant donné que nous obtenons des informations utiles, mais pas très lisibles, il faut passer par une étape de transcription de l’erreur brute vers une erreur plus compréhensible pour le personne/le bot qui se chargera de modifier la page par la suite.
Nous avons choisi pour l’instant d’écrire directement dans la page InferenceBot - Output. Cependant, après la discussion du mardi 2 mai, utiliser la page discussions pourrait aussi être une bonne idée, étant donné que notre bot serait plus utile si il avertissait directement les personnes concernées, plutôt que de les obliger à venir voir la page contenant toutes les erreurs du wiki, afin de voir s'ils ont des problèmes dans leurs pages.
Exemple d’Output
Comme nous pouvons le voir, pour la page InferenceBot page test - Secundinus Aurelianus, contenant ceci :
- 1234.12.11 / Rome. Naissance de Secundinus Aurelianus.
- 1200.04.20 / Pompei. Election de Secundinus Aurelianus.
- 1000.10.10 / Rome. Rencontre de Secundinus Aurelianus avec Pompilius Iuvenalis.
- 1000.10.10 / Naples. Position de Secundinus Aurelianus.
- 1000.12.12 / Naples. Mort de Secundinus Aurelianus.
Nous avons directement pu obtenir les informations suivantes sur la page InferenceBot - Output :
- Erreur de date : Secundinus Aurelianus né en 1234.12.11 - 0:0:0 et mort en 1000.12.12 - 0:0:0
- Erreur de date : Secundinus Aurelianus né en 1234.12.12 - 0:0:0 et mort en 1000.12.12 - 0:0:0
- Erreur de rencontre : Secundinus Aurelianus et Pompilius Iuvenalis se sont rencontrés à Rome et à Naples en même temps à la date 1000.10.10 - 0:0:0
- Erreur de rencontre : Secundinus Aurelianus et Varius Maxentius se sont rencontrés à Rome et à Naples en même temps à la date 1000.10.10 - 0:0:0
- Erreur d'election : Secundinus Aurelianus (1234.12.11 - 0:0:0 / 1000.12.12 - 0:0:0) est élu en 1200.4.20 - 0:0:0 à Pompei
- Erreur d'election : Secundinus Aurelianus (1234.12.12 - 0:0:0 / 1000.12.12 - 0:0:0) est élu en 1200.4.20 - 0:0:0 à Pompei
Ainsi, le bot d’inférence a pu en déduire plusieurs erreurs, comme deux erreurs de naissance (qui devraient se dérouler avant la mort, pas comme ici); deux erreurs de rencontre, où deux personnes se sont rencontrées en même temps à deux endroits différents; ainsi que deux erreurs d’élection, où la date d’élection est antérieur à la naissance et postérieur au décès.
Evaluation des performances
Actuellement, les règles du bot d’inférence se focalisent principalement sur des erreurs de contenu (incohérences dans les dates ou des lieux p.ex.). Sachant que les pages pertinentes du wikipast (donc pas celles crées par des attaques de bots) ont été créées méticuleusement par un étudiant, il est rare qu’elle contiennent de telles erreurs. C’est pourquoi le bot n’output pas beaucoup d’erreurs autres que celles provoquées par des pages de test. Cependant, nous pensons qu’il est utile d’avoir un tel bot lorsque le nombre de pages augmente et lorsque des utilisateurs et bots commencent à modifier les pages des autres utilisateurs. En effet, il est beaucoup plus facile de faire des erreurs en modifiant des pages d’autres utilisateurs.
Le nombres d’erreurs détectées dépend aussi du nombre de règles implémentées. Comme indiqué dans la description du bot, il est facile d’ajouter des règles grâce à la modularité de son implémentation. La principale limite de performance sur un grand wiki est donc le nombre de règles que le responsable du bot peut trouver.
Concernant le temps nécessaire à l’inférence des faits/erreurs par le bot, il faut savoir que la puissance et le nombre de connexions de l’ordinateur/serveur utilisé sont des facteurs importants. Le bot, lorsqu’il est exécuté sur un ordinateur portable, prend actuellement quelques dizaines de secondes pour scraper tout le Wikipast et inférer les faits/erreurs. Nous avons implémenté l’utilisation de multiples connexions (réglable simplement) pour scraper plus rapidement, car il s’agit de la partie la plus longue de l’exécution. L’inférence des faits/erreurs est quasi-instantanée, mais cela pourrait changer si le nombre de règles augmentent beaucoup.
Conflit avec le bot TangoBot. Les outputs de notre bot se ressemblent à la date ou au lieu près s'il s'agit de plusieurs erreurs de la même catégorie. TangoBot ne nous laisse qu'un output par catégorie de règle (mariage, élection, ...).