en / nl / sk / be

AI bij Davinci: automatisch gegevens uit documenten halen met Machine Learning

23 JULI 2019 - Bij Davinci hebben we machine learning algoritmes getraind om belangrijke gegevens automatisch te extraheren uit zakelijke documenten zoals salarisstroken, koopovereenkomsten en identiteitskaarten. Tot nu toe wordt dit extractieproces meestal gedaan met handmatig geschreven regels (erg tijdrovend) of zelfs met de hand (nog tijdrovender). Het machine learning-systeem bouwt een statistisch model op van wat voor soort informatie het verwacht, door een groot aantal voorbeelden te analyseren. Het systeem doet dit zonder enige menselijke tussenkomst. Het kan dit model vervolgens gebruiken om de gewenste informatie uit nieuwe documenten te extraheren. We zullen in dit artikel interactieve visualisaties gebruiken om uit te leggen hoe dit werkt.

Stel je voor dat je een loonstrookje hebt waaruit je informatie moet halen, zoals de naam en geboortedatum van de werknemer, wie de werkgever is en hoeveel geld iemand verdient, wat vervolgens opgeslagen wordt in een database. En stel je nu voor dat er ook een identiteitskaart, een bankafschrift en een werkgeversverklaring is, die allemaal informatie bevatten die je moet ophalen en opslaan. En niet een, maar honderden, elke dag.

Een eerste aanpak om dit probleem aan te pakken zou het handmatig schrijven van een aantal regels kunnen zijn, zoals: 'als je de achternaam nodig hebt, zoek naar de woorden: “achternaam” en neem dan de onderstaande woorden', of ' als je het cumulatieve salaris nodig hebt, zoek dan een cijfer na een € en neem je vervolgens het hoogste getal '. Maar het probleem hierbij is dat deze type documenten in een oneindig aantal verschillende lay-outs komen: soms staat de achternaam links van de woorden "werknemersnaam" in plaats van onder "achternaam" en soms heeft het cumulatieve salaris helemaal geen €. Bovendien verandert de structuur van deze documenten in de loop van de tijd: een regel waaraan we vandaag veel handmatig werk besteden, kan volgende maand zinloos zijn. Hoewel je kunt proberen om al deze obstakels met nog meer regels op te lossen (zoals we al jaren doen), begint dat wel erg veel op een tantaluskwelling te lijken; je probeert de regels tot in de eeuwigheid te verbeteren, altijd het gevoel te hebben dat je er bijna bent, maar nooit dat doel bereikt van 100% van alle belangrijke gegevens die correct zijn geëxtraheerd. Met de recente opkomst van zeer succesvolle machine learning algoritmes, hebben we daarom geëxperimenteerd met een nieuwe benadering waarbij we alleen het machine learning-algoritme een groot aantal voorbeelddocumenten tonen waarin mensen de belangrijke informatie hebben gemarkeerd. De taak van de algoritmes is dan om erachter te komen hoe het dezelfde informatie in ongeziene documenten volledig automatisch kan extraheren. Er zijn veel verschillende machine learning-algoritmes en manieren om deze te gebruiken. Na verschillende experimenten hebben we een systeem gekozen dat twee methodes combineert: het herkennen van inhoud and het herkennen van positie.

Methode 1: inhoud herkennen

De eerste benadering, en misschien de meest voor de hand liggende, classificeert elk item (= woord, nummer, datum, etc.) op een document op basis van zijn karakters. Tijdens de trainingsfase hebben we het algoritme voorzien van honderden voorbeelden van items van het type waarin we geïnteresseerd zijn en enkele duizenden voorbeelden van andere items. Dit is een klein deel van de input die wordt gebruikt om het systeem te leren om geboortedata te herkennen:
Birthdate? 1 2 3 4 5 6 7 8 9 10
y 1 5 / 0 2 / 1 9 8 6
y 3 0 - 0 3 - 1 9 5 8
y 2 5 0 5 1 9 8 9
y 0 8 1 2 1 9 7 6
y 0 4 . 1 0 . 1 9 6 3
n 1 . 4 8 5 , 6 0
n f u l l t i m e
n d a t u m
n s a l a r i s s p e
n l o o n h e f f i n
De taak van het machine learning-algoritme is om te reproduceren of er 'y' of 'n' in de eerste kolom zou moeten zijn, gebaseerd op de andere kolommen. Om dit te doen, zal systeem het moeten uitzoeken welke karakters op welke positie goede indicatoren van geboortedata zijn. Het systeem kan bijvoorbeeld leren dat als u '19' of '20' op positie 7 en 8 vindt, het zeer waarschijnlijk is dat je naar een datum kijkt. Het best presterende algoritme voor deze taak bleek k Nearest Neighbours(kNN) te zijn. Terwijl je de eerste paragraaf aan het lezen was werd er in je browser een statistisch model van geboortedata opgebouwd, dus je kan nu met de resultaten spelen. Het percentage geeft aan hoe zeker het algoritme is dat de tekst in het tekstvak een geboortedatum is.

