lundi 5 décembre 2016

SNCF, ça me Bot !

Cet article décrit le fonctionnement d’un bot perso développé sur Facebook Messenger avec les données de l’API SNCF, et disponible ici. Comme tous les articles de ce blog, il ne s’agit pas d’un travail de spécialiste mais d’un partage des connaissances acquises lors de la réalisation de cet outil.
Précisons également qu'il s'agit d'un "Work in Progress", il a donc probablement évolué depuis votre dernière visite si vous l'avez déjà testé, et continuera peut être dans les jours, mois ou années à venir, bien qu'il n'ait aucune vocation commerciale.

I) C’est quoi un bot ?


1) Les bots

Dans ce contexte, bot est le diminutif de robot. Il s’agit donc d’un programme qui agit comme un robot, c’est à dire de manière (plus ou moins) autonome pour réaliser des actions pour lesquelles on l’a programmé (ou pas, lorsque les machines auront pris le pouvoir).


2) L’apport de l’intelligence artificielle

Les bots ont connu un vrai boom ces derniers mois, portés par l’ouverture au public de plusieurs interfaces les rendant relativement simples d’accès (Messenger ou Slack notamment), et par le boom encore plus spectaculaire de l’intelligence artificielle. Ce dernier est lui-même porté par la puissance de plus en plus importante des processeurs de nos ordinateurs, et la redécouverte récente du concept des réseaux de neurones.
Récemment, plusieurs moteurs d’intelligence artificiels ont été rendus accessibles par les géants du net (TensorFlow de Google, Amazon Machine Learning, Microsoft CNTK …).
Tous ces outils facilitent la mise en oeuvre des techniques d’intelligence artificielle en s’appuyant sur les milliards de données déjà digérées par ces géants. En les ouvrant au public, ces entreprises ne font pas (uniquement) acte de philantropie, mais cherchent à développer les usages et à accumuler toujours plus de données pour enrichir leurs capacités.
Wit.ai, racheté par Facebook en 2015, utilise les mêmes techniques, et est spécialisé dans l’analyse du language.


II) Et ça fait quoi ?


Voici les fonctionnalités actuellement disponibles :

1) Départs d’une gare


a) Horaires & Retards


En entrant simplement le nom d’une gare, on obtient la liste des 5 prochains départs depuis cette gare.
En complément, on obtient avant cela la liste de tous les trains en retard au départ de cette gare dans l’heure précédente, avec la cause de leur retard (lorsqu’elle existe).


b) Projection dans le temps


Le même résultat peut être obtenu à une date et/ou une heure différente de l’instant présent.


c) Envoi de sa position


Le tableau des départs peut également être obtenu pour la gare la plus proche de notre position actuelle en envoyant cette position sur Messenger (uniquement accessible sur mobile)

Envoi de sa position


Malheureusement, l’API publique SNCF ne fournit pas aujourd’hui les numéros des voies de départ des trains, elles ne figurent donc pas dans les résultats du bot :(

3) Itinéraire


En entrant cette fois 2 gares, on obtient le premier itinéraire permettant de rejoindre ces 2 gares à partir de maintenant.
On obtient également la liste des retards de la dernière heure dans chacune des gares d’arrêt intermédiaires sur le trajet.



III) Pourquoi ?


Ce bot n’a strictement rien de révolutionnaire, et reste limité et faillible. Mais il répond à quelques besoins qui, s’ils n’ont rien d’universels, sont au moins personnels :


1) Essayer de comprendre les situations perturbées


Les retards qui sont fournis par l’API SNCF incluent une cause. En l’affichant avec les départs ou tout au long de l’itinéraire, chacun est ainsi susceptible d’anticiper un retard prévisible, ou au moins de comprendre pourquoi “ça roule mal”, et essayer d’en déduire un délai de reprise quand il n’est pas annoncé.
D’ailleurs, il y a certainement quelque chose à faire en analysant ce flot de données pour réellement prédire les retards, un peu comme ça (http://motherboard.vice.com/read/the-math-that-can-predict-transit-delays-two-hours-into-the-future), mais c’est un tout autre projet...

2) Pouvoir avoir les horaires de train quand on capte mal


En effet, grâce à l’appli Messenger, il n’est pas nécessaire d’avoir du réseau en continu pour avoir une réponse. Il suffit d’accrocher du réseau suffisamment longtemps pour que notre question puisse partir, puis ensuite que la réponse puisse arriver, quel que soit le nombre de coupures qui puissent arriver dans l'intervalle. Plus pratique que l’appli SNCF qui nécessite aujourd’hui le réseau pour pouvoir ne serait-ce que rentrer le nom d’une gare (ce qui a cependant l’intérêt de régler les problèmes 4 et 5 évoqués en dernière partie).

