Nieuws, updates en meer

Hoe ontwikkel je een taalmodel op basis van machine learning – stap 1

Ook in 2021 stond het weer op de lijstjes: een van de grote trends in finance is (nog steeds) het geautomatiseerd boekhouden. Met behulp van slimme algoritmes op basis van machine learning (in combinatie met Robotic Process Automation) is het mogelijk om boekingen geautomatiseerd te laten plaatsvinden.

Dat klinkt simpel, maar is het niet (daarom staat het al jaren op de lijstjes). In een serie artikelen nemen we je stap voor stap mee in wat er bij de ontwikkeling van zo’n algoritme komt kijken. Over Robotic Process Automation (RPA) gaan we het een andere keer hebben.

Woord vooraf

Maar voordat we ingaan op de praktische kant van het ontwikkelen van een machine learning algoritme is het het goed om even stil te staan bij twee vragen.

De eerste vraag is: leuk dat het een trend is, maar waarom zou je dit moeten willen? De tweede vraag: is het zinvol om dit zelf te doen, of kan ik dit beter uitbesteden?

Het ontwikkelen van een goed machine learning model is – zeker als het om taal gaat – zo complex en arbeidsintensief dat je zonder een goed antwoord op deze vragen, jezelf beter alle tijd en moeite kunt besparen.

Wat is je visie en waar liggen je ambities?

Administratief werk is extreem nuttig en vormt in onze optiek de basis voor een goed werkende organisatie. Het heeft alleen twee belangrijke nadelen: een goede administratie voeren is arbeidsintensief en zeer foutgevoelig.

In onze visie kun je de inzet van je administratief personeel veel beter gebruiken voor het controleren van de juistheid van gegevens, dan voor de invoer van gegevens zelf. De tijd die je bespaart als gevolg van het geautomatiseerd invoeren, kunnen je administratief medewerkers vervolgens – naast het controleren op juistheid - gebruiken voor het meer en meer vervullen van een rol als ‘business partner’.

De vraag is hoe ambitieus je daarin bent. Er zijn inmiddels steeds meer organisaties die pdf-facturen automatisch laten inscannen en verwerken. Hoewel dat een zeer goede ontwikkeling is, is het automatisch inscannen en daarmee invoeren van dingen als bedrag, factuurdatum, ordernummer, et cetera iets anders dan een algoritme inhoudelijk laten snappen wat er staat.

Als je dat kunt, kun je binnenkomende facturen bijvoorbeeld ook automatisch (op inhoud) aan de juiste grootboekrekening koppelen. Snapt je model de inhoud, dan worden meer complexe toepassingen mogelijk. Bijvoorbeeld binnen welke WKR-categorie valt de factuur, klopt het in rekening gebrachte BTW-percentage, moeten de kosten geactiveerd worden of niet, et cetera.

Denk vooraf goed na over wat je met je Machine Learning algoritme wil bereiken. Dat helpt je niet alleen in de afbakening van wat je gaat doen (een belangrijke valkuil is dat je op korte termijn te veel wilt), maar het helpt je ook in het verantwoorden van het budget en/of de personele inzet die je nodig hebt voor de ontwikkeling van je algoritme.

Ook wij bij wijcontrolerenjedata.nl zijn druk bezig. Ons grote plaatje is dat we boekingsteksten op basis van een Machine Learning taalmodel automatisch inhoudelijk willen kunnen snappen. Als we dat kunnen, kunnen we daar heel veel mooie data-analyses mee maken.

Als we de volgende boekingstekst analyseren: “reiskosten jan-mei 2018 (dhr P. M. Jansen Bsc)”, dan willen we dat ons algoritme snapt dat het om reiskosten gaat, in de periode januari tot en met mei 2018, gemaakt door een specifieke (en voor dit voorbeeld verzonnen) medewerker.

Dat zou relatief eenvoudig zijn als alle boekingsteksten dezelfde structuur zouden hebben. In dit voorbeeld: eerst het onderwerp, dan de periode en dan de persoon (in het format aanhef, voorletters, achternaam, titel). Omdat boekingsteksten er nooit hetzelfde uitzien en er in de praktijk honderd verschillende manieren zijn om dezelfde boeking op een andere manier op te schrijven hebben we hier een zelflerend algoritme voor nodig in plaats van een algoritme op basis van zogenaamde business rules (vooraf gedefinieerde, statische regels).

