23 septembre 2017

En quoi les assistants vocaux sont-ils intelligents?

Avec l'emploi de ces assistants vocaux (Amazon Echo, Google Home, etc.), voire de Chatbots, on peut se demander où se trouve la plus value de l'intelligence artificielle dans ces solutions. Quel que soit l'intonation de la voix, si une expression orale est traduite en texte et que celui-ci (mot pour mot) soit associé à une action, il n'y a pas réellement de notion d'intelligence artificielle dans ce modèle. Quand on étudie les concepts détaillés des architectures de ces solutions (semblables entre celles des deux leaders) et que l'on cherche à réaliser ses propres agents conversationnels, on comprend mieux comment tout cela fonctionne et comment la notion d'intelligence artificielle rentre en jeu. En effet, il est fréquent que l'enceinte vous réponde ceci, quand on ne demande pas exactement quelque chose que Google Home veut entendre ou peut comprendre, du style: “Je suis désolé, mais je n’ai pas compris.” ou encore “J’apprends chaque jour.”. A vrai dire, en cas d'échec, c'est-à-dire de la non compréhension d'une phrase fournie, la réponse retournée est aléatoire parmi plusieurs préenregistrées.


Pour une phrase ou un mot donné, une intention est définie dans le codage du service. Pour les mots de cette phrase, des synonymes sont naturellement possibles, voire une construction différente de la phrase. Ces derniers ne sont pas tous initialement définis dans le codage de l'intention. Chaque phrase fournie à l'enceinte ne correspondant pas exactement à l'intention définie. Selon la configuration de l'agent via la console API.AI pour Google Home, elles peuvent être analysées par une service d'intelligence artificielle (en streaming ou background?). Bien que les détails de ces algorithmes de Machine Learning (de classification et/ou de régression) ne sont pas encore connus, les fonctionnalités affichées pour la réalisation d'un agent personnalisé sont les suivantes:

L'apprentissage via le service est la fonction qui permet à l'agent réalisé de comprendre les interactions avec l'utilisateur en tant que langage naturel et de les convertir en données structurées. Dans la terminologie de Google Assistant, l'agent utilise des algorithmes d'apprentissage de Machine Learning (algorithmes probablement de type classification) pour faire correspondre les requêtes utilisateur à des intentions spécifiques et utilise des entités pour en extraire les données pertinentes.


Un agent apprend à la fois des exemples que l'on fournit dans la section Intents (ex: visibles dans la console API.AI, en cas de l'utilisation de l'interface Web UI) et les modèles de langue développés par Google Assistant et API.AI. Sur la base de ces données, il construit un modèle (algorithme) pour prendre des décisions sur lesquelles, l'intention doit être déclenchée par une entrée d'utilisateur et quelles données doivent être extraites. Cet algorithme est propre à chaque agent.


L'algorithme s'ajuste dynamiquement en fonction des modifications effectuées sur l'agent via la plate-forme API.AI. Pour s'assurer que l'algorithme s'améliore, l'agent doit toujours être mis à jour en fonction des éléments fournis par le service de Machine Learning (fonctionnalité d'apprentissage, en utilisant des exemples) qui lui même s'appuie sur les données entrantes disponibles, soit les journaux de conversation réels. L'algorithme de Machine Learning propre à chaque agent enrichit dynamiquement les données (intentions et entités) de configuration associées à l'agent par le biais de l'API du service API.AI pour Google Home, voire par le biais de la constitution d'un fichier ZIP contenant données de configuration et du code relatif au Webhook pour Amazon Echo. Dans ce dernier cas, la plate-forme AWS permet les montées de version logicielle en toute transparence sans interruption de service.

J'ai réalisé mon premier agent (en français) pour Google Home, mais je n'ai pu le valider opérationnellement, car Google Actions de Google Assistants via son simulateur ne prend pas en compte actuellement la langue de Molière. Ceci est prévu pour la fin de l'année. J'ai pu toutefois valider chaque bout de l'application créée avec la configuration de l'agent via la console API.AI, le Webhook (en Nodejs) exécuté via Google Functions et relatif à la partie fonctionnelle de l'application avec un jeu de données (au format JSON) sous Firebase et son appel et retour via HTTP. Le jeu de données correspond à une citation personnelle sur 365 jours.


Le code du Webhook pour cet agent est donné dans le tableau ci-dessous. Le nom donné à l'agent est "pamphlet", car le mot "citation" (plus approprié par rapport à mon jeu de données) est déjà retenu et compris de l'enceinte.

'use strict';

const https = require('https');
const host = 'firebasestorage.googleapis.com';
const path = '/v0/b/citations-51de5.appspot.com/o/citations.json?alt=media&token=928a0fce-216b-4070-8fd4-aa079d0a44e1';

