Chatbot

Kunstmatige Intelligentie/Neurale netwerken/Chatbot

Creative Commons License
This work is licensed under a
Creative Commons Attribution-NonCommercial-ShareAlike 4.0
International License
.
Deze praktische opdracht, die 2 a 3 lesuren van 50 minuten in beslag neemt, is bedoeld om de je nog meer gevoel te laten krijgen voor de mogelijkheden van een neuraal netwerk. In de opdrachten Tensorflow en Eigen Quickdraw hebben we een neurale netwerken gebruikt om afbeeldingen te kunnen classificeren. In deze opdracht ga je een chatbot toepassing bekijken. In een chatbot is meer interactie tussen de gebruiker en de agent. De gebruiker en de agent voeren samen een gesprek. Een chatbot kan heel specifiek zijn, b.v. een chatbot voor een klantenservice, of heel algemeen, b.v. een chatbot die het beste presteert in een Turing test die we in we in de sectie Wanneer is iets intelligent hebben behandeld. De top 30 lijst van chatbots in 2022 beschrijft niet alleen waarom sommige chatbots beter zijn dan anderen, maar geeft ook verwijzingen naar de vele mislukkingen. Voorbeelden uit deze lijst zijn:
Opdracht
Bezoek de bovenstaande websites en probeer in beide chatbots zowel een gezellige en een aankoop gerelateerde conversatie op te zetten. Welke chat geeft jouw de meeste voldoening? Voor welk publiek zou jij Kuki zinvol vinden?