Waarom kun je een machine learning model beter samen ontwikkelen?

Heb je – net als wij - voor jezelf scherp wat je wil gaan doen en waarom? Dan is het tijd voor de volgende vraag. Wie gaat het doen? Doe je de ontwikkeling zelf? Ga je het uitbesteden? Wordt het een co-creatie-project of koop je iets dat kant en klaar is?

We realiseren ons dat wat we nu gaan zeggen niet heel objectief overkomt. Maar toch...Doe. Het. Niet. Alleen. De eerste reden is dat er in de ontwikkeling van dit soort algoritmes heel erg veel voorwerk gaat zitten. We gebruiken voor ons algoritme bijvoorbeeld een lijst met meer dan honderdduizend voor- en achternamen (N.B. geen klantgegevens). Die gegevens verzamelen, ontdubbelen, opschonen en labelen kost enorm veel tijd. Die investering kunnen wij uitsmeren over een groot aantal klanten. Daarmee zijn we altijd goedkoper, dan wanneer je een dergelijk complex algoritme zelf gaat ontwikkelen.

Het tweede nadeel van zelf ontwikkelen is dat er in je eigen datasets – die je later gebruikt voor het trainen van je algoritme – veel meer ‘bias’ zit. Als er in jouw organisatie relatief vaak op een bepaalde manier wordt geboekt, dan zal je algoritme minder goed om kunnen gaan met afwijkingen (die er in de praktijk altijd zijn). Voor de ontwikkeling van onze WKR-controle (die – in overleg met onze klanten – gebaseerd is op de data van vier grote organisaties) zagen we dat één organisatie heel consequent aan het boeken was. Dat het consequent fout was, viel pas op in de vergelijking met de data van de overige organisaties.

Opknippen in kleine stukjes

Terug naar ons algoritme. Op korte termijn is het ondoenlijk om ons algoritme de volledige inhoud van een boekingstekst te laten snappen. Hoe voer je je baby een pompoen? Door hem in kleine stukjes te hakken, kapot te koken en te pureren (de pompoen, niet je baby). Zo is het ook met taalmodellen.

We beginnen er daarom mee om ons algoritme te laten snappen wanneer er een naam in een boekingstekst staat. Als dat goed werkt, laten we het model een datum herkennen. Dan een plaatsnaam. Enzovoorts. De truc is om je algoritme in zodanige stukjes op te knippen, dat ieder stukje op zichzelf bruikbaar is. Op die manier kun je tussentijds bruikbare resultaten laten zien. Dat zorgt voor blijvend draagvlak voor je project.

Als ons algoritme teksten kan opsporen waar een persoonsnaam in staat, kan dat een AVG-toepassing hebben (snel duidelijkheid welke gegevens gedeeld mogen worden op basis van de privacy-wetgeving), maar het kan ook een eerste indicatie zijn dat het om een declaratie gaat.

Hoe kom je aan de datasets voor je algoritme?

Zoals gezegd zijn we voor ons algoritme gestart met het herkennen van namen. Daar hadden we een aantal dingen voor nodig. Het meest voor de hand liggende was een lijst met heel veel namen. Maar hoe kom je daaraan? Ben je een grote organisatie? Gebruik dan in ieder geval de namen uit je eigen administratie. Ben je geen grote organisatie? Dan zijn er alternatieven. Er zijn verschillende open source initiatieven waarbij mensen proberen zo volledig mogelijke namenlijsten samen te stellen. Een andere optie is dat je dat je bepaalde websites met veel namen gaat ‘crawlen’ (met andere woorden, je bouwt een robotje dat heel veel pagina’s van een of meerdere websites bezoekt en de gegevens op die pagina’s opslaat in een database).

Omgaan met dubbele betekenis