3) Gagner du temps


Envoyer sa position sur Facebook Messenger prend à peine quelques secondes, et il suffit ensuite d’en attendre quelques autres (où l’on peut faire autre chose) pour avoir l’information sur l’état du trafic dans la gare la plus proche de chez soi. Certes, l’appli SNCF offre déjà cette possibilité, mais avec quelques temps de chargement parfois pénibles.

IV) Comment ça marche ?


1) L’API SNCF


L’ensemble des données fournies par le bot repose sur l’API SNCF (https://data.sncf.com/api). Et qu’est ce qu’une API ? Il s’agit d’une Interface de Programmation Applicative, c’est à dire une façade avec un mode d’emploi qui explique précisément ce dont elle est capable, et sous quelle forme seront obtenus les résultats.
Exemple simplifié : pour obtenir les horaires entre deux villes, on accèdera par exemple à la page suivante : https://api.sncf.com/itineraire?de=Paris&a=Lyon, qui nous renverra les résultats sous un format bien particulier qui permet d’être ensuite facilement réutilisé. [Ce lien ne fonctionne pas, car il faut d’une part s’authentifier pour accéder à l’API (pour éviter le pillage des données notamment par Google, demande à effectuer par mail auprès de SNCF), et d’autre part il est volontairement simplifié pour l’exemple, mais le principe est là].

Un exemple de retour de l'API pour les perturbations

2) WIT.AI


Le coeur du réacteur est ici. C’est cet outil qui va recevoir le texte écrit sur Messenger, et qui va le transformer en données qui seront ensuite envoyées à l’API.

Pour cela, Wit va d’abord détecter l’intention du message, puis ensuite les entités utiles pour accomplir l’intention. Pour notre bot, il y a 3 intentions possibles :
- le bonjour : si on salue le bot, il répondra par un simple message de bienvenue
- le départ : si on cherche à obtenir le tableau des départs depuis une gare. Les entités utiles à la réalisation de l’intention sont donc une gare, et éventuellement une date/heure si on souhaite obtenir ce tableau à une date différente de maintenant.
- l’itinéraire : si on cherche à obtenir l’itinéraire entre deux gares. Les entités sont ici deux gares, ainsi de même qu’une éventuelle date/heure.

Une fois que le bot a compris l’intention, et identifié les entités utiles, il transmet ces éléments à notre code “maison”, qui va ensuite simplement le mettre en forme pour le transmettre à l’API dans le format prescrit.

Les intentions et les entités sont enseignées à Wit en lui montrant autant d’exemples que possible. Certaines entités sont déjà connues par Wit, par exemple une date ou une heure. Wit sait ainsi très bien détecter une date ou une heure dans un message quel qu’il soit.
Pour les gares, nous lui avons donné un certain nombre d’exemples de gares en indiquant que c’était effectivement des gares, de manière à ce qu’il sache ensuite généraliser. En lui disant par exemple que Dijon Ville, Vierzon Ville et Nanterre Ville sont des gares, il y a de bonnes chances qu’il déduise seul que Valence Ville est également une gare.
Bien sûr, il y a des limites à cette méthode car il est très difficile de faire la différence par exemple entre un nom de ville et un nom de gare. Ce n’est pas utile dans notre cas car on n’utilise que des gares, mais cela nécessiterait une attention particulière dans d’autres cas.

De même, la détection des intentions est issue d’un entraînement avec plusieurs exemples factices.

Entrainement du bot. On voit ici la détection de l'intention, ainsi que des 2 gares

Reprenons notre exemple pour illustrer le fonctionnement. Si j’écris dans Messenger : “je voudrais l’itinéraire de Paris à Lyon”, Wit doit détecter l’intention “itinéraire”, et les concepts de gare de Paris et de Lyon. Il les transmet ensuite à notre code maison, qui va alors les mettre en forme pour lire le contenu de la page https://api.sncf.com/itineraire?de=Paris&a=Lyon.

Une des richesses de cet outil est qu'il apprend en permanence. Ainsi, tous les messages qu'il reçoit sont enregistrés, et peuvent être corrigé pour améliorer les résultats.

Un exemple d'erreur : Brdx n'a pas été détecté comme une gare. On peut corriger cette erreur manuellement pour éviter qu'elle ne se reproduise par la suite.


