<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Parsing &#8211; Smals Research</title>
	<atom:link href="https://www.smalsresearch.be/tag/parsing/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.smalsresearch.be</link>
	<description></description>
	<lastBuildDate>Thu, 09 Apr 2026 12:23:30 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.smalsresearch.be/wp-content/uploads/2026/01/cropped-cropped-Smals_Research-32x32.png</url>
	<title>Parsing &#8211; Smals Research</title>
	<link>https://www.smalsresearch.be</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Natural Language Processing in het Nederlands</title>
		<link>https://www.smalsresearch.be/natural-language-processing-in-het-nederlands/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Wed, 31 Mar 2021 09:23:39 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[automatic translation]]></category>
		<category><![CDATA[big data]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<category><![CDATA[NER]]></category>
		<category><![CDATA[NLP]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Parsing]]></category>
		<guid isPermaLink="false">/?p=15508</guid>

					<description><![CDATA[We lezen dan wel met de regelmaat van de klok over spectaculaire vooruitgang met NLP in het Engels - herinner u GPT-3 - maar over andere, minder courant gesproken talen, horen we weinig. Iemand die NLP probeert toe te passen op het Nederlands, kan dan ook nog een paar obstakels tegenkomen. ]]></description>
										<content:encoded><![CDATA[
<p>We publiceerden eerder al verschillende artikels over de computationele verwerking van taal, in het vakjargon bekend als Natural Language Processing (NLP):</p>



<ul class="wp-block-list"><li><a href="/facetten-van-natural-language-processing-deel-1/">Facetten van Natural Language Processing: deel 1</a> &amp; <a href="/facetten-van-natural-language-processing-deel-2/">deel 2</a></li><li><a href="/nlp-modeles-de-langue/">NLP &amp; Modèles de langue (FR)</a></li><li><a href="/named-entity-recognition-une-application-du-nlp-utile/">Named Entity Recognition: une application pratique du NLP (FR)</a> </li><li><a href="/apis-voor-computervertaling-de-praktijk/">API&#8217;s voor computervertaling</a> &amp; <a href="/apis-voor-computervertaling-de-praktijk/">in de praktijk</a></li></ul>



<p>NLP is een belangrijke component in toepassingen zoals <a href="/chatbot-studentwork-lessons-learned/">chatbots</a> en <a href="/uitdagingen-bij-voicebots/">voicebots</a>. Het kan ook ingezet worden om data te annoteren en bv. een <a href="/les-graphes-de-connaissance-quelques-applications/">knowledge graph</a> te verrijken, wat dan weer beter <a href="/graph-db-vs-rdbms/">kennisbeheer</a> en <a href="/sept-bonnes-raisons-dutiliser-une-graph-database/">-ontsluiting</a> mogelijk maakt.</p>



<p>Het is niet zo moeilijk voor iemand met wat programmeervaardigheden om met NLP te experimenteren. Veel code is open source, en er zijn talloze <a href="https://www.fast.ai/2019/07/08/fastai-nlp/">goede tutorials</a> te vinden, compleet met educatieve <em>notebooks</em> in Jupyter of Google Colab en duidelijke instructievideo&#8217;s. Maar deze beperken zich veelal tot het Engels, of heel af en toe een andere grote wereldtaal. </p>



<p>We lezen dan wel met de regelmaat van de klok over spectaculaire vooruitgang met NLP in het Engels &#8211; herinner u <a href="https://en.wikipedia.org/wiki/GPT-3">GPT-3</a> &#8211; maar over minder courant gesproken talen horen we weinig. Iemand die NLP probeert toe te passen op het Nederlands, komt dan ook plots een paar obstakels tegen. Ook <a href="https://www.standaard.be/cnt/dmf20210319_05008561">De Standaard</a> merkte dit recent op, en wist daarbij te vertellen dat de trainingsdata van GPT-3 voor 92% uit Engelse tekst bestaat en voor 0,35% uit Nederlandse &#8211; toch een stevige grootteorde verschil.</p>



<p>(Noot: de evoluties in het domein van NLP en de beschikbare tools gaan snel; dit artikel is dus accuraat op het moment van schrijven maar de situatie kan volgend jaar al helemaal anders zijn.)</p>



<p><a href="https://spacy.io/">SpaCy</a> is een bekende open-source Python library voor NLP. Ze is gebruiksvriendelijk en abstraheert veel van de onderliggende complexiteit van NLP of de achterliggende Machine Learning frameworks zoals PyTorch of Tensorflow weg. Sinds versie 3.0 ondersteunen ze ook de <em><a href="https://huggingface.co/transformers/index.html">transformer</a></em> deep learning architecturen, die aan de basis liggen van de meest succesvolle recente taalmodellen. We gebruiken deze versie van SpaCy voor al wat volgt. Alternatieven voor SpaCy zijn o.a. <a href="https://stanfordnlp.github.io/stanza/">Stanza </a>en <a href="https://github.com/flairNLP/flair">Flair</a>.</p>



<h2 class="wp-block-heading">Entiteiten herkennen</h2>



<p>Een ingebouwde functionaliteit van hun taalmodellen is Named Entity Recognition (NER), het herkennen van entiteiten in een tekst. In de <a href="https://spacy.io/models/en">documentatie</a> bij elk taalmodel zien we in het <em>label scheme</em> o.a. alle categorieën die het model kan herkennen: DATE, TIME, PERCENT etc., maar ook PERSON (eigennamen), PRODUCT of WORK_OF_ART. Het is gemakkelijk dit zelf uit te proberen op een klein stukje tekst, geïnspireerd op <a href="https://course.spacy.io/en/chapter1">hun tutorial</a>:</p>



<pre class="wp-block-preformatted">import spacy
from spacy import displacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("Apple buys a French company for $1 billion.")
displacy.render(doc, style="ent")</pre>



<figure class="wp-block-image size-large is-style-default"><a href="/wp-content/uploads/2021/03/en_core_web_sm_demo_2.png"><img decoding="async" width="474" height="34" src="/wp-content/uploads/2021/03/en_core_web_sm_demo_2.png" alt="" class="wp-image-15660" srcset="https://www.smalsresearch.be/wp-content/uploads/2021/03/en_core_web_sm_demo_2.png 474w, https://www.smalsresearch.be/wp-content/uploads/2021/03/en_core_web_sm_demo_2-300x22.png 300w" sizes="(max-width: 474px) 100vw, 474px" /></a></figure>



<p>We merken dat <em>Apple</em> wordt herkend als ORG (organisatie), <em>French</em> als NORP (nationaliteit of religieuze/politieke groep) en <em>$1 billion</em> als een geldhoeveelheid. Proberen we echter hetzelfde in het Nederlands:</p>



<pre class="wp-block-preformatted">import spacy
from spacy import displacy
nlp = spacy.load("nl_core_news_sm")
doc = nlp("Apple koopt een Frans bedrijf voor $1 miljard.")
displacy.render(doc, style="ent")</pre>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2021/03/nl_core_news_sm_demo_2.png"><img decoding="async" width="522" height="35" src="/wp-content/uploads/2021/03/nl_core_news_sm_demo_2.png" alt="" class="wp-image-15661" srcset="https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_demo_2.png 522w, https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_demo_2-300x20.png 300w" sizes="(max-width: 522px) 100vw, 522px" /></a></figure>



<p>In het Nederlands wordt <em>Apple</em> plots aanzien als persoon en wordt <em>1</em> aangeduid als simpel telwoord! Eerlijkheid gebiedt ons te zeggen dat de grote versie van het taalmodel dit wel correct annoteert, op het dollarteken na. De kleine taalmodellen die we hier hebben gebruikt illustreren echter wel een belangrijk punt: er is geen garantie dat wat werkt in de ene taal, daarom ook even goed zou werken in een andere taal, ook al lijkt het dat de taalmodellen slechts verschillen qua taalcode. Het repliceren van Engelstalige NLP-succesverhalen in een andere taal, is dus geen kwestie van even snel copy-pasten.</p>



<h2 class="wp-block-heading">Waarom dat verschil?</h2>



<p>Een blik op de onderliggende automatische grammaticale analyse maakt een en ander duidelijk:</p>



<pre class="wp-block-preformatted">displacy.render(list(doc.sents), style="dep")</pre>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2021/03/en_core_web_sm_dependencies.png"><img fetchpriority="high" decoding="async" width="975" height="265" src="/wp-content/uploads/2021/03/en_core_web_sm_dependencies.png" alt="" class="wp-image-15664" srcset="https://www.smalsresearch.be/wp-content/uploads/2021/03/en_core_web_sm_dependencies.png 975w, https://www.smalsresearch.be/wp-content/uploads/2021/03/en_core_web_sm_dependencies-300x82.png 300w, https://www.smalsresearch.be/wp-content/uploads/2021/03/en_core_web_sm_dependencies-768x209.png 768w" sizes="(max-width: 975px) 100vw, 975px" /></a></figure>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2021/03/nl_core_news_sm_dependencies.png"><img loading="lazy" decoding="async" width="975" height="262" src="/wp-content/uploads/2021/03/nl_core_news_sm_dependencies.png" alt="" class="wp-image-15665" srcset="https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_dependencies.png 975w, https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_dependencies-300x81.png 300w, https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_dependencies-768x206.png 768w" sizes="auto, (max-width: 975px) 100vw, 975px" /></a></figure>



<p>De betekenis van alle afkortingen voor woordsoorten en -functies kan je terugvinden op de website van <a href="https://universaldependencies.org/">Universal Dependencies.</a> Wat blijkt:</p>



<ul class="wp-block-list"><li><em>billion</em> wordt aanzien als telwoord, <em>miljard</em> als zelfstandig naamwoord.</li><li><em>$</em> wordt in het Engels als symbool, in het Nederlands als naamwoord geannoteerd.</li><li>In het Engels is <em>&#8220;for $1 billion&#8221;</em> afhankelijk van het werkwoord (een bijwoordelijke bepaling), in het Nederlands wordt <em>&#8220;voor $1 miljard&#8221;</em> als afhankelijk van het naamwoord <em>bedrijf</em> beschouwd.</li><li><em>Apple</em> wordt in beide talen correct aangeduid als eigennaam en onderwerp, dus de grammaticale analyse alleen is niet genoeg om het onderscheid te verklaren.</li></ul>



<p><a href="https://spacy.io/">SpaCy</a>&#8216;s taalmodel voor het Nederlands ziet de zaken dus anders dan dat voor het Engels. De <a href="https://spacy.io/models/nl">documentatie</a> ervan laat zien dat de componenten <em>tagger</em> en <em>parser</em>, die de zinsontleding voor hun rekening nemen, ook heel anders georganiseerd zijn in het Nederlands en veel complexer (of fijnmaziger?) lijken dan die voor het Engels. Ook lezen we elders dat de dataset waarop de grammaticale analyse is getraind, anders is: <a href="https://catalog.ldc.upenn.edu/LDC2013T19">OntoNotes 5</a> voor het Engels, en <a href="https://github.com/UniversalDependencies/UD_Dutch-LassySmall">LassySmall 2.5</a> en <a href="https://github.com/UniversalDependencies/UD_Dutch-Alpino">Alpino</a> uit <a href="https://universaldependencies.org/">Universal Dependencies</a> voor het Nederlands.</p>



<h2 class="wp-block-heading">Lassy, Alpino en OntoNotes</h2>



<p><a href="https://www.let.rug.nl/~vannoord/Lassy/">Lassy</a> heeft haar oorsprong in de academische wereld van de computationeel taalkundigen. Er bestaat een kleine versie en een grote versie: LassyKlein met ongeveer 1 miljoen woorden, is manueel geverifieerd; LassyGroot met ongeveer 700 miljoen woorden, is automatisch geannoteerd met het programma <a href="https://www.let.rug.nl/~vannoord/alp/Alpino/">Alpino</a> . Ze gebruikten een eigen XML-annotatieformaat geïnspireerd op het eerdere project <a href="https://lands.let.ru.nl/cgn/">Corpus Gesproken Nederlands</a>. Dit formaat verschilt nogal van het <a href="https://www.conll.org/">CoNLL</a> formaat dat vaak gebruikt wordt voor opslag van dit soort gegevens, en dat de standaard is voor de <a href="https://universaldependencies.org/">Universal Dependencies</a> datasets. Na omzetting met een <a href="https://rug-compling.github.io/">convertor</a> kon wel een subset van LassyKlein daarin opgenomen worden als <a href="https://universaldependencies.org/">UD_Dutch-LassySmall</a>. Men is daarbij wel heel selectief geweest: enkel een subset uit Wikipedia is bewaard, met daarin <strong>7388</strong> zinnen van in totaal 98163 woorden. </p>



<p>Een andere dataset gebaseerd op voornamelijk nieuwsartikels is ook beschikbaar: <a href="https://github.com/UniversalDependencies/UD_Dutch-Alpino">UD_Dutch-Alpino</a>, met daarin <strong>13578</strong> zinnen met 208601 woorden. Wie enkele van de zinnen leest, merkt dat ze vooral verzameld zijn in de vroege jaren 2000. Onderwerpen die ter sprake komen zijn bijvoorbeeld Brussel-Halle-Vilvoorde, Justine Henin-Hardenne en Wim Kok als premier van Nederland. </p>



<p><a href="https://paperswithcode.com/dataset/ontonotes-5-0">OntoNotes 5.0</a> is het Engelstalige bronmateriaal voor SpaCy&#8217;s grammaticale analyse. Het bevat naar schatting 2 miljoen woorden in <strong>+/- 300000</strong> zinnen uit gevarieerde bronnen: het merendeel uit nieuwsartikels waarvan een deel ook uit vertaalde internationale bronnen, en dan nog een klein deel uit blogs en stukken uit de Bijbel. De dataset kan gezien worden als een opvolger van de <a href="https://catalog.ldc.upenn.edu/docs/LDC95T7/cl93.html">Penn Treebank</a> , een van de eerste grote datasets voor automatische syntactische analyse. Ook OntoNotes is niet in het CoNLL formaat en vereist dus een <a href="https://conll.cemantix.org/2012/data.html">omzetting</a>.</p>



<p>Om een model te kunnen trainen, moet SpaCy de CoNLL-data nog <a href="https://spacy.io/api/cli#convert">converteren</a> in haar eigen interne formaat.</p>



<h2 class="wp-block-heading">Nederlandstalige datasets: werk aan de winkel</h2>



<p>Het valt op dat er zowat 10 keer minder trainingsdata beschikbaar is voor het Nederlands dan voor het Engels. Daarbij komt ook  het uitgebreidere label schema in de woordsoort-tagger, dus minder voorbeelden per label, en een beperkte variatie in het bronmateriaal &#8211; enkel oude nieuws- en Wikipedia-artikelen. Dan is het geen verrassing dat zelfs het <a href="https://spacy.io/models/nl#nl_core_news_lg">beste (ingebouwde) Nederlandse taalmodel</a> in SpaCy qua accuraatheid in detectie van woordsoort (<em>part-of-speech</em> <em>tags</em>, <strong>95%</strong>), zinsstructuur (<em>labeled dependencies</em>, <strong>82%</strong>) en entiteiten (F-score <strong>77%</strong>) achterblijft op hun <a href="https://spacy.io/models/en#en_core_web_sm">slechtste Engelse taalmodel</a> (resp. <strong>97%, 90%, 84%</strong>) &#8211; laat staan dat het in de buurt komt van het <a href="https://spacy.io/models/en#en_core_web_trf">beste Engelse taalmodel</a> (resp. <strong>98%, 94%, 90%</strong>). Dat laatste is weliswaar een gloednieuw <em>transformer</em>-model, en het valt te verwachten dat we dit type binnenkort ook voor het Nederlands zullen mogen verwachten in SpaCy, gezien er al enkele beschikbaar zijn in de <a href="https://huggingface.co/models?filter=nl">transformers model hub</a>.</p>



<p>Wil men de achterstand echt structureel inhalen, dan zal men op een bepaald moment toch werk moeten maken van grotere Nederlandstalige datasets voor het trainen van taalmodellen. Dat vergt veel middelen en tijd, maar misschien kan een gedeeltelijke automatisering met behulp van wat vandaag al bestaat qua automatische annotatie, aangevuld met crowdsourcing voor bv. de validatie, de zaken wat versnellen. In de zijlijn: voor het trainen van <a href="https://en.wikipedia.org/wiki/Word_embedding">word embeddings / vectors</a> hoeft de tekst niet geannoteerd te zijn. Daarvoor bestaan dus, ook in het Nederlands, wel erg grote datasets, o.a. Wikipedia dumps of <a href="https://commoncrawl.org/">Common Crawl</a>. Ook gebeurt er onderzoek naar <a href="https://research.aimultiple.com/few-shot-learning/">few-shot learning</a>, waarvoor slechts enkele geannoteerde voorbeelden voldoende zouden zijn, maar er is nog volop debat over <a href="https://gpt3experiments.substack.com/p/is-gpt-3-really-doing-few-shot-learning">wanneer en onder welke voorwaarden dat wel of niet kan werken</a>. </p>



<p>Ondertussen zijn de bestaande taalmodellen zeker niet nutteloos: we kunnen ze gemakkelijk tweaken voor onze eigen toepassingen.</p>



<h2 class="wp-block-heading">Een taalmodel verbeteren</h2>



<p>Wat kunnen we vandaag al doen om fouten te reduceren? Gelukkig is SpaCy als library modulair opgezet en iedere component van de tekstverwerkingspijplijn is naar believen aan te passen. We zagen dat het Engelse <em>billion</em> wel als getal werd gezien, maar het Nederlandse <em>miljard</em> niet.</p>



<p>Laat ons eerst kijken naar de <a href="https://spacy.io/usage/linguistic-features#language-data">taalspecifieke uitzonderingen</a> die SpaCy definieert. Daarin zien we dat in de <a href="https://github.com/explosion/spaCy/blob/master/spacy/lang/nl/lex_attrs.py">lexicale attributen</a> het woord miljard wel degelijk als getal wordt aangemerkt, <a href="https://github.com/explosion/spaCy/blob/master/spacy/lang/en/lex_attrs.py">net zoals in het Engels</a>. Alleen samengestelde getallen (&#8220;drieëntwintig&#8221;) worden op moment van schrijven nog niet zo geannoteerd in het Nederlands &#8211; hiermee hebben we al direct een eerste plek gevonden waar ruimte voor verbetering is qua analyse van het Nederlands in SpaCy! </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2021/03/spacy-pipeline.png"><img loading="lazy" decoding="async" width="1024" height="173" src="/wp-content/uploads/2021/03/spacy-pipeline-1024x173.png" alt="The SpaCy NLP pipeline." class="wp-image-15730" srcset="https://www.smalsresearch.be/wp-content/uploads/2021/03/spacy-pipeline-1024x173.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2021/03/spacy-pipeline-300x51.png 300w, https://www.smalsresearch.be/wp-content/uploads/2021/03/spacy-pipeline-768x130.png 768w, https://www.smalsresearch.be/wp-content/uploads/2021/03/spacy-pipeline.png 1155w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption>De SpaCy NLP pipeline. De Morphologizer is een Tagger component.</figcaption></figure>



<p>De woordsoorten worden toegekend door een <em>Morphologizer </em>in de pijplijn, dit is een component die getraind is en waarvan de uitkomst dus afhangt van de trainingsdata. En inderdaad , als we de inhoud van <a href="https://github.com/UniversalDependencies/UD_Dutch-LassySmall">UD_Dutch-LassySmall </a>en <a href="https://github.com/UniversalDependencies/UD_Dutch-Alpino">UD_Dutch-Alpino</a> erop nalezen, zijn woorden zoals <em>miljoen</em> en <em>miljard</em> er enkele keren in terug te vinden, consistent geannoteerd als NOUN.</p>



<p>Je kan desgewenst een eigen versie van de trainingsdata maken waarin dat anders is en proberen een geheel nieuwe Morphologizer component te trainen. Voor een kleine aanpassing zoals dit is een elegant alternatief ook om een op maat gemaakte component toe te voegen aan de pijplijn, die de automatische annotatie door zo&#8217;n standaard taalmodel aanpast of aanvult waar nodig of gewenst. In dit geval kunnen we een zelfgeschreven <em>AttributeRuler </em>invoegen achter de Morphologizer, die de woordsoort aanpast van  NOUN naar NUM voor NOUNs waarbij &#8220;<em>token.like_num == True</em>&#8220;:</p>



<pre class="wp-block-preformatted">ruler = nlp.add_pipe("attribute_ruler", name="fix_num", after="morphologizer")
detect = [[{"POS": "NOUN", "LIKE_NUM": True}]]  
assign = {"POS": "NUM"}  
ruler.add(patterns=detect, attrs=assign)</pre>



<figure class="wp-block-image size-large is-resized"><a href="/wp-content/uploads/2021/03/nl_core_news_sm_numfixed.png"><img loading="lazy" decoding="async" src="/wp-content/uploads/2021/03/nl_core_news_sm_numfixed.png" alt="" class="wp-image-15686" width="580" height="38" srcset="https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_numfixed.png 856w, https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_numfixed-300x20.png 300w, https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_numfixed-768x51.png 768w" sizes="auto, (max-width: 580px) 100vw, 580px" /></a></figure>



<h2 class="wp-block-heading">NER updaten</h2>



<p>De Named Entity Recognition component, die het nodig vond om <em>Apple</em> een persoon te noemen, is ook een aparte component in de pijplijn die we kunnen aan- of uitschakelen, bijtrainen of desgewenst in zijn geheel vervangen. Het is niet mogelijk om een lijstje van patronen te maken waarmee alle mogelijke bedrijfsnamen herkend zouden kunnen worden, dus trainen op voorbeelden is hier onvermijdelijk. De NER-component kan hier blijkbaar enkele voorbeeldzinnen over bedrijfsacquisities gebruiken, om te leren dat niet enkel personen iets kunnen kopen.</p>



<p>SpaCy heeft sinds kort een hele <a href="https://spacy.io/usage/projects">projectarchitectuur</a> uitgebracht die het beheer en het uitvoeren van trainingsprojecten voor taalmodellen sterk vereenvoudigt. We hoeven maar een van de <a href="https://github.com/explosion/projects">templateprojecten</a> te klonen en aan te passen aan onze noden:</p>



<pre class="wp-block-preformatted">python -m spacy project clone pipelines/ner_demo_update</pre>



<p>Dit commando downloadt een kant-en-klaar project dat out-of-the-box werkt. In het bestand <em>project.yml</em> maken we de nodige aanpassingen aan de configuratie: de taal en het basismodel wijzigen naar het Nederlands, eventueel kan ook de GPU ingeschakeld worden, etc. Het <em>project.yml</em> bestand werkt zoals een <a href="https://en.wikipedia.org/wiki/Makefile">Makefile</a>: het definieert verschillende commando&#8217;s voor de voorbereiding van het data, het samenstellen van de trainingsconfiguratie, het uitvoeren van de training, het exporteren en packagen van het resulterende model en het schoonmaken van de bestandsstructuur. Je kan daar zelf naar believen onderdelen aan toevoegen. Er zijn ook mogelijkheden om het resultaat te visualiseren of via een API te publiceren, middels <a href="https://github.com/explosion/projects/tree/v3/integrations">integraties</a> met libraries zoals <a href="https://streamlit.io/">streamlit</a>, <a href="https://fastapi.tiangolo.com/">FastAPI</a>, <a href="https://wandb.ai/site">weights&amp;biases</a> en <a href="https://ray.io/">ray</a>.</p>



<p>Dan moeten we enkel nog trainingsdata in de map <em>assets</em>  zetten. Er zijn allerlei tools beschikbaar om tekst of andere data te annoteren: die van <a href="https://universaldependencies.org/tools.html">UD</a> zelf, <a href="https://labelbox.com/">LabelBox</a>, <a href="https://doccano.github.io/doccano/">Doccano</a>, &#8230; maar buiten SpaCy&#8217;s eigen <a href="https://prodi.gy/">Prodigy</a> bieden weinigen directe ondersteuning voor SpaCy. Het kan nog nodig zijn om een eigen script te maken om data te converteren naar een ondersteund formaat, en dat is met een extra lijntje code in <em>project.yml</em> snel ingevoegd. Gelukkig is het formaat gebruikt in het demoproject relatief eenvoudig en kunnen we snel manueel een JSON-file schrijven. We nemen bijvoorbeeld enkele titels van recente artikels op <a href="https://tweakers.net/">Tweakers.net</a>:</p>



<pre class="wp-block-preformatted">[
["OnePlus 9 Pro met nieuwe Sony-sensor verschijnt eind maart voor 899 euro.", {"entities":[[0,7,"ORG"],[25,29,"ORG"],[64,72,"MONEY"]]}],
["Gerucht: Discord voert gesprekken met Microsoft over mogelijke overname.",{"entities":[[9,16,"ORG"],[38,47,"ORG"]]}],
...
]</pre>



<p>Om te illustreren dat de context bepalend is om een woord als een bepaalde entiteit te markeren, vermeldt geen enkele van de voorbeeldzinnen die we gebruikten <em>Apple</em>. Eens alle onderdelen van het project zijn gedefinieerd, is de trainingsupdate met één commando uit te voeren en het resultaat al even snel te visualiseren: </p>



<pre class="wp-block-preformatted">spacy project run all
spacy project run visualize-model</pre>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2021/03/nl_core_news_sm_retrained.png"><img loading="lazy" decoding="async" width="620" height="85" src="/wp-content/uploads/2021/03/nl_core_news_sm_retrained.png" alt="" class="wp-image-15689" srcset="https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_retrained.png 620w, https://www.smalsresearch.be/wp-content/uploads/2021/03/nl_core_news_sm_retrained-300x41.png 300w" sizes="auto, (max-width: 620px) 100vw, 620px" /></a></figure>



<p>Dit geeft dus een gemengd beeld. Het goede nieuws is dat <em>Apple</em> nu wel wordt herkend als een bedrijf. Het systeem lijkt ook extra aandacht te hebben voor cijfers gevolgd door woorden, die in commerciële context wel eens een geldbedrag zouden kunnen zijn. Maar plots worden ook mensen en nationaliteiten aanzien als organisaties &#8211; en dat was vroeger niet zo. Wat is hier gebeurd? </p>



<p>Het fenomeen staat bekend als <a href="https://explosion.ai/blog/pseudo-rehearsal-catastrophic-forgetting">Catastrophic Forgetting</a>: in de ijver om de herkenning van een bepaalde categorie van entiteiten te verfijnen, zijn de andere entiteiten in het model bij het bijtrainen veel te ver naar de achtergrond gedrukt. De standaard oplossing hiervoor is om er voor te zorgen dat genoeg voorbeelden zijn toegevoegd in de trainingsdata die ook nog over al die andere entiteiten gaan, zodat je bijtraint met een gezonde mix aan voorbeelden die alle gevraagde entiteiten bevat. Het blijft dus belangrijk dat trainingsdata, ook als het enkel om een update gaat, goed gebalanceerd blijft.</p>



<h2 class="wp-block-heading">Custom NER</h2>



<p>Naast het updaten van een NER component kan je hem ook integraal vervangen door een andere die je zelf traint. Misschien vindt je de 17 entiteiten aangeboden in de huidige trainingsdata overkill, en heb je genoeg aan wat bijvoorbeeld het <a href="https://spacy.io/models/de">Duitse taalmodel</a> biedt: <em>Person</em>, <em>Organisation</em>, <em>Location </em>en <em>Miscellaneous</em>, zoals gedefinieerd in de <a href="https://metatext.io/datasets/wikiner">WikiNER</a> dataset, en die ook beschikbaar is voor het Nederlands en het Frans.</p>



<p>Dan doe je exact hetzelfde als voordien, maar, je haalt de mosterd bij het kant-en-klare <a href="https://github.com/explosion/projects/tree/v3/pipelines/ner_wikiner">SpaCy WikiNER project</a> dat je ook eenvoudig kan klonen:</p>



<pre class="wp-block-preformatted">python -m spacy project clone pipelines/ner_wikiner </pre>



<p>Dan is het een kwestie van de <a href="https://github.com/dice-group/FOX/tree/master/input/Wikiner">trainingsdata van WikiNER</a> te downloaden en te converteren naar het juiste inputformaat. Die datavoorbereiding is waarschijnlijk nog het meeste werk. Eens het model getraind en bewaard is, kan je de NER component ervan eenvoudig inpluggen in een andere analysepijplijn, op dezelfde manier als we al eerder een stukje hadden toegevoegd aan de Morphologizer.</p>



<p>Het wordt vooral interessant als we zelf nieuwe categorieën van entiteiten gaan definiëren. Er is immers geen reden om ons te beperken tot dat wat voorzien is in een of andere dataset. Voor <a href="https://paperswithcode.com/task/medical-named-entity-recognition">e-health toepassingen</a> kan het zeer nuttig zijn om ziektes, behandelingen en medicijnen in een tekst als dusdanig te markeren. In <a href="https://xuanwang91.github.io/BioNER/">biomedische tekst</a> kan het gaan over namen van genen of proteïnen. En in <a href="https://2019.semantics.cc/fine-grained-named-entity-recognition-legal-documents">juridische tekst </a> is de herkenning van wetsartikelen ongetwijfeld ook nuttig.</p>



<p>Zolang je er trainingsdata voor kan aanmaken, en je zorgt dat er een goede balans is tussen alle entiteiten die je wil herkennen, is het allemaal mogelijk. Met wetsartikelen hadden we dat bij Smals Research <a href="/facetten-van-natural-language-processing-deel-2/">al eens uitgeprobeerd</a>, met het oog op <a href="https://www.youtube.com/watch?v=8u57WSXVpmw">entity linking</a> &#8211; in dit geval, linken naar de eigenlijke wettekst via de <a href="https://eur-lex.europa.eu/eli-register/about.html">ELI</a>: </p>



<p><img loading="lazy" decoding="async" width="800" height="283" class="wp-image-12648" style="width: 800px;" src="/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized.png" alt="Entity Recognition van locaties, organisaties en wetsverwijzingen op een juridisch document" srcset="https://www.smalsresearch.be/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized.png 999w, https://www.smalsresearch.be/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized-300x106.png 300w, https://www.smalsresearch.be/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized-768x272.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></p>



<p>Het aanhouden van de projectstructuur van SpaCy, met een workflow definitie in <em>project.yml </em>en een trainingsconfiguratie in <em>config.cfg</em> , maakt dit alles veel gemakkelijker te beheren. We staan bij Smals Research dan ook graag open om verdere experimenten te doen met Named Entity Recognition. We kunnen snel een proof-of-concept aanleveren aan iedereen die een geannoteerde trainingsdataset heeft liggen. </p>



<h2 class="wp-block-heading">Conclusie</h2>



<p>Er is vandaag nog wat achterstand wat betreft Nederlandstalige NLP, maar het veld verandert zeer snel. Het ontbreken van grote trainingsdatasets zet een rem op de performantie. Maar met de opkomst van transfomer modellen, ook in het Nederlands, kunnen we in de nabije toekomst zeker verbetering verwachten. </p>



<p>Ondertussen zijn de bestaande taalmodellen misschien niet perfect, maar zeker niet slecht. Ze zijn bovendien erg gemakkelijk om te tweaken en te optimaliseren voor eigen toepassingen. Wie vandaag al begint met computationele analyse van taal, zal dus gemakkelijk kunnen meesurfen met de opeenvolgende verbeteringen die we de komende maanden en jaren zeker zullen zien.</p>



<p>______________________</p>



<p><em>Dit is een ingezonden bijdrage van Joachim Ganseman, IT consultant bij Smals Research. &nbsp;Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Facetten van Natural Language Processing – deel 2</title>
		<link>https://www.smalsresearch.be/facetten-van-natural-language-processing-deel-2/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Thu, 07 Feb 2019 10:32:21 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[automatic translation]]></category>
		<category><![CDATA[Disambiguation]]></category>
		<category><![CDATA[Entity Linking]]></category>
		<category><![CDATA[Entity Recognition]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<category><![CDATA[NLP]]></category>
		<category><![CDATA[Parsing]]></category>
		<guid isPermaLink="false">/?p=12622</guid>

					<description><![CDATA[Veel aspecten van Natural Language Processing (NLP) steunen op een of andere vorm van classificatie. Als we een tekst automatisch willen analyseren of begrijpen, zal het immers snel nodig zijn om labels aan (groepen van) woorden of zinnen toe te kennen. Op basis van die labels of annotaties kan de analyse verdergezet worden. Classificatie is [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Veel aspecten van Natural Language Processing (NLP) steunen op een of andere vorm van <a href="https://en.wikipedia.org/wiki/Statistical_classification">classificatie</a>. Als we een tekst automatisch willen analyseren of begrijpen, zal het immers snel nodig zijn om <em>labels </em>aan (groepen van) woorden of zinnen toe te kennen. Op basis van die labels of annotaties kan de analyse verdergezet worden.</p>



<p>Classificatie is hét typevoorbeeld van machine learning, en bij uitbreiding artificiële intelligentie. Het algemene probleem is als volgt: gegeven een bepaalde input (onze gegevens), welke output (een label) hoort daarbij? Die output geeft dan weer of de input tot een of meerdere categorieën behoort: bvb. de bloedtypes “A”, “B”, “AB”, “O”, of nog simpeler: “ja”, “nee”. Een <em>classifier (*)</em> is een algoritme dat we kunnen trainen om deze vraag te beantwoorden. Die training vereist dat we het algoritme voeden met hopen voorbeelden: een <em>dataset&nbsp;</em>van input-output-paren die we al ter beschikking hebben.</p>



<p>Bij NLP bestaat onze input uit tekst. Tekst bestaat uit zinnen, zinnen uit woorden, woorden uit letters, en op elk van die niveau’s kunnen we classifiers trainen en toepassen. Omwille van de grote woordenschat en variabiliteit in vele talen (denk aan alle vervoegingen en verbuigingen) moet een trainingsdataset voor NLP-classifiers vaak enorm groot zijn. Bovendien kan je een classifier getraind op één taal niet zomaar toepassen op een andere: daarvoor moet de classifier meestal volledig opnieuw getraind worden met een dataset uit die andere taal.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="512" src="/wp-content/uploads/2019/02/spamfilter-1024x512.png" alt="diagram van een spamfilter" class="wp-image-12660" srcset="https://www.smalsresearch.be/wp-content/uploads/2019/02/spamfilter-1024x512.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2019/02/spamfilter-300x150.png 300w, https://www.smalsresearch.be/wp-content/uploads/2019/02/spamfilter-768x384.png 768w, https://www.smalsresearch.be/wp-content/uploads/2019/02/spamfilter.png 1277w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>Diagram van een spamfilter. Image (c) Google, CC Attribution 3.0 License<br>Bron: https://developers.google.com/machine-learning/guides/text-classification/</figcaption></figure>



<p>Een courante tekstclassifier die we allemaal dagelijks gebruiken is de <a href="https://en.wikipedia.org/wiki/Naive_Bayes_spam_filtering">spamfilter</a>: gegeven een email, beslist die of het spam is, ja of nee. In dit artikel wil ik echter focussen op een fijnmaziger niveau: de classificatie van een woord, of een kleine woordgroep, binnen eenzelfde zin.</p>



<p><em>(*) Er bestaat een brede waaier aan algoritmes voor classificatie, waaronder <a href="https://en.wikipedia.org/wiki/Decision_tree_learning">decision trees</a>, <a href="https://en.wikipedia.org/wiki/Support-vector_machine">support vector machines</a>, <a href="https://en.wikipedia.org/wiki/Probabilistic_classification">probabilistische modellen</a>, <a href="https://en.wikipedia.org/wiki/Graphical_model">graaf-gebaseerde modellen</a> en <a href="https://en.wikipedia.org/wiki/Artificial_neural_network">neurale netwerken</a> in allerlei geuren en kleuren. Ze zijn in principe allemaal inzetbaar voor de NLP-problemen beschreven in dit artikel; &#8220;classifier&#8221; mag in deze tekst dus breed geïnterpreteerd worden.</em></p>



<h2 class="wp-block-heading"> </h2>



<h2 class="wp-block-heading">Grammatica</h2>



<p>In de context van <em>parsing </em>(zinsontleding) willen we bijvoorbeeld achterhalen tot welke woordsoort een woord behoort. Dit probleem staat bekend als <a href="https://en.wikipedia.org/wiki/Part-of-speech_tagging"><em>Part-of-Speech (POS) tagging</em></a>. Naamwoorden worden in veel talen verbogen, en werkwoorden vervoegd. Ter vereenvoudiging wordt daarom vaak eerst een vorm van <a href="https://en.wikipedia.org/wiki/Stemming"><em>stemming</em> of <em>lemmatisering</em></a> toegepast, waarbij men ieder woord eerst terug brengt tot zijn stam.</p>



<div class="wp-block-image"><figure class="alignright"><img loading="lazy" decoding="async" width="270" height="300" src="/wp-content/uploads/2019/02/flieslike-270x300.gif" alt="Grammaticale ambiguïteit in het Engels: &quot;Time flies like an array. Fruit flies like a banana&quot;." class="wp-image-12674"/><figcaption>Grammaticale ambiguïteit in het Engels. <br>Bron: <a href="https://specgram.com/CLIII.4/08.phlogiston.cartoon.zhe.html">SpecGram.com</a> </figcaption></figure></div>



<p>Dan nog is er ambiguïteit mogelijk. Neem het woord “werken” in de volgende voorbeelden:</p>



<ul class="wp-block-list"><li>De 12 werken van Hercules</li><li>Er zijn ook onderzoekers die werken bij Smals</li></ul>



<p>Dit illustreert de noodzaak om met <em>context </em>rekening te houden. Net daar komt machine learning van pas: we hebben een systeem nodig dat bepaalt dat het in de eerste zin het gaat om een zelfstandig naamwoord, en in de tweede zin om een werkwoord.</p>



<p>Een classifier die dat moet bepalen zal je daarom trainen met voorbeelden waarin ook enkele woorden rondom worden meegenomen (zogenoemde <em><a href="https://en.wikipedia.org/wiki/N-gram">n-grams</a></em>). Neem bijvoorbeeld 2 woorden voordien en 1 woord nadien als context:</p>



<ul class="wp-block-list"><li>“De 12 werken van” → werken = zelfst. nw.</li><li>“onderzoekers die werken bij” → werken = werkwoord</li></ul>



<p>Een geschikte classifier die zo voldoende wordt getraind, zal ook van onbekende woorden de meest waarschijnlijke woordsoort kunnen afleiden. Dit is handig omdat we dan in zekere mate kunnen omgaan met neologismen of nieuwe woordenschat:</p>



<ul class="wp-block-list"><li>“Hij schreef 7 ghjkl in zijn leven” → ghjkl = zelfstandig naamwoord</li></ul>



<h2 class="wp-block-heading">&nbsp;</h2>



<h2 class="wp-block-heading"><strong>Disambiguatie</strong></h2>



<p>Ook binnen eenzelfde woordsoort kan een woord verschillende betekenissen hebben, dit zijn de <em>homoniemen</em>. Voor ons is het evident dat als een &#8220;muis&#8221; knoppen heeft om op te drukken, je waarschijnlijk spreekt over de computermuis en niet over de veldmuis. Een computer moet eerst getraind worden om de juiste betekenis te selecteren. Dit vraagt om een classifier die je traint op een hoop zinnen waarin het woord “muis” voorkomt, in de hoop dat de classifier aanleert in welke context “muis” verwijst naar de computermuis en in welke context niet.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="162" src="/wp-content/uploads/2019/02/mouse2-1024x162.png" alt="Image search results for &quot;mouse&quot;" class="wp-image-12688" srcset="https://www.smalsresearch.be/wp-content/uploads/2019/02/mouse2-1024x162.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2019/02/mouse2-300x47.png 300w, https://www.smalsresearch.be/wp-content/uploads/2019/02/mouse2-768x122.png 768w, https://www.smalsresearch.be/wp-content/uploads/2019/02/mouse2.png 1219w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="817" height="70" src="/wp-content/uploads/2019/02/mouse-desambiguate.png" alt="Voorbeeld: desambiguatie bij het zoeken naar een muis" class="wp-image-12664" srcset="https://www.smalsresearch.be/wp-content/uploads/2019/02/mouse-desambiguate.png 817w, https://www.smalsresearch.be/wp-content/uploads/2019/02/mouse-desambiguate-300x26.png 300w, https://www.smalsresearch.be/wp-content/uploads/2019/02/mouse-desambiguate-768x66.png 768w" sizes="auto, (max-width: 817px) 100vw, 817px" /><figcaption>Google Search doet soms zelf voorstellen tot disambiguatie, die verraden welke andere contextuele termen hun zoekmachine relateert aan de verschillende betekenissen van een woord.</figcaption></figure>



<p>In de computationele linguïstiek heet dit <a href="https://en.wikipedia.org/wiki/Word-sense_disambiguation"><em>Word Sense Disambiguation</em></a>, een klassiek probleem waarvoor dan ook grote datasets bestaan voor training en evaluatie van algoritmes. Een basisdataset is het Engelstalige <a href="https://wordnet.princeton.edu/">WordNet</a>. Het Europees project <a href="https://www.babelnet.org/">BabelNet</a> breidt dat uit tot een honderdtal andere talen via Wikipedia-crosslinks, terwijl <a href="https://compling.hss.ntu.edu.sg/omw/">Open MultiLingual Wordnet</a> een lijst bevat van andere datasets gelinkt aan WordNet.</p>



<p>Data genoeg, zo lijkt het, maar dat maakt het niet noodzakelijk gemakkelijk om goede resultaten te krijgen. Zelfs de beste algoritmes halen momenteel een F1-score (een maat voor accuraatheid) die maar weinig hoger ligt dan die van de eenvoudigste strategie: “kies altijd de meest voorkomende betekenis”. <a href="https://github.com/sebastianruder/NLP-progress/blob/master/english/word_sense_disambiguation.md">Volgens de laatste resultaten</a> presteren neurale netwerken en traditionelere classifiers daarbij op ongeveer hetzelfde niveau, en doen deze classificatiegebaseerde systemen het net iets beter dan rule-based systemen.</p>



<p>Het spreekt vanzelf dat grammaticale en semantische disambiguatie allebei erg nuttig zijn voor <a href="https://en.wikipedia.org/wiki/Machine_translation">automatische vertaling</a>, waar ik in <a href="/facetten-van-natural-language-processing-deel-1/">een vorige blogpost</a> al kort over schreef.</p>



<h2 class="wp-block-heading">&nbsp;</h2>



<h2 class="wp-block-heading"><strong>Named Entity Recognition</strong></h2>



<p>In een tekst vind je al snel referenties terug naar mensen, bedrijven, plaatsnamen, bedragen, tijdstippen, kunstwerken, etc.  Vaak gaat het om eigennamen of jargon: woorden die je niet zomaar in het woordenboek terugvindt. Dit noemen we <em>entiteiten</em>, en een vaak voorkomende vraag is: kunnen we deze automatisch herkennen en markeren in een tekst? </p>



<p>Het probleem staat bekend als <a href="https://en.wikipedia.org/wiki/Named-entity_recognition"><em>Named Entity Recognition (NER)</em></a>, en je kan dat aanpakken op verschillende manieren:</p>



<ul class="wp-block-list"><li>Als je je kan beperken tot een overzichtelijke eindige lijst: gewoon kijken of een woord in dat lijstje voorkomt. Handig voor o.a. plaatsnamen of de namen van de maanden.</li><li>Als de term een gestructureerde vorm heeft, kan je werken met een <a href="https://en.wikipedia.org/wiki/Regular_expression">reguliere expressie</a>. Nuttig voor datums in een vaste vorm, identificatienummers, telefoonnummers, emailadressen of URLs.</li><li>Als een entiteit beschreven kan worden op teveel manieren om op te sommen, kan je die met een getrainde classifier proberen te herkennen. Deze aanpak wordt vaak gehanteerd voor het herkennen van persoonsnamen en organisaties, of wanneer een tekst veel spelfouten kan bevatten.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img loading="lazy" decoding="async" width="556" height="253" src="/wp-content/uploads/2019/02/ibmnews_BelgianPeopleInPolitics_20190207_2.png" alt="semantic querying via named entity recognition" class="wp-image-12668" srcset="https://www.smalsresearch.be/wp-content/uploads/2019/02/ibmnews_BelgianPeopleInPolitics_20190207_2.png 556w, https://www.smalsresearch.be/wp-content/uploads/2019/02/ibmnews_BelgianPeopleInPolitics_20190207_2-300x137.png 300w" sizes="auto, (max-width: 556px) 100vw, 556px" /><figcaption>Dankzij Named Entity Recognition kan <a href="https://news-explorer.mybluemix.net/">IBM News Explorer</a> vragen beantwoorden zoals: welke personen komen voor in (Engelstalige) nieuwsartikels over Belgische politiek? Het resultaat is niet helemaal foutloos en bevat entiteiten die geen personen zijn.</figcaption></figure></div>



<p>Ter illustratie, het volgende experiment: in een gescand juridisch document (een vonnis, een arrest, een brief van een advocaat), waaruit de tekst werd geëxtraheerd met behulp van <em><a href="https://en.wikipedia.org/wiki/Optical_character_recognition">Optical Character Recognition (OCR)</a></em>, willen we alle verwijzingen naar wetteksten markeren. Dit is nuttig om bijvoorbeeld de binnenkomende post onmiddellijk intern te kunnen doorsturen naar de jurist die gespecialiseerd is de wet waarvan sprake, of om de tekst te verrijken met links naar andere informatiebronnen over die wet&nbsp;<em>(<a href="https://en.wikipedia.org/wiki/Entity_linking">Entity Linking</a>), </em>wat een hoop manueel opzoekwerk kan besparen.</p>



<p>Een referentie naar een wettekst kan op veel manieren verwoord worden:</p>



<ul class="wp-block-list"><li>Wet ter bescherming van persoonsgegevens,</li><li>Wet ter bescherming van de persoonlijke levenssfeer ten opzichte van de verwerking van persoonsgegevens,</li><li>Wet van 8 december 1992,</li><li>Belgische Privacywet,</li><li>&#8230;&nbsp;</li></ul>



<p>Al deze referenties zouden we op een of andere manier willen herkennen. We doen dat door trainingsvoorbeelden te geven aan een classifier die antwoord geeft op de vraag: is dit woord onderdeel van een wetsverwijzing, ja of nee? De trainingsdata neemt de vorm aan van individuele zinnen waarin een wetsverwijzing voorkomt, en de beginpositie en eindpositie van die wetsverwijzing. In de volgende frase markeerden we een verwijzing naar een wetsartikel van letter <strong>26</strong> tot letter <strong>65</strong>:</p>



<ul class="wp-block-list"><li><em>terwijl overeenkomstig de <span style="background-color: #ffff99;">artikelen 87 tot 94 Wet Strafuitvoering</span> een gevangenisstraf kan worden omgezet in een werkstraf</em></li></ul>



<p>Zonder hier dieper in te gaan op de details, zal een NER-classifier proberen om in een nieuwe tekst de beginposities en eindposities van alle entiteiten terug te vinden. Een geschikte classifier zal daarbij rekening moeten kunnen houden met de context, of misschien gebruik maken van systemen zoals <em><a href="https://www.wildml.com/2016/01/attention-and-memory-in-deep-learning-and-nlp/">attention</a></em>, die kunnen zorgen voor een consistentere output.</p>



<p>In onderstaand voorbeeld proberen we ook met machine learning te detecteren welke woorden plaatsnamen en organisaties zijn. Dit omdat de input afkomstig is van een beeldscanner met OCR, waarvan het resultaat inherent spelfouten bevat. Na een minimale training is een eerste resultaat:</p>



<figure class="wp-block-image"><a href="/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized.png"><img loading="lazy" decoding="async" width="999" height="354" src="/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized.png" alt="Entity Recognition van locaties, organisaties en wetsverwijzingen op een juridisch document" class="wp-image-12648" srcset="https://www.smalsresearch.be/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized.png 999w, https://www.smalsresearch.be/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized-300x106.png 300w, https://www.smalsresearch.be/wp-content/uploads/2019/02/entityrecognitioncassatie_anonymized-768x272.png 768w" sizes="auto, (max-width: 999px) 100vw, 999px" /></a></figure>



<p>Hieruit blijkt alvast:</p>



<ul class="wp-block-list"><li>De spelfouten en splitsingstekens in de input maken het moeilijker voor NER. In plaats van &#8220;Ar-beidsrechtbank&#8221; als organisatie te markeren, wordt &#8220;Ar-&#8221; als apart woord aanzien, dat de computer blijkbaar eerder doet denken aan een wetsverwijzing &#8211; vermoedelijk omdat het begint met dezelfde letters als &#8220;artikel&#8221;.</li><li>Dat &#8220;Mechelen&#8221; soms als organisatie wordt aangeduid, is vermoedelijk omdat in de trainingsdata soms een plaatsnaam voorkomt in de naam van een organisatie. Dat zal iedere classifier in de war brengen. (Hetzelfde probleem doet zich voor bij het onderscheid tussen persoonsnamen en bedrijfsnamen: nogal wat bedrijfsnamen bevatten een persoonsnaam.)</li></ul>



<p>Met extra trainingsvoorbeelden kan dat uiteindelijk geremedieerd worden, maar duiken er elders misschien nieuwe problemen op.  Helaas vergt het samenstellen van een trainingsdataset voor gespecialiseerde toepassingen zoals deze, nog altijd veel manueel werk. <a href="https://en.wikipedia.org/wiki/Crowdsourcing">Crowdsourcing </a>kan daarvoor eventueel een oplossing bieden.&nbsp;En dan nog is het onbegonnen werk om alle mogelijke variaties en nuances te vatten, zodus zal er altijd met een zekere <strong>foutenmarge </strong>rekening gehouden moeten worden. </p>



<p>Met de entiteiten die wél goed gedetecteerd worden, kunnen we alvast aan de slag. Een link naar een andere toepassing met nuttige info over die wettekst is snel gelegd: bijvoorbeeld naar de integrale gepubliceerde wetteksten, die in Europa sinds kort online beschikbaar worden gesteld via een gestandaardiseerd systeem, de <a href="https://eur-lex.europa.eu/eli-register/about.html">European Legislation Identifier (ELI)</a>.</p>



<figure class="wp-block-image"><a href="/wp-content/uploads/2019/02/entitylinking.png"><img loading="lazy" decoding="async" width="940" height="297" src="/wp-content/uploads/2019/02/entitylinking.png" alt="Voorbeeld van entity linking: link een wetsverwijzing naar de wettekst." class="wp-image-12650" srcset="https://www.smalsresearch.be/wp-content/uploads/2019/02/entitylinking.png 940w, https://www.smalsresearch.be/wp-content/uploads/2019/02/entitylinking-300x95.png 300w, https://www.smalsresearch.be/wp-content/uploads/2019/02/entitylinking-768x243.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></a></figure>



<p>Dit werd als proof-of-concept uitgewerkt op de <a href="https://overheid.vlaanderen.be/opleiding/nlp4gov-de-eerste-belgische-nlp-hackathon">NLP4Gov Hackathon</a> georganiseerd door Informatie Vlaanderen in 2018. Daar ging een team van startup <a href="https://www.thematchbox.be/">TheMatchbox</a> aan de slag met een dataset die Smals Research voorstelde samen met <a href="https://www.rsz.fgov.be/nl">RSZ-ONSS</a> en <a href="https://www.igo-ifj.be/nl">IGO-IFJ</a>, op basis van de gepubliceerde arresten van het <a href="https://justitie.belgium.be/nl/rechterlijke_orde/hoven_en_rechtbanken/hof_van_cassatie/documenten/arresten_van_cassatie">Hof van Cassatie</a>. Om af te sluiten, hun filmpje dat het eindresultaat presenteert:</p>



<figure><iframe loading="lazy" src="https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Fthematchbox.be%2Fvideos%2F2247087955333449%2F&amp;show_text=0&amp;width=560" width="560" height="315" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true"></iframe></figure>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Facetten van Natural Language Processing – deel 1</title>
		<link>https://www.smalsresearch.be/facetten-van-natural-language-processing-deel-1/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Mon, 15 Oct 2018 15:16:32 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[automatic translation]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<category><![CDATA[NLP]]></category>
		<category><![CDATA[Parsing]]></category>
		<guid isPermaLink="false">/?p=12235</guid>

					<description><![CDATA[Bij Natural Language Processing (NLP) denken veel mensen spontaan aan spraakherkenning. Het blijft een van de meest tot de verbeelding sprekende toepassingen, en de technologie is ondertussen robuust genoeg dat ze steeds vaker ingang vindt in alledaagse toepassingen. Apple’s Siri, Google Home of Amazon Alexa zijn bekende voorbeelden. Taal is echter meer dan spraak alleen. [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Bij Natural Language Processing (NLP) denken veel mensen spontaan aan spraakherkenning. Het blijft een van de meest tot de verbeelding sprekende toepassingen, en de technologie is ondertussen <a href="https://github.com/syhw/wer_are_we">robuust genoeg</a> dat ze steeds vaker ingang vindt in alledaagse toepassingen. Apple’s Siri, Google Home of Amazon Alexa zijn bekende voorbeelden.</p>
<p>Taal is echter meer dan spraak alleen. Ook geschreven tekst valt onder de noemer “Natural Language”: krantenartikels, boeken en tijdschriften, blogs en Wikipedia-pagina’s, … Er worden bergen onderzoek verzet naar het extraheren van nuttige informatie uit al deze bronnen, of het automatisch proberen begrijpen van de inhoud ervan. Voortgestuwd door de recente vooruitgang in artificiële intelligentie, zien we ook veel beweging in deze tekstuele subdomeinen van NLP. In deze eerste blogpost over NLP houden we de vinger aan de pols van enkele belangrijke facetten ervan: parsing en automatische vertaling.</p>
<p><strong>Parsing</strong></p>
<p>Parsing is zinsontleding voor computers. Daarbij wordt geprobeerd aan ieder woord of zinsdeel een label toe te kennen (is het een bijwoord, naamwoord, werkwoord, bijzin, …), en zo mogelijk ook de grammaticale structuur af te leiden.</p>
<p><figure id="attachment_12243" aria-describedby="caption-attachment-12243" style="width: 183px" class="wp-caption alignleft"><a href="/wp-content/uploads/2018/10/Parse_tree_NL.jpg"><img loading="lazy" decoding="async" class=" wp-image-12243" src="/wp-content/uploads/2018/10/Parse_tree_NL.jpg" alt="" width="183" height="200" /></a><figcaption id="caption-attachment-12243" class="wp-caption-text">Parsing van een zin (S) in een constituency tree. De moeilijkheid is het correct labelen van &#8220;plant&#8221; als een werkwoord (V) en niet als een zelfstandig naamwoord (N).</figcaption></figure></p>
<p>In de meest eenvoudige vorm worden woorden individueel gelabeld (&#8220;<a href="https://en.wikipedia.org/wiki/Part-of-speech_tagging">Part of Speech tagging</a>&#8220;). Op relatief “schone” tekst, zoals uit kranten, worden ondertussen accuraatheden van <a href="https://en.wikipedia.org/wiki/Part-of-speech_tagging">bijna 98% gehaald</a> op de belangrijkste Engelstalige en bijna 97% op de belangrijkste <a href="https://universaldependencies.org/">meertalige</a> datasets. Op een hoger niveau kan men ook zinsdelen proberen herkennen &#8211; wat men “<a href="https://en.wikipedia.org/wiki/Shallow_parsing">shallow parsing</a>” of “<a href="https://aclweb.org/aclwiki/NP_Chunking_(State_of_the_art)">chunking</a>” noemt.</p>
<p>Aan de basis van automatisch vertalen (Google/Bing Translate, …) liggen meestal <a href="https://en.wikipedia.org/wiki/Phrase_structure_grammar"><em>constituency grammars</em></a>, waarmee gemakkelijker overkoepelende grammaticale structuren voorgesteld worden. Met traditionele methodes zijn er echter nog <a href="https://www.statmt.org/book/">talloze kleine regeltjes nodig</a> om correct met woordvolgorde of de nodige tussenvoegsels om te gaan. Door de boomstructuur voor te stellen als een rij van karakters en er zogenaamde <a href="https://theai.wiki/Seq2Seq"><em>sequence-to-sequence</em></a> methodes op los te laten, bleek men ook die speciale regeltjes <a href="https://papers.nips.cc/paper/5635-grammar-as-a-foreign-language.pdf">automatisch te kunnen aanleren</a>. Met zulke <em>deep learning</em> methodes wordt nog regelmatig <a href="https://nlpprogress.com/constituency_parsing.html">vooruitgang geboekt</a> op het vlak van parsing.</p>
<p>Correct parsen is een voorwaarde om daaropvolgende analyses, zoals een vertaling of een automatische annotatie, ook correct te kunnen uitvoeren. Er komen echter nogal wat moeilijkheden kijken bij natuurlijke taal, waaronder:</p>
<ul>
<li>Verschillende verbuigingen of vervoegingen van hetzelfde woord moeten herkend worden als variaties van datzelfde woord (door <a href="https://en.wikipedia.org/wiki/Stemming">stemming</a> of <a href="https://en.wikipedia.org/wiki/Lemmatisation">lemmatization</a>).</li>
<li>Vaste uitdrukkingen en idiomen worden misschien best niet letterlijk geïnterpreteerd.</li>
<li>Interpunctie maakt een <a href="https://cybertext.wordpress.com/2012/11/22/a-light-hearted-look-at-how-punctuation-can-change-meaning/">wereld van verschil</a>.</li>
</ul>
<p>Dat alles is bovendien verschillend voor iedere taal. Alleen al aan die problemen zijn hele subdomeinen van NLP gewijd. <span style="font-weight: 300;">Bovendien kan natuurlijke taal ook erg </span><a style="font-weight: 300;" href="https://nl.wikipedia.org/wiki/Ambigu%C3%AFteit">ambigu of dubbelzinnig</a><span style="font-weight: 300;"> zijn</span><span style="font-weight: 300;">. Zonder nu dieper in te gaan op al deze moeilijkheden (dat doe ik misschien in een volgend artikel), enkele voorbeeldjes van dat laatste:</span></p>
<ul>
<li>Op grammaticaal vlak is de functie van een woord niet altijd eenduidig. Voorbeeld uit de laatste link: “De man slaat de hond met de stok” – wie heeft hier de stok vast? Ook in “De jongen die Marc geslagen heeft” is niet duidelijk wat nu het onderwerp of het lijdend voorwerp is.</li>
<li>Op semantisch vlak kan een woord meerdere betekenissen hebben. In dat geval is er meestal context nodig om te weten over welke betekenis het gaat. Is die context er niet of onvoldoende, dan slaan ook de beste automatische vertaalmachines de bal mis.</li>
</ul>
<p><figure id="attachment_12242" aria-describedby="caption-attachment-12242" style="width: 1134px" class="wp-caption alignnone"><a href="/wp-content/uploads/2018/10/ascenseur.png"><img loading="lazy" decoding="async" class="size-full wp-image-12242" src="/wp-content/uploads/2018/10/ascenseur.png" alt="Vertaling van Nederlands naar Frans" width="1134" height="223" srcset="https://www.smalsresearch.be/wp-content/uploads/2018/10/ascenseur.png 1134w, https://www.smalsresearch.be/wp-content/uploads/2018/10/ascenseur-300x59.png 300w, https://www.smalsresearch.be/wp-content/uploads/2018/10/ascenseur-768x151.png 768w, https://www.smalsresearch.be/wp-content/uploads/2018/10/ascenseur-1024x201.png 1024w" sizes="auto, (max-width: 1134px) 100vw, 1134px" /></a><figcaption id="caption-attachment-12242" class="wp-caption-text">Bij gebrek aan context, is het voor automatische vertalers moeilijker om de juiste betekenis te selecteren van homoniemen. (credits: met dank aan Renzo Lylon voor dit voorbeeld.)</figcaption></figure></p>
<p><strong>Automatisch (v|h)ertalen</strong></p>
<p>Het gebruik van deep learning in vertaling wordt vaak <a href="https://en.wikipedia.org/wiki/Neural_machine_translation">Neural Machine Translation</a> genoemd. Omdat daarmee correctere woordkeuzes en woordvolgordes bekomen worden, en omdat zo enigszins (maar zeker niet perfect) ook met context rekening wordt gehouden, is Google eind 2016 begonnen met de <a href="https://blog.google/products/translate/found-translation-more-accurate-fluent-sentences-google-translate/">uitrol ervan in Translate</a>, en ook de meeste andere online vertaaldiensten zijn ondertussen hierop gebaseerd.</p>
<p>Het evalueren van automatisch vertalen blijft echter moeilijk. De meest gebruikte metriek voor automatisch vertalen, <a href="https://en.wikipedia.org/wiki/BLEU">BLEU</a>, probeert te meten hoe een professional de vertaling zou beoordelen. Er is echter van bekend dat de manier van meten toch enkele tendensen vertoont (bvb het bevoordelen van kortere vertalingen).  Qua datasets om zulke systemen te trainen en testen zijn er o.a. erg veel meertalige gegevens van het <a href="https://www.statmt.org/europarl/">Europees Parlement</a>, die echter logischerwijs enkel westerse talen bevatten. Er is dus nog zeker werk aan de winkel wat betreft inclusie van niet-westerse en zeldzamere talen. Ondertussen leiden die lacunes soms tot <a href="https://debunkingdoomsday.quora.com/Debunked-Why-does-Google-Translate-sometimes-translate-nonsense-into-end-times-messages">bevreemdende effecten</a> in online vertaaltools.</p>
<p><figure id="attachment_12251" aria-describedby="caption-attachment-12251" style="width: 2108px" class="wp-caption alignnone"><a href="/wp-content/uploads/2018/10/semantic-parsing-frames.png"><img loading="lazy" decoding="async" class="size-full wp-image-12251" src="/wp-content/uploads/2018/10/semantic-parsing-frames.png" alt="voorbeeld van semantic parsing" width="2108" height="558" srcset="https://www.smalsresearch.be/wp-content/uploads/2018/10/semantic-parsing-frames.png 2108w, https://www.smalsresearch.be/wp-content/uploads/2018/10/semantic-parsing-frames-1536x407.png 1536w, https://www.smalsresearch.be/wp-content/uploads/2018/10/semantic-parsing-frames-2048x542.png 2048w, https://www.smalsresearch.be/wp-content/uploads/2018/10/semantic-parsing-frames-300x79.png 300w, https://www.smalsresearch.be/wp-content/uploads/2018/10/semantic-parsing-frames-768x203.png 768w, https://www.smalsresearch.be/wp-content/uploads/2018/10/semantic-parsing-frames-1024x271.png 1024w" sizes="auto, (max-width: 2108px) 100vw, 2108px" /></a><figcaption id="caption-attachment-12251" class="wp-caption-text">Semantic Parsing linkt de woorden uit een zin aan hun betekenis. Daarmee kunnen we later automatisch vragen beantwoorden zoals in dit geval &#8220;Waar heeft Lansky gewoond?&#8221; en &#8220;Wat heeft Lansky gestudeerd?&#8221;. Image (c) Ivan Titov et al., &#8220;Inducing Shallow Semantic Representations from Text&#8221;, 2016.</figcaption></figure></p>
<p>Vertaling hoeft niet alleen van een gesproken taal naar een andere gesproken taal te gaan. We kunnen even goed &#8220;hertalen&#8221;: de vraag in natuurlijke taal omzetten naar een query die op een database uitgevoerd kan worden, of naar een andere formele structuur zoals computercode. Deze vorm van NLP, <a href="https://github.com/sebastianruder/NLP-progress/blob/master/semantic_parsing.md">Semantic Parsing</a>, wordt o.a. gebruikt door Google Assistant of Amazon Alexa om vragen in natuurlijke taal te beantwoorden (genre “Wie is de president van de VS?”). Om dat op grote schaal te trainen en testen bestaan verschillende datasets die beschrijvingen van een query in natuurlijke taal linken aan de query zelf. (<a href="https://github.com/salesforce/WikiSQL">WikiSQL</a>, <a href="https://github.com/Microsoft/CNTK/tree/master/Examples/LanguageUnderstanding/ATIS">ATIS vliegverkeer</a>, etc). Voor specifieke toepassingen of niet-courante talen heb je vaak geen andere keuze dan het zelf opbouwen van een eigen database, die sowieso erg groot moet zijn. <a href="https://en.wikipedia.org/wiki/Crowdsourcing">Crowdsourcing</a> kan voor dat laatste eventueel een oplossing bieden.</p>
<p><figure id="attachment_12250" aria-describedby="caption-attachment-12250" style="width: 299px" class="wp-caption alignright"><a href="/wp-content/uploads/2018/10/IBM_Watson_w_Jeopardy.jpg"><img loading="lazy" decoding="async" class=" wp-image-12250" src="/wp-content/uploads/2018/10/IBM_Watson_w_Jeopardy.jpg" alt="IBM Watson won Jeopardy in 2011" width="299" height="202" /></a><figcaption id="caption-attachment-12250" class="wp-caption-text">IBM&#8217;s NLP computer &#8220;Watson&#8221; won Jeopardy tegen 2 spelers in 2011</figcaption></figure></p>
<p>Van daar is de stap snel gezet naar het beantwoorden van (algemene) vragen. Hiermee gooide IBM hoge ogen toen hun <a href="https://en.wikipedia.org/wiki/Watson_(computer)">Watson</a> systeem het spel Jeopardy won. Het probleem lijkt een beetje op een “examen begrijpend lezen”: gegeven een document of stukje tekst, wordt een bepaalde vraag gesteld waarvan het antwoord teruggevonden moet worden (al dan niet letterlijk) in de tekst. Daarvoor wordt de computer voorzien van de inhoud van, bijvoorbeeld, Wikipedia. Op basis van een training met vragen en de correcte antwoorden daarop, tracht men de computer zelf te doen afleiden hoe het het antwoord van een vraag moet opzoeken in de beschikbare dataset. Ook voor de training hiervan bestaan grote datasets, met bvb vragen over <a href="https://github.com/Maluuba/newsqa">nieuwsartikels</a>, crowdsourced op basis van <a href="https://rajpurkar.github.io/SQuAD-explorer/">Wikipedia</a>, of van <a href="https://github.com/qizhex/RACE_AR_baselines">eindexamens Engels</a> in China.</p>
<p><strong>De data definieert het systeem</strong></p>
<p>Eens we op dit niveau van NLP aankomen, zijn we erg afhankelijk van de datasets waarop het systeem wordt getraind. Kunnen we een systeem dat is getraind op tekst uit Wikipedia, inzetten om documenten met een heel andere inhoud te verwerken – van straattaal tot juridisch jargon (i.e. <a href="https://artix41.github.io/static/domain-adaptation-in-2017/index.html">domein-adaptatie</a>)? Deze uitdaging van de <a href="https://thegradient.pub/frontiers-of-generalization-in-natural-language-processing/"><em>generaliseerbaarheid</em></a> van systemen die getraind zijn op gelimiteerde of biased datasets, vinden we terug in zo goed als elke AI-applicatie. We willen vermijden dat een AI-systeem bepaalde biases (&#8220;vooroordelen&#8221;) aanleert of bestendigt. Daar zijn <a href="https://www.infoq.com/presentations/unconscious-bias-machine-learning">veel voorbeelden</a> van bekend, en dat dat voor problemen zorgt, lichtte ik al toe in een <a href="/enkele-valkuilen-in-ai/">vorige blogpost</a>. Ook recent nog verschenen berichten over een <a href="https://www.reuters.com/article/us-amazon-com-jobs-automation-insight/amazon-scraps-secret-ai-recruiting-tool-that-showed-bias-against-women-idUSKCN1MK08G">CV-screening systeem dat de mist in ging</a> op dat vlak. Dit blijft dus om permanente waakzaamheid vragen.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