kNN birthday recognizer

0%
Examples
Merk wel op dat dit systeem geen eenvoudige datumherkenner is, maar echt is afgestemd op geboortedata: 01-02-1999 is bijvoorbeeld prima mogelijk als datum, maar het is geen zeer waarschijnlijke geboortedatum voor een medewerker (althans niet in onze dataset), dus krijgt het een lage score. Dit maakt het mogelijk om geboortedata te scheiden van andere datums op documenten, zoals de huidige datum en de startdatum van het dienstverband. Dit is duidelijk te zien als we de betrouwbaarheidswaarden bekijken voor alle items in een aantal voorbeelddocumenten in de interactieve visualisatie hieronder. Naast het k Nearest Neighbours-algoritme kun je ook de resultaten van twee andere algoritmes zien.
0%
100%
Example document
Algorithm

Betrouwbaarheidswaarden van de algoritmen voor het herkennen van geboortedata op salarisstroken, waarbij alleen de letters, cijfers en punctatie in het item zelf worden gebruikt. Helderdere kleuren betekenen dat het algoritme zekerder is van zijn zaak.

In de meeste gevallen heeft kNN het meeste vertrouwen in het juiste antwoord, terwijl de Multilayer Perceptron (een neuraal netwerk) ook triggert op meer dingen die getallen bevatten. Interessant is dat bij de data die zowel een geboortedatum als een werknemer-startdatum kunnen zijn, alle algoritmes fouten gaan maken. Een paar voorbeelden van false positives en false negativesvan dit systeem zijn 12-06-1995, 22/02/1991, 12 JAN 1997 en 05 09 1988. Dit zijn allemaal data die zowel geboortedata kunnen zijn voor jonge werknemers als startdatavoor iets oudere trouwe medewerkers. Om deze te scheiden, moesten we een tweede methode gebruiken die kijkt naar de posities en relaties tussen items in plaats van enkel naar hun inhoud.

Methode 2: positie herkennen

Onze tweede benadering is om nuttige labels in een document te identificeren en er omheen te kijken. Dit is waarschijnlijk ook hoe mensen het doen: als je wilt weten welke datum op een salarisstrook de geboortedatum is, is het waarschijnlijk handiger om het label 'geboortedatum' te zoeken en de datum ernaast te gebruiken (in plaats van eerst het hele document te scannen voor geboortedata). Voor deze aanpak hebben we een manier nodig om automatisch uit te zoeken welke labels nuttig zijn. We hebben een systeem gekozen dat in vier richtingen rond het item van belang kijkt; dit zijn enkele voorbeelden van wat je vindt als je kijkt rond geboortedata:
Direction Found labels
Top geb.   geb.   geboortedatum   geboortedatum   170454319   bijz.tarief   geb.datum   geb.datum
Left geboortedatum   geboortedatum   geboortedatum   geboortedatum   geboortedatum   geb.datum   geboorte-datum   geboorte-datum   geboortedatum:   geboortedatum:
Bottom dienst   dienst   dienst   dienst   dienst   dienst   dienst   ongehuwd   ongehuwd   ongehuwd
Right ln   ln   ln   dagen   dagen   recht   recht   recht   stam   stam
Je kunt zien dat er woorden in deze lijst zitten die duidelijk nuttig zijn (zoals 'geboortedatum' en 'geb.datum'), maar ook woorden die we niet hadden verwacht, zoals het feit dat blijkbaar de woorden 'dienst' en 'ongehuwd' vaak onder de geboortedata staan. Hoewel dit niet iets is wat we doorgaans zouden gebruiken in een handgeschreven regel om geboortedata te identificeren, kan het nog steeds een handige hint zijn voor een machine learning-algoritme. Een ander ding dat ons opviel is dat er veel dubbele items zijn en items die erg op elkaar lijken. Om vergelijkbare items samen te groeperen, hebben we het clusteralgoritme DBScan gebruikt. Dit is een voorbeeld van wat het resultaat van een dergelijke clustering kan zijn, waarbij grotere cirkels items aangeven die vaker voorkomen:
Je ziet dat veel items met vergelijkbare betekenissen gegroepeerd worden, zoals alle manieren om 'geboortedatum' te schrijven. Merk echter op dat het niet vlekkeloos is: de niet-verwante woorden 'recht' en 'geslacht' zijn gegroepeerd omdat hun laatste drie letters identiek zijn. De volgende stap is om te zien of deze gegroepeerde labels kunnen worden gebruikt om de oorspronkelijke entiteit te vinden waarin we geïnteresseerd zijn. We hebben dezelfde set algoritmes getest als met de op inhoud gebaseerde aanpak. Deze keer was het Multilayer Perceptron (een neuraal netwerk) het meest succesvol.
0%
100%
Example document
Algorithm