In het vervolg van deze opdracht probeer je voor een eigen onderwerp (bedrijf, organisatie of iets anders), zo volledig mogelijk een verzameling vraag/antwoord of meer algemeen uiting/antwoord combinaties te maken. De opdracht maakt gebruik van de Natural Language Processing library nlp.js (https://github.com/axa-group/nlp.js) die is verwerkt in de chatbot hiernaast. Deze chatbot gaan jullie gebruiken voor jullie vraag antwoord applicatie. We hopen dat je plezier aan deze opdracht gaat beleven.

Opdracht
Vul in de chatbot in het grijze van naast “Enter” de volgende uitingen in en druk dan op Enter:
  1. Waar is mijn pakje?
  2. Hoe laat komt mijn pakket?
  3. Kan ik jullie opbellen?
  4. Ik wl iets trug sturen
  5. Ik wil een baan
  6. Is mijn pakje te klein
Tevreden over de antwoorden? Waarschijnlijk bij 3 van de zes vragen niet, maar bij vraag 4 zie je dat er bij taalfouten toch nog een zinvol antwoord terugkomt.

De chatbot is getraind met maar een heel beperkt aantal uiting/antwoord combinaties. Klap het onderstaande blok open om te zien hoe beperkt deze lijst is. We vertellen je in dit blok ook wat de verschillende onderdelen betekenen en hoe je je eigen vragen kunt invoeren in de chatbot.

De trainingsdata en uitleg:
De trainingsdata voor de chatbot is geplaatst in een JSON object. Het JSON object dat standaard wordt ingeladen is:
    {
      "name": "Bol.com",
      "locale": "nl",
      "data": [
        {
          "intent": "agent.waarispakketje",
          "utterances": [
            "Waar is mijn pakketje?",
            "Waar is mijn pakketje",
            "Komt mijn pakketje nog?",
            "Wacht op mijn pakketje"
          ],
          "answers": [
            "Als je inlogt, kan ik zien welke bestelling je bedoelt. Wil je inloggen op je bol.com account?",
            "Zou je willen inloggen, dan kan ik zien welk pakketje je bedoelt"
          ]
        },
        {
          "intent": "agent.retourneren",
          "utterances": [
            "Ik wil iets retourneren",
            "Ik wil iets terugsturen",
            "Ik wil iets terug sturen"
          ],
          "answers": [
            "Artikelen terugsturen is bijna altijd mogelijk. Als je inlogt, kijk ik graag met je mee. Wil je inloggen op je bol.com account?",
            "Zou je willen inloggen, dan kunnen we samen verder kijken hoe je je pakketje terug kunt sturen"
          ]
        }
      ]
    }
		
Als je nog niets van JSON objecten weet kun je dit blok uitklappen voor een heel korte introductie.
JSON is de afkorting van “JavaScript Object Notation”. Een JSON object bestaat uit een set accolades met daarin definities van eigenschappen met hun waarde gescheiden door een komma:
        {
        	"eigenschap1": ,
        	"eigenschap2": ,
        	"eigenschap3": 
        }
				
De waarde van een eigenschap kan een “tekst” zijn, een getal of een genest JSON object:
        {
        	"Naam": "Jayson",
        	"Lengte": 178,
        	"adres": {
        			"straat": "Vrijheidslaan",
        			"huisnummer": "2022z",
        			"plaats": "Vredeburg",
        			"land": "Utopia"
        		}
        }
				
Maar dat niet alleen, een waarde kan ook een rij (array) zijn. Een array bevat elementen tussen twee vierkante haken [,,,] In een array kunnen dan weer bovenstaande waarden zitten of ook weer andere rijen:
        {
        	"Naam": "Jayson",
        	"hobbies": [ "voetbal", "breien", "drummen" ],
        	"cijfers": [
        				{	"wiskunde": [6.4, 7.8, 5.9, 7.6] },
        				{	"informatica": [8.3, 8.7, 9.1, 5.4, 6.6, 8.1] },
        				{ "frans": [9.4, 9.8, 7.9, 8.6 ] }
        			]		
        }
				
In het JSON object voor de chatbot zijn er de volgende onderdelen:
  • name: De naam van de organisatie
  • locale: De taal waarin de conversatie plaat vindt.
  • data: Een lijst (array) van JSON objecten voor uiting/antwoord combinaties voor een bepaald doel. Hierin staat intent voor doel en heeft altijd de vorm “agent.beschrijvingdoel”, utterances voor een lijst van uitingen van de gebruiker die bij dit doel passen en answers voor een lijst met antwoorden die bij de uitingen kunnen worden getoond?
Zelf aan de slag: Kopieer de code hierboven naar je favoriete code editor. Verander de naam van de organisatie en voeg enkele nieuwe doelen toe en sla het bestand op als een document met extensie .json. Volg in de bovenstaande chatbot app de instructie in het het veld met de tekst “Sleep hier je JSON ...”. Zodra het document is geladen wordt de chatbot opnieuw getraind.


Eindopdracht Nu jullie in de uitleg hebben gezien hoe je uiting/antwoord combinaties kunt definiëren en deze in de chatbot app kunt invoeren, kunnen jullie de klas opsplitsen in groepjes en voor een bepaald doel (b.v. klachten afhandeling van een winkel, communicatie over storingen openbaar vervoer, reserveren corona testen, ...) een chatbot maken. Een chatbot als Kuki is natuurlijk onmogelijk om samen te stellen, daar is verschrikkelijk veel data voor nodig. Geef elkaar een heel lesuur voor het opstellen van het JSON document. Vervolgens geven jullie elkaar de ontwikkelde JSON documenten en het doel van de chatbot en test je elkaars chatbot op de zinvolheid van de gegeven antwoorden voor het specifieke doel van de chatbot. Geef individueel iedere chatbot een cijfer van 1 t/m 10 en geef je lijst aan je docent. Die maakt dan aan het einde een ranglijst van jullie scores.

Opsporen fouten

In je browser kun je controleren of het laden van de training data goed is gegaan door op F12 te drukken en Console te selecteren. Als het training bestand zonder problemen geladen is zie je een succesvolle melding van een training. Anders krijg je een foutmeldingen.


Verdieping

Wil je je na de eerste kennismaking met het ontwikkelen van een chatbot meer verdiepen in de achterliggende techniek, dan kun je de code van de chatbot, aanwezig in het bestand ChatBot.zip, doorgronden en eventueel aanpassen op de verschillende mogelijkheden die de Natural Language Processing library nlp.js (https://github.com/axa-group/nlp.js) te bieden heeft. Je kunt je ook verdiepen door de top 30 lijst van chatbots in 2022 te bestuderen met als doel het verschil tussen succes en mislukking te ontdekken.

Om de chatbot uit te breiden qua functionaliteiten kan je kijken naar de code in het bestand js/bot.js. Dit is de code die verantwoordelijk is voor de reactie van de bot. De functie die wordt aangeroepen is this.getReply(message) in de class const Bot. Momenteel wordt de NLP aangeroepen om een antwoord te genereren, maar dit kan je natuurlijk ook iets anders laten doen. Of je kan ook extra analyse uitvoeren op het inkomende bericht message.

Let op: de functie getReply(message) geeft een Promise terug. Dit is een belofte om later (wanneer de code klaar is) een antwoord te geven. De NLP geeft automatisch een Promise terug, maar als je de code verandert, dan kan het zijn dat je bijvoorbeeld een gewone string mee wilt geven. Indien je dit wilt doen, moet je het verpakken in een Promise. Dit doe je als volgt:

return await new Promise(function(resolve, reject) {
            resolve({ answer: "Antwoord" });
        });

Bij het creëren van de class Bot in het bestand client.js wordt de functie init() aangeroepen in Bot. In deze functie vindt initialisatie plaats.