exports.pamphlet = (req, res) => {
  // ... "parameters": { "date": "2017-09-13" },
 let date = req.body.result.parameters['date'];

 var now = new Date(date);
 var start = new Date(now.getFullYear(), 0, 0);
 var diff = now - start;
 var oneDay = 1000 * 60 * 60 * 24;
 var day = Math.floor(diff / oneDay);
 // console.log('Day of year: ' + day);

 // call citations service
 pamphlet(day).then((output) => {
   // return the results of the citation function to API.AI
   res.setHeader('Content-Type', 'application/json');
   res.send(JSON.stringify({ 'speech': output, 'displayText': output }));
 }).catch((error) => {
   // if there is an error let the user know
   res.setHeader('Content-Type', 'application/json');
   res.send(JSON.stringify({ 'speech': error, 'displayText': error }));
 });
};

function pamphlet (day) {
 return new Promise((resolve, reject) => {
   https.get({host: host, path: path, day: day}, (res) => {
     let body = ''; // var to store the response chunks
     let rec = day;
     res.on('data', (d) => { body += d; }); // store each response chunk
     res.on('end', () => {
       // after all the data has been received parse the JSON for desired data
       // console.log(body);
       let response = JSON.parse(body).citations[rec];
       let index = response['id'];
       let citation = response['citation'];
       let author = response['auteur'];

       // create response
       if (index == 1)
         var output = `La citation du ${index}er jour de l'année est la suivante: ${citation} ${author}`;
       else
         var output = `La citation du ${index}ème jour de l'année est la suivante: ${citation} ${author}`;

       // resolve the promise with the output text
       console.log(output);
       resolve(output);
     });
     res.on('error', (error) => {
       reject(error);
     });
   });
 });
}

La validation de la publication du Webhook sur Google Functions a été effectuée et qualifiée dans la foulée, comme le montre les informations du tableau ci-dessous.

$ pwd <CR>
/home/patrick/Private/src/languages/nodejs/pamphlet
$ gcloud beta functions deploy pamphlet--stage-bucket pamphlet-18092017 \
 --trigger-http --region=us-central1 <CR>
Copying file:///tmp/tmpBDBZ9c/fun.zip [Content-Type=application/zip]...
- [1 files][  1.1 KiB/  1.1 KiB]                                                
Operation completed over 1 objects/1.1 KiB.                                      
Deploying function (may take a while - up to 2 minutes)...done.                                                                                                         
availableMemoryMb: 256
entryPoint: pamphlet
httpsTrigger:
 url: https://us-central1-strong-market-179414.cloudfunctions.net/pamphlet
latestOperation: operations/c3Ryb25nLW1hcmtldC0xNzk0MTQvdXMtY2VudHJhbDEvcHJvdmVyYi9PcHBGcVlqTmxodw
name: projects/strong-market-179414/locations/us-central1/functions/pamphlet
serviceAccount: strong-market-179414@appspot.gserviceaccount.com
sourceArchiveUrl: gs://pamphlet-18092017/us-central1-proverb-dolvsyiduris.zip
status: READY
timeout: 60s
updateTime: '2017-09-18T12:09:53Z'
versionId: '2'

# afin de qualifier le Webhook, un fichier JSON est créé avec le paramètre (date) adéquate issu de
# de la console API.AI
$ cat ../data.json <CR>
{
 "id": "879b15a9-b782-4902-a199-2036e2c0eb2d",
 "timestamp": "2017-09-18T11:49:18.045Z",
 "lang": "fr",
 "result": {
   "source": "agent",
   "resolvedQuery": "hier",
   "action": "",
   "actionIncomplete": false,
   "parameters": {
     "date": "2017-09-18"
   },
   "contexts": [],
   "metadata": {
     "intentId": "d8a27c2c-4e4a-4174-94a3-a89115a2ed5d",
     "webhookUsed": "false",
     "webhookForSlotFillingUsed": "false",
     "intentName": "Donne-moi le pamphlet du jour ?"
   },
   "fulfillment": {
     "speech": "",
     "messages": [
       {
         "type": 0,
         "speech": ""
       }
     ]
   },
   "score": 1
 },
 "status": {
   "code": 200,
   "errorType": "success"
 },
 "sessionId": "40b922b6-0285-4dad-83c4-a9ae6163a0a2"
}

# Sollicitation du Webhook
$ curl -H "Content-Type: application/json" \
--data "@../data.json" https://us-central1-strong-market-179414.cloudfunctions.net/pamphlet <CR>
{"speech":"La citation du 262ème jour de l'année est la suivante: La paresse est utile à cause de l'effort qu'elle demande pour être surmontée. Citation de Tristan Bernard.","displayText":"La citation du 262ème jour de l'année est la suivante: La paresse est utile à cause de l'effort qu'elle demande pour être surmontée. Citation de Tristan Bernard."}
$

Pour en revenir à la notion d'intelligence artificielle, pour obtenir une bonne précision de classification, il est important de fournir à son agent suffisamment de données. Ceci est bien connu dans le monde du Big Data, un mauvais algorithme avec beaucoup de données est plus pertinent qu'un bon algorithme avec peu de données. Plus le nombre d'exemples en langage naturel est grand dans la section "User Says of Intents" de la console API.AI, meilleure est la précision de la classification. La console offre des fonctions qui permettent de s'entraîner et d'améliorer l'apprentissage.

Aucun commentaire:

Enregistrer un commentaire