Van bak met data naar een werkende lawyerbot #ndalynnweek

Weet je wat het idiootste is aan AI? Dat iedereen het maar over algoritmes heeft en hoe spannend of bedrijfsgeheim die zijn. Het labelen van je data, dát is waar de kwaliteit van je systeem mee staat of valt. Ik vind het dan ook erg raar dat je overal leest dat men een blik studenten opentrekt of via diensten als Mechanical Turk willekeurige mensen labels laat zetten. Of dat wij via reCaptcha en dergelijke diensten zeggen waar zebrapaden lopen of verkeerslichten te zien zijn. Data is de kern van je dienst, dus hoezo besteed je dat uit en pronk je vervolgens met je unieke algoritmes die uiteindelijk niet ter zake doen?

Natuurlijk, studenten inzetten is goedkoop maar waar vind je de rechtenstudent die in honderd NDA’s zinnen kan herkennen als zijnde overmacht, verlenging, aansprakelijkheid met boete enzovoorts? In een rechtenopleiding krijg je welgeteld nul contracten te lezen (ja, serieus) laat staan een specifiek document als een NDA.

Dus nee, er zit niets anders op dan het zelf te doen. Gelukkig vind ik het perfecte moment om dit te doen: mijn dochter van een paar maanden oud slaapt ’s nachts beter als ik in de kamer zit, dus ik leg mijn laptop klaar en ga labelen tot ze slaapt. Zo kom ik in een paar maanden tot een volgens mij keurig gelabelde dataset. Een paar steekproeven op de resultaten laat zien dat ik redelijk consistent label, ook al heb ik geen formele criteria opgesteld om clausules te categoriseren.

Dat is ergens ook wel een beetje de makke van zo’n systeem. Er zijn geen echte categorieën waar je op terug kunt vallen, je moet zelf maar iets bedenken. Zowel het soort clausule (is een vrijwaring een vorm van aansprakelijkheid of iets heel anders) als de smaakjes daarbinnen (is een ton aansprakelijkheid erger dan een boete van 10k per gelekt geheim). Dus ik doe maar wat. Bij elke zin bedenk ik een categorie, en na driehonderd zinnen ga ik categorieën samenvoegen en splitsen.

Hier, de tagger waarmee ik al die tijd heb gewerkt om zinnen van labeltjes te voorzien. Je ziet hoe het aantal categorieën is geëxplodeerd:

En de clauser, waarmee ik groepen zinnen (clausules dus) van een smaakje kon voorzien:

Dan heb je dus een berg zinnen en bijbehorende clausules, en daarmee kun je BigML gaan trainen. Dat had nog heel wat voeten in de aarde. Het eerste datasetje deed het goed, het voelt echt héél gaaf als je dan een test doet:

galactus@toad:~> php tagtest.php
input text: "Recipient shall use the same level of security as it uses for its own sensitive information to protect the Confidential Information against unauthorized use or disclosure, but at least a reaasonable level of security."
..... bigml says: security / standard
galactus@toad:~> 
En dat klopte helemaal. Maar er zaten genoeg fouten in. In het jargon: de F1-score was maar 0,64 en dat is niet genoeg om een commerciële dienst op te drijven. Terug naar de tekentafel dus, of beter gezegd de datatafel.

Allereerst viel me op dat ik toch wel wat foutjes had gemaakt. Dit haal je uit de confusion matrix, waarbij je kunt zien welke uitvoer op welke foute manier gelabeld wordt. Dan zie je bijvoorbeeld dat ‘parties’ clausules vaak als security clausules worden aangemerkt, zodat je specifiek daar extra voorbeelden van toe kunt voegen en foutcorrectie kunt doorvoeren.

Ook ontdekte ik dat ik de nodige categorieën had die ik zelf eigenlijk niet snapte. Overlap tussen categorieën maakt dat ML systemen slecht performen. Snoeien dus, en zorgen dat je per categorie duidelijk kunt aangeven wat erin hoort. Toch het nadeel van in halfslaap taggen wellicht?

De ingewikkeldste ingreep had te maken met dit soort clausules:

Recipient shall (a) treat all Confidential Information with the highest care; (b) only permit persons having a clear need to know access; (c) evaluate the Confidential Information at its own risk; (d) comply with relevant export regulations; (e) indemnify and hold harmless Discloser from any damages in connection with usage of the Confidential Information; and (f) waive its right to a jury trial.