V) Ca marche pas !


Il est très facile de mettre le bot en échec. Voici quelques exemples et explications.

1) Lui dire des choses qui n’ont rien à voir avec sa fonction première


Le bot comprend ce qu’on lui a dit de comprendre. Et dans notre cas, il s’agit des gares. Il va donc systématiquement essayer de détecter des gares dans les phrases qu’on lui donne.
Comme on l’a vu plus haut, il connait aussi le concept de “bonjour” (pas très bien d’ailleurs, car il n’a pas eu beaucoup d’entraînement).
Mais rien d’autre. Si on lui parle d’autre chose, il va donc toujours essayer de se raccrocher à ces 2 éléments, ce qui peut parfois donner des résultats inattendus.


2) L’ambiguité


Le meilleur exemple : Paris Lyon. Est-ce qu’on cherche les horaires au départ de la gare de Paris Lyon, ou l’itinéraire pour aller de Paris à Lyon ? L’intelligence artificielle n’est ici d’aucune aide, sans contexte on ne peut pas faire mieux que tirer à pile ou face. Et en l’occurence, le bot a été entraîné pour supposer que c’était un itinéraire.

3) C’est long


Oui, la réponse est un peu longue à arriver. Ce délai n’est pas du tout lié à Wit, mais purement à l’analyse des retours de l’API sur les retards. En effet, l’API est ainsi faite qu’il est impossible de filtrer les retards autrement que dans le temps. Ainsi, en cherchant les retards de la dernière heure, il est impossible d’indiquer qu’on ne souhaite les retards qu’à une seule gare. On obtient donc systématique la liste de tous les trains en retard de la dernière heure partout en France. Alors, non, cette liste n’est pas si longue que ça (n’oublions pas que plus de 90% des trains sont à l’heure en moyenne ;) ), mais tout de même, son analyse prend un petit peu de temps. L’optimisation de cette analyse fait partie des pistes de développement possibles par la suite.

4) Villes à plusieurs gares


Exemple : Paris. Lorsqu’on cherche un itinéraire Paris – Ailleurs, le bot ne va pas essayer de deviner la gare de Paris la plus adaptée (ce qui n’est d’ailleurs pas forcément simple et, sauf erreur, pas fourni par l’API). Le bot ne va donc ici que “recracher” le résultat de l’API, c’est à dire la première gare qui sort quand on l’interroge sur Paris (en l’occurence, Paris Nord).


5) Pas la bonne gare


Il peut arriver que le bot renvoit le tableau des horaires d’une autre gare que celle qu’on souhaitait. Le problème vient de l’ordre dans lequel l’API SNCF renvoit les résultats lorsqu’on l’interroge. Etant donné que le code “Maison” choisit systématiquement le premier résultat de la liste, cela peut être surprenant.
Ce point pourrait être amélioré en proposant d’autres choix de gares lorsque le doute est possible.

6) Pas de réponse


Parfois, Wit n’arrive pas à détecter correctement les intentions ou les concepts, ou se trompe. Par exemple, lorsqu’on lui dit “Mer”, il détecte une date et ne fait rien, alors qu’il peut aussi s’agir de la gare de Mer.

Il peut aussi arriver que le bot “désaprenne”, c’est à dire réponde mal alors qu’il répondait bien la fois précédente. Cela fait partie des caractéristiques de l’intelligence artificielle : même en lui apprenant que Mer est une gare, il peut très bien se tromper et prendre Mer pour une date, car d’autres exemples d’apprentissage l’auront conduit à cette conclusion. La réponse n’est pas codée “en dur”, le système tente une réponse sur la base de l’ensemble de ses connaissances précédentes et peut donc se tromper, de manière très similaire … à l’humain !


Ce bot est donc assez loin de la perfection, mais il a au moins 2 intérêts personnels complémentaires à ceux exposés en partie III :
- Tester l’utilisation de Facebook Messenger et les capacités de son moteur d’intelligence artificielle. Beaucoup de bots se sont déjà aventurés sur ce terrain, y compris au sein du groupe SNCF (on peut citer Ouibus, ou Voyages-sncf.com qui est particulièrement efficace (https://www.facebook.com/VbotMessenger/), et pas uniquement basé sur des boutons).
- Explorer les possibilités de l’API SNCF


Le code peut être mis à disposition sur simple demande, et n’hésitez pas à réagir pour améliorer l’article, ou le bot !

TESTER