Betrouwbaarheidswaarden van het algoritme voor het herkennen van geboortedata, waarbij labels worden gebruikt die eerder als mogelijk nuttig zijn aangemerkt. Handige labels worden aangegeven in geel, heldere kleuren betekenen dat het algoritme zekerder is van zijn zaak.

Net als de op inhoud gebaseerde benadering is deze positiegerichte benadering niet perfect. Een veelgemaakte fout is dat het vaak niet weet of het links of onder een label moet lijken (zoals in document 4 en 5), wat natuurlijk logisch is, omdat met alleen informatie over posities het algoritme onmogelijk kan hebben geweten dat het item onder 'geboortedatum' niets lijkt op een geboortedatum.

Combinatie van de twee benaderingen

Samenvattend maakt de op inhoud gebaseerde benadering fouten die kunnen worden opgelost door naar de labels eromheen te kijken, en de positie gebaseerde benadering maakt fouten die kunnen worden opgelost door naar de inhoud te kijken. Een logische volgende stap is om beide benaderingen te combineren. Dit is minder triviaal dan het klinkt: een betrouwbaarheidsscore van 0,9 kan normaal zijn voor één algoritme en echt hoog voor een ander. Uiteindelijk hebben we ons gebaseerd op een op classificatie gebaseerde normalisatie die 98% van de keren de juiste entiteit lijkt terug te geven. Resterende fouten zijn meestal te wijten aan (1) ongebruikelijke documentlay-outs die slechts één keer voorkomen in de dataset en (2) fouten in beeld-> tekst (OCR) die al tijdens de voorbewerking zijn geïntroduceerd. Een belangrijke resterende uitdaging waaraan we momenteel werken, is dat deze combinatie van benaderingen niet voor elk entiteitstype zal werken. Rekeningnummers op salarisstroken zijn bijvoorbeeld vaak niet voorzien van een label, terwijl de functiebeschrijving geen duidelijk herkenbare inhoud heeft.

What's next

Naast de uitdaging die hierboven is uitgelegd, werken we er momenteel aan om dit systeem in de cloud te laten draaien (met behulp van Amazon Sagemaker). Hier zal het parallel lopen aan ons bestaande regelgebaseerd systeem, dus we kunnen testen hoe het presteert op realtime productiegegevens in de cloud. Een interessant voordeel van deze gegevens is dat deze handmatig worden gecorrigeerd door mensen en dat deze voortdurend worden bijgewerkt met duizenden nieuwe documenten, elke dag opnieuw. Dit betekent dat we door regelmatig bijtrainen ervoor kunnen zorgen dat het systeem automatisch up-to-date blijft, zowel wat betreft het uiterlijk van de documenten als wat onze klanten verwachten. Op deze manier zijn we weer een stap dichter bij ons ultieme einddoel: een systeem waarbij onze klanten handmatig een nieuw stukje informatie kunnen labelen waarin ze geïnteresseerd zijn en ons AI-systeem langzaam het werk overneemt. Neem voor meer informatie contact op met Wessel Stoop. Interesse om bij ons te komen werken? Bekijk onze openstaande vacatures.