Welke categorie plak je hier nu weer op? Het artikel regelt van alles, van security eisen tot wie het mag zien tot aansprakelijkheid en iets met juryrechtspraak. Daar kun je dus helemaal niets mee. Dat moest worden opgesplitst. Een hele vieze reguliere expressie (dit gaat een thema worden in het verhaal) splitste zo’n clausule in meerdere tegelijk, waarbij elke één van die zes bullet items bevatte.

En wat ook nog eens leuk bleek te werken, was bij elke zin mee te geven op welke plek hij in het document stond. Een zin over Florida aan het begin van een NDA gaat meestal over waar een partij gevestigd is. Staat hij aan het einde, dan is het waarschijnlijk de rechtskeuze. Dus kreeg elke zin als extra veld mee waar hij in het document stond. En hoe lang hij was (in woorden) want dat blijkt ook uit te maken. Grof gezegd, hoe langer een zin hoe strenger de bepaling. Soms is juridisch werk heel makkelijk.

Stiekem ook nog wat reguliere expressies bij de kwalificatie van clausules. Want sommige dingen zijn inschattingen (is dit streng of juist niet), anderen zijn gewoon simpel lezen. Een rechtskeuze voor Florida is geen inschatting, dat zie je gewoon letterlijk staan. Dus als je weet dat een clausule over rechtskeuze gaat (dat zegt de 1st stage classifier) dan kijk je gewoon welk land je ziet staan in die clausule en dat zal de rechtskeuze dan wel zijn.

Idem voor duur van het contract. Een AI heeft héél veel moeite met lezen of er staat dat een contract drie jaar duurt. Maar een reguliere expressie vindt hem zo. Deze oplossing is wat lomp, maar computers zijn snel en krachtig genoeg en het scheelt ontzéttend veel in de uitvoer. Mag ik zeggen, de regexp is de ducttape van de artificial intelligence?

Als laatste truc voegde ik vlaggetjes toe. Een machine learning systeem kijkt in principe naar losse woorden, maar juist in juridische teksten gebruikt men vaak vaste uitdrukkingen (“reasonable security measures”, “confidential information”, “receiving party”) en die moet je dus niet opsplitsen. De vlaggetjes werden toegevoegd met wéér een setje reguliere expressies, en dat gaf alles bij elkaar een hele mooie verbetering: een F1 van 0,86. Genoeg om de markt mee op te durven.

(Dit is de tweede van vijf vakantieberichten.)

Arnoud

2 reacties

  1. Leuk dit! Regexp als ducttape voor (overigens nogal risicovolle) datapreparatie lijkt me wel kloppen. Wat wel in me opkomt is de vraag hoe vaak je eigenlijk je onderliggende methode wil updaten naar iets in de buurt van “state of the art”. Juist dat kijken naar individuele woorden is in de NLP “al lang” (met een knipoog, want werkend product vs. reaguurder) losgelaten ten faveure van bag of words en semantische structuren die voor- en achteruit kijken. Veel van de regexp zou je kunnen opvangen door breed getrainde modellen daarna domeinspecifiek te maken (de fastai-aanpak noem ik het maar). Pre-processing van contract, naar artikelen, naar sub-artikelen zal nog heel lang handig blijven.

    Andere gedachte blijft “Hoe schaalt het?”. Uit de M&A-praktijk: bij een deal van € 1 mld. maken die tweemaal veertig uur junior-advocaat per belangrijk contract echt niet uit. Paar ton voor je juridisch adviseur is part of the game en een besparing van 50% daarop niet echt een game changer. Vervang de junioren door het zusje van Lynn en dan heb je weer een team senior juristen en data scientist zitten om na te gaan of het zusje van de materialiteit van de bevindingen goed inschat.

  2. Echt zo tof dat je dit allemaal deelt! Heerlijk prutsen ter leering ende vermaeck en er uiteindelijk nog wat mee verdienen ook. Heel erg volgens de open source gedachte: “je verkoopt geen product, maar uren (kennis)”. Die uren zitten bij AI inderdaad in de dataset en bij jou dus ook in de ducttape. De algoritmes kun je vrijelijk delen met de rest van de wereld. Geweldig! Dankjewel hiervoor.

Geef een reactie

Handige HTML: <a href=""> voor hyperlinks, <blockquote> om te citeren, <UL>/<OL> voor lijsten, en <em> en <strong> voor italics en vet.