Naast een dataset met namen hebben we nog twee andere datasets gebruikt. De eerste was een lijst met alle woorden uit het Nederlands woordenboek. De tweede was een lijst met alle gemeentes en plaatsnamen in Nederland. De reden dat we in dit stadium ook die lijsten nodig hadden is omdat het herkennen van een mogelijke naam niet voldoende is. Je wil dat het algoritme iets kan zeggen over de kans dat een woord feitelijk een naam is. Neem bijvoorbeeld het woord ‘Amsterdam’. Het kan een achternaam zijn, maar het kan ook een plaatsnaam zijn. Net zoals het woord ‘Molenaar’ een achternaam kan zijn, maar ook een zelfstandig naamwoord. Woorden die wel op de namenlijst staan, maar geen plaatsnaam zijn en niet in het woordenboek voorkomen hebben – los van de context – een grotere kans een naam te zijn, dan woorden die bijvoorbeeld ook een betekenis hebben als plaatsnaam.

Hoe label je een dataset voor je algoritme?

In een ideale wereld moet je voor je algoritme op twee niveau’s data gaan labelen: op woord-niveau en op context-niveau. Voor het eerste niveau heb je – in ons voorbeeld – je namenlijst nodig. Onze namenlijst bestond uit verschillende bronnen. Om te beginnen hebben we de feitelijke namen afgesplitst van de voorvoegsels. Dus bijvoorbeeld “Van Ommen” hebben we uitgesplitst in “Van” en “Ommen”. Dat heeft een paar redenen. De eerste is dat we de voorvoegsels in ons algoritme apart willen kunnen onderscheiden. Dat is omdat we zo veel meer combinaties kunnen maken dan in onze namenlijst staat. “Hoff” kan zo “Van ‘t Hoff” worden, “Van Hoff”, “Van der Hoff” et cetera. De tweede reden is dat we een naam willen kunnen vergelijken met onze lijst met plaatsnamen en onze lijst met het woordenboek. Je wil voorkomen dat “Van Ommen” door het voorvoegsel niet als mogelijke plaatsnaam wordt gezien.

Na de uitsplitsing van de voorvoegsels en de feitelijke namen hebben we onze lijst ontdubbeld. Namen met onleesbare of foute karakters hebben we vervolgens verwijderd en tot slot hebben we de namenlijst gelabeld door in verschillende kolommen kruisjes te zetten. Is het voornaam? Is het een achternaam (of allebei)? Is het een plaatsnaam? Komt het voor in het woordenboek en zo ja, wat voor type woord is het? Is het een onwaarschijnlijke naam? Komt de naam voor in de lijst met meest voorkomende voor- of achternamen? Al deze informatie gaat het algoritme helpen om met meer of minder waarschijnlijkheid te bepalen of een woord een naam is.

Het tweede niveau waarop je in deze fase data moet gaan labelen is op context-niveau. Het woord “Amsterdam” heeft in de boekingstekst “12-02-2020 treinreis Amsterdam – Utrecht” een hele andere betekenis dan in de boekingstekst “12-02-2020 declaratie treinreis dhr. J. van Amsterdam”. Dit leer je je algoritme door (heel veel) boekingsteksten woord voor woord te gaan labelen. “12-02-2020 treinreis Amsterdam – Utrecht” wordt dan “12-02-2020 [date] treinreis [travel] Amsterdam [city] – [interpunction] Utrecht [city]”. Heb je zowel op context-niveau als op woord-niveau data gelabeld, dan is het tijd voor de volgende stap: het ontwikkelen van het algoritme zelf.

Maar daarover vertellen we je in een volgend artikel. Laten we eerlijk zijn: voorlopig ben je toch nog druk met data labelen...;-)

Welkom bij
WijControlerenJedata.nl

Voordat je verder gaat, vragen we je akkoord te gaan met onze Algemene voorwaarden en onze Cookies.

Ik ga niet akkoord Ik ga akkoord

Controleren javascript ondersteuning

Voor een optimale gebruikerservaring, maakt deze website intensief gebruik van javascript.

Als deze tekst niet snel wordt vervangen, ondersteunt uw browser GEEN javascript. Schakel javascript in uw browser in of gebruik een andere browser.