<?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>Pierre Leleux &#8211; Smals Research</title>
	<atom:link href="https://www.smalsresearch.be/author/leleux/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.smalsresearch.be</link>
	<description></description>
	<lastBuildDate>Thu, 09 Apr 2026 12:23:58 +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>Pierre Leleux &#8211; Smals Research</title>
	<link>https://www.smalsresearch.be</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Neosemantics &#8211; Semantic tools for Neo4J</title>
		<link>https://www.smalsresearch.be/neosemantics-semantic-tools-for-neo4j/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Thu, 04 Dec 2025 13:02:12 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Quick reviews]]></category>
		<guid isPermaLink="false">https://www.smalsresearch.be/neosemantics-semantic-tools-for-neo4j/</guid>

					<description><![CDATA[(FR) Neosemantics est un plugin java pour Neo4J, ayant pour but de rendre accessibles les outils sémantiques de RDF, afin de pouvoir les utiliser directement au sein de Neo4J. (NL) Neosemantics is een Java plug-in voor Neo4J, ontworpen om RDF-semantische tools toegankelijk te maken voor direct gebruik binnen Neo4J.]]></description>
										<content:encoded><![CDATA[
<p><strong>(FR)</strong> Neosemantics est un plugin java pour Neo4J, ayant pour but de rendre accessibles les outils sémantiques de RDF, afin de pouvoir les utiliser directement au sein de Neo4J.</p>



<p><strong>(NL)</strong> Neosemantics is een Java plug-in voor Neo4J, ontworpen om RDF-semantische tools toegankelijk te maken voor direct gebruik binnen Neo4J.</p>



<div data-wp-interactive="core/file" class="wp-block-file"><object data-wp-bind--hidden="!state.hasPdfPreview" hidden class="wp-block-file__embed" data="/wp-content/uploads/2025/12/Quick-review-n10s.pdf" type="application/pdf" style="width:100%;height:600px" aria-label="Embed of Quick-review-n10s."></object><a id="wp-block-file--media-db2780a5-840d-4008-ac93-5e78372e49bb" href="https://www.smalsresearch.be/wp-content/uploads/2025/12/Quick-review-n10s.pdf">Quick-review-n10s</a><a href="/wp-content/uploads/2025/12/Quick-review-n10s.pdf" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-db2780a5-840d-4008-ac93-5e78372e49bb">Download</a></div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Ingestion van ongestructureerde data: hoe maak je automatisch een graph op basis van tekst?</title>
		<link>https://www.smalsresearch.be/ingestion-van-ongestructureerde-data-graph/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Mon, 06 Oct 2025 09:00:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[data ingestion]]></category>
		<category><![CDATA[Knowledge Graph]]></category>
		<category><![CDATA[Large Language Model]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<guid isPermaLink="false">/?p=24036</guid>

					<description><![CDATA[Dit artikel gaat in op de manieren waarop een graph kan worden verkregen op basis van tekstuele data, de verschillende soorten graphs die kunnen worden geëxtraheerd en de tools die vaak worden gebruikt.]]></description>
										<content:encoded><![CDATA[
<p><a href="/ingestion-donnees-non-structurees-vers-graphe/"><em>Version en Français</em></a></p>
<p>Graphs, en meer bepaald knowledge graphs, maken het mogelijk om <a href="/graphtechnologieen-toepassingen-en-tools-2/">informatie op een gestructureerde manier weer te geven</a>. Zo krijgt een persoon een visuele samenvatting van de inhoud van een of meerdere documenten en kan een machine deze structuur gebruiken om bijvoorbeeld de inhoud ervan te analyseren (met behulp van <a href="/graphtechnologieen-toepassingen-en-tools/">graphalgoritmen</a>) en/of redeneringen te maken op basis van de graph (bijvoorbeeld in het kader van <a href="/graphrag-naar-een-knowledge-graph-augmented-generatie/">een graphRAG-toepassing</a> of om impliciete informatie te ontdekken (af te leiden)).</p>
<p>Dit artikel gaat in op de manieren waarop een graph kan worden verkregen op basis van tekstuele data, de verschillende soorten graphs die kunnen worden geëxtraheerd en de tools die vaak worden gebruikt, afhankelijk van het type extractie dat men wil uitvoeren.</p>
<p>Aangezien grote taalmodellen (LLM&#8217;s) bijzonder geschikt zijn voor tekstverwerking, zal dit artikel zich voornamelijk richten op de presentatie van LLM-gebaseerde benaderingen en vervolgens kort ingaan op verschillende alternatieve benaderingen.</p>



<h2 class="wp-block-heading">Knowledge graphs: een kort overzicht</h2>



<p>Een graph is een structuur die bestaat uit een reeks nodes en bogen (die paren van nodes met elkaar verbinden). Een knowledge graph voegt een extra semantische laag toe aan een klassieke graph, waarbij elke node een concept vertegenwoordigt (entiteit, persoon, enz.) en elke boog een relatie tussen twee concepten vertegenwoordigt (“werkt voor”, “is bevriend met”, enz.). Het is dus een weergave van kennis in de vorm van een reeks onderling verbonden entiteiten. Meer details over de verschillende soorten graphs en de bijbehorende tools vindt u <a href="/graphtechnologieen-toepassingen-en-tools/">hier</a>.</p>



<h2 class="wp-block-heading">Voorbereiding van het documentcorpus</h2>



<p>Voor de eenvoud gaan we ervan uit dat de tekstdocumenten die worden gebruikt om de graph op te bouwen, correct zijn opgeschoond. Dit artikel is namelijk niet bedoeld om de voorbewerking van tekstdocumenten (scrapen van webpagina&#8217;s, extraheren van tekst uit pdf-bestanden, enz.) te bespreken, aangezien deze voorbewerking op zich al een uitgebreid onderwerp is dat ongetwijfeld een apart artikel verdient.</p>



<h3 class="wp-block-heading">Fragmentatie van de tekst in “chunks”</h3>



<p>Een belangrijke stap in de voorbereiding van tekstdata voordat entiteiten en relaties worden geëxtraheerd, is het opsplitsen van de tekst in fragmenten (meestal ‘chunks’ genoemd). We hebben het concept van chunking al meerdere keren besproken in <a href="/databeheer-voor-generatieve-ai-toepassingen-kernbegrippen/">vorige blogposts</a>. Wanneer een document te lang is (meer dan enkele paragrafen), is het raadzaam om het op te splitsen in chunks (tekstfragmenten van redelijke omvang) die één voor één door de LLM worden verwerkt. Deze procedure maakt het mogelijk om de hoeveelheid informatie in elke chunk te beperken, zodat deze niet te veel entiteiten en relaties bevat die moeten worden geëxtraheerd. Deze opsplitsing in chunks kan op verschillende manieren gebeuren, hetzij op basis van het aantal woorden in de chunk, hetzij op basis van een vooraf gedefinieerd scheidingsteken (bijvoorbeeld een regeleinde dat het einde van de paragraaf aangeeft).</p>



<h2 class="wp-block-heading">De informatie weergeven of de structuur weergeven</h2>



<p>Laten we beginnen met de twee belangrijkste soorten graphs die kunnen worden geconstrueerd op basis van een reeks tekstdocumenten.</p>
<p>De eerste is een graph die de structuur van het document weergeeft (<em>document structure graph</em>), en niet de informatie die in de tekst staat. Bijvoorbeeld door de chunks te koppelen aan het document waaruit ze zijn gehaald en de volgorde waarin ze in het document voorkomen:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Document_structure_graph.png"><img fetchpriority="high" decoding="async" width="939" height="527" src="/wp-content/uploads/2025/09/Document_structure_graph.png" alt="" class="wp-image-23750" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph.png 939w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph-300x168.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph-768x431.png 768w" sizes="(max-width: 939px) 100vw, 939px" /></a><figcaption class="wp-element-caption">Figuur 1: Graph die de structuur van een eenvoudig document weergeeft</figcaption></figure>



<p>Dit type graph kan ook worden verrijkt door relaties toe te voegen tussen semantisch vergelijkbare chunks of, indien van toepassing, door de hiërarchische organisatie van het document weer te geven in secties, subsecties, enz. Dit gebeurt via nodes die de secties/subsecties vertegenwoordigen en relaties van het type “HAS_SECTION”, “HAS_SUBSECTION”, evenals relaties die de volgorde van de secties/subsecties aangeven. Zodra de graph is opgebouwd, kan deze bijvoorbeeld worden gebruikt in RAG-toepassingen voor indexeringsdoeleinden om context te bieden aan de gebruikte chunks (zie <a href="/graphrag-naar-een-knowledge-graph-augmented-generatie/">onze blogpost over graphRAG</a>).</p>
<p>Het tweede type graph bestaat uit het opnemen van de informatie in de documenten in de vorm van nodes en relaties:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Domain_graph.png"><img decoding="async" width="877" height="179" src="/wp-content/uploads/2025/09/Domain_graph.png" alt="" class="wp-image-23751" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph.png 877w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph-300x61.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph-768x157.png 768w" sizes="(max-width: 877px) 100vw, 877px" /></a><figcaption class="wp-element-caption">Figuur 2: Voorbeeld van informatie-extractie</figcaption></figure>



<p>In het kader van deze blogpost zullen we ons concentreren op dit tweede type graph. Merk op dat beide benaderingen elkaar niet uitsluiten. Als men voor het tweede type graph kiest, is het trouwens vaak nuttig om ook de documentstructuur weer te geven. Zo kan men indien nodig teruggaan naar de bron van de informatie in de graph.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Graph_combined.png"><img decoding="async" width="896" height="674" src="/wp-content/uploads/2025/09/Graph_combined.png" alt="" class="wp-image-23754" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined.png 896w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined-300x226.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined-768x578.png 768w" sizes="(max-width: 896px) 100vw, 896px" /></a><figcaption class="wp-element-caption">Figuur 3: Extractie van structuur en informatie</figcaption></figure>



<h2 class="wp-block-heading">Opbouw van een knowledge graph met behulp van een LLM</h2>



<p>Eerst zullen we de algemene procedure voor het aanmaken van een knowledge graph op basis van tekstdocumenten via LLM voorstellen, alvorens te bekijken hoe deze aan de eigen behoeften kan worden aangepast.</p>
<p>LLM&#8217;s ontvangen standaard tekst als input (prompt) en sturen tekst terug als output in reactie op de prompt. Afhankelijk van de instructies bieden LLM&#8217;s echter de mogelijkheid om <strong><em>gestructureerde outputs</em></strong> te genereren, zoals JSON-bestanden. Vaak wordt deze functionaliteit gebruikt als basis voor het extraheren van kennis naar een graph, omdat deze gestructureerde output systematisch kan worden verwerkt.</p>
<p>Een script (bv. Python) haalt de chunks op en stuurt ze een voor een naar de LLM door een gestructureerd antwoord op te leggen (bv. <a href="https://python.langchain.com/docs/how_to/structured_output/">LangChain met de methode <em>llm.with_structured_output()</em></a>), met instructies over de taak, het type informatie dat in de tekst moet worden gedetecteerd en de structuur van het verwachte antwoord in de output. De gestructureerde output (meestal in JSON) wordt vervolgens eenvoudigweg ontleed in Python om de door de LLM gedetecteerde informatie (nodes/relaties) op te halen, die vervolgens rechtstreeks aan de graph kan worden toegevoegd (via een databasedriver).</p>
<p>Interessant is dat LLM&#8217;s een grote verscheidenheid aan antwoorden kunnen geven en dat het gebruik van gestructureerde output niet altijd nodig is. In sommige gevallen is het nog steeds het eenvoudigst om de LLM te vragen zijn extracties te leveren in de vorm van queries (bijvoorbeeld queries die de gedetecteerde nodes/relaties direct toevoegen), die als zodanig kunnen worden uitgevoerd, of in de vorm van RDF triples.</p>
<p>Na de algemene procedure, kijken we nu meer in detail naar de verschillende manieren om de informatie in de chunks binnen een graph te extraheren en weer te geven, te beginnen met de eenvoudigste benadering (thema-extractie) tot de meest complete (extractie van entiteiten en relaties).</p>



<h3 class="wp-block-heading">Thematische extractie</h3>



<p>In deze eerste benadering richten we ons op het opsporen en extraheren van de thema&#8217;s die in het document aan bod komen. We bouwen dus een thematische weergave van de verschillende documenten in het corpus om een structuur te verkrijgen van het type:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Theme_extraction.png"><img loading="lazy" decoding="async" width="872" height="178" src="/wp-content/uploads/2025/09/Theme_extraction.png" alt="" class="wp-image-23756" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction.png 872w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction-300x61.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction-768x157.png 768w" sizes="auto, (max-width: 872px) 100vw, 872px" /></a><figcaption class="wp-element-caption">Figuur 4: Ontologieschema van een thematische extractie</figcaption></figure>



<p>De graph heeft dus een lichte structuur en wordt gebruikt voor referentiedoeleinden, om gemakkelijk en snel documenten te identificeren die betrekking hebben op een (of meerdere) bepaald(e) onderwerp(en) van belang. Met dit type graph kunnen ook gelijkenissen tussen documenten (of tussen chunks) worden vastgesteld op basis van de gemeenschappelijke onderwerpen, of kan eenvoudigweg een schematische weergave worden gegeven van hun corpus van documenten en de thema&#8217;s die daarin aan bod komen.</p>
<p>Dit kan op een niet-gestuurde manier (de LLM vrij laten bepalen welke thema&#8217;s in de chunk aan bod komen) of op een gestuurde manier gebeuren (de LLM kiest een of meer thema&#8217;s uit een vooraf gedefinieerde lijst met thema&#8217;s die in de instructies van de prompt wordt gegeven).</p>



<h3 class="wp-block-heading">Extractie van <em>named entities</em></h3>



<p>De extractie (of herkenning) van <em>named entities</em> (<em>named-entity recognition</em>, vaak afgekort tot NER) is een bekend domein van natuurlijke taalverwerking (<em>natural language processing</em> (NLP)) dat bestaat uit het detecteren en categoriseren van entiteiten (personen, organisaties, plaatsen, enz.) die in een tekst worden genoemd. Het doel is dus vergelijkbaar met dat van thematische extractie: een graph maken door tekstfragmenten te koppelen aan de entiteiten die erin worden genoemd. We krijgen dus een graph met het volgende standaard schema:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Entity_extraction.png"><img loading="lazy" decoding="async" width="877" height="176" src="/wp-content/uploads/2025/09/Entity_extraction.png" alt="" class="wp-image-23752" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction.png 877w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction-300x60.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction-768x154.png 768w" sizes="auto, (max-width: 877px) 100vw, 877px" /></a><figcaption class="wp-element-caption">Figuur 5: Ontologieschema van een extractie van <em>named entities</em></figcaption></figure>



<p>Met dit type graph kunnen ook gelijkenissen tussen documenten (of tussen chunks) worden vastgesteld op basis van de entiteiten die ze gemeenschappelijk hebben. Het is interessant om op te merken dat deze extractie vergelijkbaar is met een volledige extractie (inclusief entiteiten en relaties, zie onderstaande paragraaf), behalve dat hier alleen de entiteiten worden geëxtraheerd en niet de relaties die ze met elkaar verbinden. Dit is een lichtere en gemakkelijker te implementeren oplossing wanneer een volledige extractie niet nodig is.</p>
<p>Dit soort extractie kan gemakkelijk worden uitgevoerd met behulp van een LLM met gestructureerde outputs. Met het <code>pydantic</code>-pakket kunnen op maat gemaakte templates worden gemaakt voor de verwachte outputstructuur. Bijvoorbeeld:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from pydantic import BaseModel, Field
from typing import List
class Entity(BaseModel):
    category: str = Field(description="The category of the entity.")
    name: str = Field(description="The name of the entity.")
class Extraction(BaseModel):
    entityList: List&#91;Entity&#93; = Field(description="The list of extracted entities.")
structured_llm = llm.with_structured_output(Extraction)
extracted=structured_llm.invoke(myPrompt)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> pydantic </span><span style="color: #AF00DB">import</span><span style="color: #000000"> BaseModel, Field</span></span>
<span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> typing </span><span style="color: #AF00DB">import</span><span style="color: #000000"> List</span></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">Entity</span><span style="color: #000000">(</span><span style="color: #267F99">BaseModel</span><span style="color: #000000">):</span></span>
<span class="line"><span style="color: #000000">    category: </span><span style="color: #267F99">str</span><span style="color: #000000"> = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The category of the entity.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">    name: </span><span style="color: #267F99">str</span><span style="color: #000000"> = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The name of the entity.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">Extraction</span><span style="color: #000000">(</span><span style="color: #267F99">BaseModel</span><span style="color: #000000">):</span></span>
<span class="line"><span style="color: #000000">    entityList: List&#91;Entity&#93; = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The list of extracted entities.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">structured_llm = llm.with_structured_output(Extraction)</span></span>
<span class="line"><span style="color: #000000">extracted=structured_llm.invoke(myPrompt)</span></span></code></pre></div>



<p> </p>
<p>In dit eenvoudige voorbeeld wordt de LLM gevraagd om een gestructureerde output van het type “Extraction” terug te geven, met als attribuut “entityList”, een lijst van “Entity”-objecten “ die net daarvoor zijn gedefinieerd.</p>
<p>Het is interessant om op te merken dat dit type template kan worden uitgebreid wanneer we extra informatie willen extraheren of het type gedetecteerde entiteiten willen beperken. Als we bijvoorbeeld alleen entiteiten van het type “persoon” en “onderneming” willen detecteren, kan de template worden aangepast door de klassen “ Persoon” en “Onderneming&#8221; aan te maken, waarin de attributen worden opgesomd die voor elke instantie van deze entiteiten moeten worden geëxtraheerd, en door het veld ”entityList“ te vervangen door twee velden “personList” en ”enterpriseList&#8221; in het uiteindelijke object dat moet worden teruggegeven.</p>
<p>Het voordeel van het gebruik van de methode <code>with_structured_output</code> is dat LangChain automatisch controleert of de output van de LLM overeenkomt met de template.</p>



<h3 class="wp-block-heading">Extractie van entiteiten en relaties</h3>



<p>Het doel hier is het bouwen van een graph die de kennis in het document of de documenten weergeeft in de vorm van onderling verbonden entiteiten (nodes) en relaties. Dit is de meest uitgebreide (en meest ingewikkelde) taak die we in detail zullen bekijken.</p>
<p>Laten we het volgende stukje tekst nemen om te illustreren wat voor soort extractie we hier willen uitvoeren:</p>
<p><em>“The San Fransisco-based 9th U.S. Circuit Court of Appeals rejected the legal challenge by the Federal Trade Commission to Microsoft’s $69</em><em> </em><em>billion acquisition of Activision Blizzard, the developer of </em><em>“</em><em>Call of Duty.</em><em>”</em><em> A three</em><em>‑</em><em>judge panel unanimously upheld a lower court</em><em>’</em><em>s decision denying a preliminary injunction, finding that the FTC had not demonstrated a likelihood of success in proving the merger would harm competition. The acquisition, completed in late</em><em> </em><em>2023 following UK regulatory approval, is the largest ever in the video gaming industry.”<br /></em>(Source: adapted from <a href="https://www.reuters.com/legal/microsoft-wins-ftc-appeal-challenging-69-bln-activision-blizzard-deal-2025-05-07/">Reuters, 2025</a>).</p>
<p>Zodra de informatie is geëxtraheerd, is dit een voorbeeld van een graph die op basis van deze tekst kan worden gemaakt:</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/09/Full_Extracted_KG.png"><img loading="lazy" decoding="async" width="1024" height="537" src="/wp-content/uploads/2025/09/Full_Extracted_KG-1024x537.png" alt="" class="wp-image-23761" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-1024x537.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-300x157.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-768x402.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG.png 1330w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 6: Voorbeeld van extractie uit een tekst</figcaption></figure>



<p>Dit type extractie kan op veel verschillende manieren worden uitgevoerd. Het volgende deel is speciaal gewijd aan de verschillende benaderingen om een volledige extractie uit te voeren, en aan de voor- en nadelen daarvan.</p>



<h2 class="wp-block-heading">Welke benaderingen zijn er voor het extraheren van entiteiten en relaties?</h2>



<h3 class="wp-block-heading">Handmatige extractie versus speciale tools</h3>



<p>Een dergelijke graph kan manueel worden opgebouwd volgens de techniek die in het vorige deel werd voorgesteld (een prompt met instructies en de chunk naar de LLM sturen, de gestructureerde output ophalen en ontleden, en vervolgens de graph bijwerken via queries), ofwel biedt LangChain een tool aan om deze verschillende taken te automatiseren via de <a href="https://python.langchain.com/api_reference/experimental/graph_transformers/langchain_experimental.graph_transformers.llm.LLMGraphTransformer.html">LLM Graph Transformer</a>.</p>
<p>Deze tool vereenvoudigt de procedure door de instructies aan de LLM, het opstellen van de template en de verwerking van de gestructureerde output voor zijn rekening te nemen. De tool biedt verschillende instelmogelijkheden, zoals de mogelijkheid om de soorten nodes die gedetecteerd moeten worden te beperken (bv. alleen nodes van het type “Person”, “Company” en “Location”), de soorten relaties te beperken of de instructieprompt aan te passen.</p>
<p>Bovendien geeft een <code>LLMGraphTransformer</code>-instantie een lijst terug met objecten van het type <code>GraphDocument</code>, die de gedetecteerde nodes en relaties bevat en die direct kan worden gebruikt door verschillende LangChain-drivers naar graph-gerichte databases (zoals Memgraph, TigerGraph, Neo4j, enz.), om de geëxtraheerde entiteiten en relaties direct in de graph te importeren.</p>
<p>Hieronder volgt een voorbeeld van het extraheren van data uit een lijst met chunks met behulp van de <code>LLMGraphTransformer</code>-tool, gevolgd door het importeren van de entiteiten en relaties naar Neo4j:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>doc_transformer=LLMGraphTransformer(llm=llm)
graph_docs=doc_transformer.convert_to_graph_documents(listOfChunks)

from langchain_neo4j import Neo4jGraph
graph=Neo4jGraph(
    url='XXXXX',
    username='YYYYY',
    password='ZZZZZ'
)
graph.add_graph_documents(graph_docs)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #000000">doc_transformer=LLMGraphTransformer(</span><span style="color: #001080">llm</span><span style="color: #000000">=llm)</span></span>
<span class="line"><span style="color: #000000">graph_docs=doc_transformer.convert_to_graph_documents(listOfChunks)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> langchain_neo4j </span><span style="color: #AF00DB">import</span><span style="color: #000000"> Neo4jGraph</span></span>
<span class="line"><span style="color: #000000">graph=Neo4jGraph(</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">url</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;XXXXX&#39;</span><span style="color: #000000">,</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">username</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;YYYYY&#39;</span><span style="color: #000000">,</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">password</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;ZZZZZ&#39;</span></span>
<span class="line"><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">graph.add_graph_documents(graph_docs)</span></span></code></pre></div>



<p><br />Er bestaat ook een gratis alternatief voor Neo4j, waarvoor geen programmering nodig is: de <a href="https://llm-graph-builder.neo4jlabs.com/">Neo4j LLM Knowledge Graph Builder</a>. Deze online tool neemt alle stappen voor zijn rekening, van de voorbewerking van documenten (pdf, webpagina) tot de opbouw van de resulterende knowledge graphs, en biedt tal van personaliseringsopties (het beperken van de te detecteren entiteit- en/of relatietypes, enz.). Zie <a href="https://neo4j.com/labs/genai-ecosystem/llm-graph-builder/">hier</a> voor meer details.</p>



<h3 class="wp-block-heading">Vrije extractie versus begeleide extractie</h3>



<p>Merk op dat als er met deze tools geen beperkingen (op de soorten entiteiten en relaties die moeten worden geëxtraheerd) worden gedefinieerd, ze in alle vrijheid alle informatie zullen extraheren die ze kunnen vinden. Dit soort “blinde” extractie kan eventueel worden gebruikt voor kleine documenten, of in gevallen waarin men van tevoren niet weet wat voor soort structuur men kan extraheren, maar het is over het algemeen beter om van tevoren de gewenste ontologie voor de graph vast te leggen.</p>
<p>Vrije extractie is namelijk vaak een probleem om verschillende redenen:</p>
<p><strong>Explosie van entiteitstypen en relaties </strong></p>
<p>Naarmate de omvang of het aantal documenten toeneemt, bestaat het risico dat er al snel een zeer groot aantal verschillende soorten entiteiten en relaties in de graph terechtkomen, waardoor deze moeilijk te gebruiken kan worden (bijvoorbeeld voor RAG-toepassingen).</p>
<p><strong>Inconsistentie van types</strong></p>
<p>Bij gebrek aan een ontologie die een duidelijke nomenclatuur biedt, bestaat het risico van inconsistentie in de gedetecteerde types (een bedrijf kan bijvoorbeeld worden gelabeld als “Enterprise”, een ander als “Company” en een derde als “Organization”). In de praktijk kunnen dit soort problemen achteraf worden opgelost door alle soorten nodes op te sommen en semantisch verwante soorten te groeperen.</p>
<p><strong>Problemen met reïficatie</strong></p>
<p>Per definitie verbindt een relatie in een graph een node met een ander node. Er kan een probleem ontstaan wanneer een entiteit moet worden gekoppeld aan informatie die in de vorm van een relatie is gemodelleerd. Om het probleem te illustreren, nemen we als voorbeeld de overname van Activision Blizzard door Microsoft. Stel dat een eerste stuk tekst alleen deze overname vermeldt zonder verdere details, dan wordt deze hoogstwaarschijnlijk opgeslagen in de vorm:</p>
<p><code>(Microsoft)-[ACQUIRES]-&gt;(Activision Blizzard)</code></p>
<p>Stel dat de volgende chunk de informatie “<em>The FTC challenged the acquisition&#8230;</em>” vermeldt, dan hebben we een probleem omdat het niet meer mogelijk is om</p>
<p><code>(FTC)-[CHALLENGES]-&gt;(Acquisition)</code></p>
<p>te modelleren, aangezien de overname eerder werd gemodelleerd in de vorm van een relatie en niet als een node waarnaar door een relatie kan worden verwezen.</p>
<p>In dit geval kan de relatie bijvoorbeeld worden verwijderd en vervolgens worden vervangen door een node, zodat ernaar kan worden verwezen:</p>
<p><code>(Microsoft)-[INITIATES]-&gt;(Acquisition)-[TARGETS]-&gt;(Activision Blizzard)</code></p>
<p>Dit proces, dat <strong>reïficatie</strong> wordt genoemd, verloopt niet automatisch en vereist een extra verrijkingsstap om mogelijke verwijzingen naar informatie die in de vorm van relaties is gemodelleerd, op te sporen en indien nodig te reïficeren.</p>



<h2 class="wp-block-heading">Enkele alternatieven voor LLM&#8217;s</h2>



<p>Nu we een reeks benaderingen hebben bekeken die specifiek op LLM&#8217;s zijn gebaseerd, worden in dit gedeelte enkele alternatieve tools voorgesteld die zijn gebaseerd op klassieke NLP-methoden.</p>
<p>Voor wie alleen <em>named entities</em> wil extraheren, is <a href="/named-entity-recognition-une-application-du-nlp-utile/">hier een blogpost over dit onderwerp</a> te vinden, evenals een <a href="/pii-filtering/">voorbeeld van de toepassing van NER bij PII-filtering</a>.  Er zijn tal van vooraf getrainde NER-modellen beschikbaar op platforms zoals <a href="https://huggingface.co/models">Hugging Face</a>.</p>
<p>Het extraheren van entiteiten en relaties kan doorgaans op twee verschillende manieren gebeuren:</p>



<ul class="wp-block-list">
<li><strong>Extractie in twee afzonderlijke stappen</strong>: eerst wordt een NER gebruikt voor het detecteren en categoriseren van entiteiten, gevolgd door een extractie van relaties op basis van de tekst en de gedetecteerde entiteiten, om de relaties tussen deze entiteiten te bepalen. Enkele voorbeelden van tools voor het extraheren van relaties zijn <a href="https://github.com/thunlp/OpenNRE">openNRE</a>, <a href="https://github.com/alimirzaei/spacy-relation-extraction">spacy-relation-extraction</a> en <a href="https://github.com/jackboyla/GLiREL">GliREL</a>.</li>



<li><strong>End-to-end-extractie</strong>: tools die entiteiten en relaties in één stap extraheren, zoals <a href="https://nlp.stanford.edu/software/openie.html">OpenIE</a>, <a href="https://github.com/SapienzaNLP/relik">Relik</a>, <a href="https://github.com/Babelscape/rebel">REBEL</a> of <a href="https://www.diffbot.com/products/natural-language/">Diffbot</a> (commerciële oplossing).</li>
</ul>



<h2 class="wp-block-heading">Nagaan of de gedetecteerde gegevens conform zijn</h2>



<p>De grote kracht van LLM&#8217;s voor dit soort extractietaken is hun begrip van natuurlijke taal, waardoor de extractie kan worden gepersonaliseerd door de instructieprompt aan te passen. Als er bijvoorbeeld geen outputtemplate bestaat voor het gestructureerde antwoord (waar de LLM moeite mee kan hebben als de template te ingewikkeld wordt), is het mogelijk om ontologieconforme nodes en relaties te verkrijgen door de ontologie rechtstreeks in de instructieprompt te beschrijven, maar het is belangrijk om alert te blijven voor extracties. Er is namelijk geen garantie dat de LLM geen fouten maakt en geen niet-conforme relatie/entiteit als output teruggeeft.</p>
<p>In het algemeen geldt dat wanneer een LLM (of een andere tool) wordt gebruikt om automatisch informatie uit een tekst te extraheren naar een knowledge graph, het nuttig is om te controleren of datgene dat is geëxtraheerd wel degelijk in overeenstemming is met de ontologie en trouw is aan de informatie in de bron.</p>
<ol>
<li>Controleren of de extractie voldoet aan de ontologie</li>
</ol>
<p><a href="/shacl-logische-en-vormcontroles-met-kg-technologieen/">In een vorige blogpost</a> hebben we al vermeld dat het mogelijk is om de structuur en inhoud van een knowledge graph te valideren met behulp van de SHACL-standaard. Dit is een taal die de verschillende beperkingen bevat die van toepassing zijn op een knowledge graph. Het is mogelijk om ofwel een definitieve validatie van de graph uit te voeren, om te controleren of de inhoud daadwerkelijk voldoet aan de in SHACL geformuleerde beperkingen (en de data die deze beperkingen overtreden op te sommen), ofwel deze validaties transactioneel uit te voeren bij elke nieuwe toevoeging van informatie, om elke nieuwe onrechtmatige toevoeging te weigeren. Hoewel SHACL oorspronkelijk bedoeld was voor graphs in RDF, kunnen sommige databases toch SHACL-beperkingen interpreteren en de graph valideren, zoals <a href="https://neo4j.com/labs/neosemantics/">Neo4j met het <em>neosemantics</em> package (n10s)</a>.</p>
<ol start="2">
<li>Nagaan of de extractie correct is</li>
</ol>
<p>Het risico van automatische extractie is dat informatie die in de graph wordt ingevoerd feitelijk onjuist is ten opzichte van de oorspronkelijke tekst, wat in het bijzonder problematisch kan zijn als deze graph wordt gebruikt als potentiële informatiebron (bijvoorbeeld voor een graphRAG-toepassing). Er kunnen verschillende benaderingen worden gevolgd. De eenvoudigste is een menselijke controle van de geëxtraheerde informatie, maar dit kan moeilijk of zelfs onhaalbaar worden wanneer de documenten te lang/talrijk worden. De andere aanpak bestaat erin een tweede LLM te gebruiken om te controleren wat uit elk fragment is geëxtraheerd. Zoals we <a href="/praktische-ervaringen-met-automatische-rag-evaluatie/">in de post over de evaluatie van LLM&#8217;s</a> hebben vermeld, is het voor LLM&#8217;s gemakkelijker om achteraf fouten op te sporen dan ze te vermijden.</p>



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



<p>Deze technologieën zijn weliswaar krachtig, maar nooit perfect. Behalve vrije (blinde) extractie, die kan resulteren in een moeilijk bruikbare graph, vormt het opstellen van een knowledge graph op basis van tekst een taak die veel werk vereist. En dit zowel vooraf (voorbewerking van teksten, opstellen van een ontologie voor de graph op basis van de inhoud van de tekst), als achteraf (validatie van de structuur van de graph ten opzichte van de ontologie en controle van de juistheid en betrouwbaarheid van de inhoud).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><em>Dit is een ingezonden bijdrage van Pierre Leleux, data scientist et network data analyst bij Smals Research. Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Ingestion de données non-structurées&#160;: comment créer un graphe automatiquement à partir de texte&#160;?</title>
		<link>https://www.smalsresearch.be/ingestion-donnees-non-structurees-vers-graphe/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Thu, 11 Sep 2025 09:00:00 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[data ingestion]]></category>
		<category><![CDATA[Knowledge Graph]]></category>
		<category><![CDATA[Large Language Model]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<guid isPermaLink="false">/?p=23748</guid>

					<description><![CDATA[Cet article s’intéresse aux façons dont une représentation graphe peut être obtenue à partir de données textuelles, les différents types de graphe qui peuvent être extraits, et les outils fréquemment utilisés.]]></description>
										<content:encoded><![CDATA[
<p><em><a href="/ingestion-van-ongestructureerde-data-graph/">Nederlandstalige versie</a></em></p>
<p>Les graphes, et plus particulièrement les graphes de connaissances, permettent de <a href="/graphes_applications_et_outils_2/">représenter l’information de manière structurée</a>. Cela permet, pour un humain, d’avoir une représentation (synthèse visuelle) du contenu d’un ou de plusieurs documents et, pour une machine, d’exploiter cette structure afin, par exemple, d’en analyser le contenu (via l’utilisation <a href="/graphes_applications_et_outils/">d’algorithmes de graphe</a>) et/ou de raisonner sur le graphe (par exemple dans le cadre d’une <a href="/graphrag-vers-une-generation-augmentee-par-les-graphes-de-connaissances/">application de graphRAG</a> ou pour découvrir (inférer) de l’information implicite).</p>
<p>Cet article s’intéresse aux façons dont une représentation graphe peut être obtenue à partir de données textuelles, les différents types de graphe qui peuvent être extraits, et les outils fréquemment utilisés suivant le type d’extraction que l’on souhaite effectuer.</p>
<p>Il est à noter que, puisque les grands modèles de langage (LLM) sont particulièrement adaptés pour le traitement de texte, cet article se concentrera principalement sur la présentation d’approches basées sur les LLM et discutera rapidement, dans un second temps, de différentes approches alternatives.</p>



<h2 class="wp-block-heading">Les graphes de connaissances&nbsp;: un rappel rapide</h2>



<p>Un graphe est une structure composée d’un ensemble de nœuds et d’arcs (qui lient des paires de nœuds). Un graphe de connaissances ajoute une couche sémantique supplémentaire à un graphe classique, où chaque nœud représente un concept (entité, personne, etc.) et chaque arc représente une relation entre deux concepts (« travaille pour », « est ami avec », etc.). Il s’agit donc d’une représentation de la connaissance sous forme d’un ensemble d’entités interconnectées. Plus de détails sur les différentes formes de graphes et les outils associés peuvent être trouvés <a href="/graphes_applications_et_outils/">ici</a>.</p>



<h2 class="wp-block-heading">Préparation du corpus de documents</h2>



<p>Il est à noter que, pour des raisons de simplicité, nous faisons l’hypothèse que les documents de texte utilisés pour construire le graphe ont été correctement nettoyés. En effet, cet article n’a pas pour but de discuter de l’aspect relatif au prétraitement des documents de texte (scrapping de pages web, extraction de texte à partir de fichiers pdf, etc.), car ce prétraitement est déjà, en tant que tel, un vaste sujet méritant sans doute un article dédié.</p>



<h3 class="wp-block-heading">Fragmentation du texte en « chunks »</h3>



<p>Une étape importante de la préparation des données de texte avant d’en extraire les entités et relations est la division du texte en fragments (généralement appelés « chunks »). Nous avons déjà mentionné le concept de chunking à plusieurs reprises dans <a href="/ingestion-de-donnees-pour-les-applications-d-ia-generative/">de précédents articles</a>. Si un document est trop long (plus de quelques paragraphes…) il convient de le séparer en chunks (fragments de texte de taille raisonnable) qui seront traités un à un par le LLM. Cette procédure permet de limiter la quantité d’information présente dans chaque chunk, pour éviter que celui-ci ne contienne une quantité trop importante d’entités et de relations à extraire. Cette séparation en chunks peut se faire de différentes manières, soit sur la base du nombre de mots dans le chunk, soit sur la base d’un séparateur prédéfini (par exemple&nbsp;: un passage à la ligne qui indiquerait la fin du paragraphe).</p>



<h2 class="wp-block-heading">Représenter l’information ou représenter la structure</h2>



<p>Commençons par regarder les deux principaux types de graphe qui peuvent être construits à partir d’un ensemble de documents textuels.</p>
<p>Le premier est un graphe qui va présenter la structure du document (<em>document structure graph</em>), et non pas l’information qui est contenue dans le texte. Par exemple, en reliant les chunks au document d’où ils sont tirés ainsi que l’ordre d’apparition de ceux-ci dans le document&nbsp;:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Document_structure_graph.png"><img loading="lazy" decoding="async" width="939" height="527" src="/wp-content/uploads/2025/09/Document_structure_graph.png" alt="" class="wp-image-23750" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph.png 939w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph-300x168.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Document_structure_graph-768x431.png 768w" sizes="auto, (max-width: 939px) 100vw, 939px" /></a><figcaption class="wp-element-caption">Figure 1&nbsp;: Graphe représentant la structure d’un document simple</figcaption></figure>



<p>Ce type de graphe peut aussi être enrichi en ajoutant des relations entre chunks sémantiquement similaires ou, le cas échéant, en représentant l’organisation hiérarchique du document en sections, sous-sections, etc. Cela se fait via des nœuds représentant les sections/sous-sections et des relations de type « HAS_SECTION », « HAS_SUBSECTION », ainsi que des relations indiquant l’ordre des sections/sous-sections. Une fois le graphe construit, il peut par exemple être utilisé dans des applications de RAG à des fins d’indexation pour fournir du contexte aux chunks utilisés (voir <a href="/graphrag-vers-une-generation-augmentee-par-les-graphes-de-connaissances/">notre article sur le graphRAG</a>).</p>
<p>Le second type de graphe consiste à capturer l’information contenue dans les documents sous la forme de nœuds et de relations :</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Domain_graph.png"><img loading="lazy" decoding="async" width="877" height="179" src="/wp-content/uploads/2025/09/Domain_graph.png" alt="" class="wp-image-23751" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph.png 877w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph-300x61.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Domain_graph-768x157.png 768w" sizes="auto, (max-width: 877px) 100vw, 877px" /></a><figcaption class="wp-element-caption">Figure 2&nbsp;: Exemple d&#8217;extraction d&#8217;informations</figcaption></figure>



<p>Dans le cadre de cet article, nous nous concentrerons sur ce second type de graphe. Il est à noter que les deux approches ne sont pas mutuellement exclusives. D’ailleurs, il est souvent utile, si l&#8217;on souhaite opter pour le deuxième type de graphe, de représenter également la structure des documents. Cela permet, si nécessaire, de pouvoir remonter à la source des informations présentes dans le graphe.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Graph_combined.png"><img loading="lazy" decoding="async" width="896" height="674" src="/wp-content/uploads/2025/09/Graph_combined.png" alt="" class="wp-image-23754" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined.png 896w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined-300x226.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Graph_combined-768x578.png 768w" sizes="auto, (max-width: 896px) 100vw, 896px" /></a><figcaption class="wp-element-caption">Figure 3&nbsp;: Extraction de structure et d&#8217;informations</figcaption></figure>



<h2 class="wp-block-heading">Construction d’un graphe de connaissances à l’aide d’un LLM</h2>



<p>Dans un premier temps, nous allons présenter la procédure générale à suivre pour la création d’un graphe de connaissances à partir de documents textuels via LLM, avant de voir comment l’adapter suivant ses besoins.</p>
<p>Les LLMs, par défaut, reçoivent en entrée du texte (prompt) et renvoient en sortie du texte généré en réponse au prompt. Cependant, suivant les instructions, les LLM offrent la possibilité de générer des <strong><em>outputs structurés</em></strong> tels que des fichiers JSON. C’est souvent sur la base de cette fonctionnalité que se base l’extraction de connaissances vers un graphe, car cet output structuré pourra être traité de façon systématique.</p>
<p>Un script (par ex. python) va récupérer les chunks et les envoyer un à un au LLM en imposant une réponse structurée (par ex. <a href="https://python.langchain.com/docs/how_to/structured_output/">langchain avec la méthode llm.with_structured_output()</a>), avec des instructions concernant la tâche, le genre d’information à détecter dans le texte, et la structure de la réponse attendue en sortie. L’output structuré (typiquement en JSON) est ensuite simplement décomposé en python afin de récupérer les informations (nœuds/relations) détectées par le LLM, qui peuvent ensuite être directement ajoutées au graphe (via un database driver).</p>
<p>Il est intéressant de noter que les LLM peuvent fournir une grande diversité de réponses, et l’utilisation d’une sortie structurée n’est pas forcément toujours nécessaire. Dans certains cas, le plus simple est encore de demander au LLM de fournir ses extractions sous la forme de requêtes (par exemple, de requêtes qui ajoutent directement les nœuds/relations détectées), qui peuvent être exécutées telles quelles, ou sous forme de triplets RDF.</p>
<p>Maintenant que nous avons vu la procédure générale, nous allons regarder plus en détail les différentes façons d’extraire et de représenter l’information contenue dans les chunks au sein d’un graphe, en commençant par l’approche la plus simple (extraction de thèmes) jusqu’à la plus complète (extraction d’entités et de relations).</p>



<h3 class="wp-block-heading">Extraction thématique</h3>



<p>Dans cette première approche, on va s’intéresser à la détection et l’extraction des thèmes abordés dans le document. On y construit donc une représentation thématique des différents documents du corpus de sorte à obtenir une structure de type&nbsp;:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Theme_extraction.png"><img loading="lazy" decoding="async" width="872" height="178" src="/wp-content/uploads/2025/09/Theme_extraction.png" alt="" class="wp-image-23756" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction.png 872w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction-300x61.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Theme_extraction-768x157.png 768w" sizes="auto, (max-width: 872px) 100vw, 872px" /></a><figcaption class="wp-element-caption">Figure 4&nbsp;: Schéma d’ontologie d’une extraction de thèmes</figcaption></figure>



<p>Le graphe a donc une structure légère et est utilisé à des fins de référencement, afin d&#8217;identifier facilement et rapidement les documents traitant d&#8217;un (ou plusieurs) sujet(s) d&#8217;intérêt donné(s). Ce type de graphe permet aussi d’établir des similarités entre documents (ou entre chunks) sur la base des sujets qu’ils ont en commun, ou simplement d’avoir une représentation schématique du corpus de documents et des thèmes qui y sont abordés.</p>
<p>Cela peut se faire soit de façon non-dirigée (laisser le LLM déterminer librement de la liste des thèmes abordés dans le chunk), soit dirigée (le LLM choisit un ou plusieurs thèmes parmi une liste prédéfinie de thèmes fournie dans les instructions du prompt).</p>



<h3 class="wp-block-heading">Extraction d’entités nommées</h3>



<p>L’extraction (ou reconnaissance) d’entités nommées (<em>named-entity recognition</em>, souvent abrégé en NER) est un domaine bien connu du traitement du langage naturel (<em>natural language processing</em> (NLP)) qui consiste à détecter et catégoriser les entités (personne, organisation, lieu, etc.) qui sont nommées dans un texte. L’objectif va donc être similaire à celui de l’extraction thématique&nbsp;: créer un graphe en liant les chunks de texte aux entités qui y sont mentionnées. Nous obtenons donc un graphe avec le schéma-type suivant&nbsp;:</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/09/Entity_extraction.png"><img loading="lazy" decoding="async" width="877" height="176" src="/wp-content/uploads/2025/09/Entity_extraction.png" alt="" class="wp-image-23752" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction.png 877w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction-300x60.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Entity_extraction-768x154.png 768w" sizes="auto, (max-width: 877px) 100vw, 877px" /></a><figcaption class="wp-element-caption">Figure 5&nbsp;: Schéma d’ontologie d’une extraction d’entités nommées</figcaption></figure>



<p>Ce type de graphe permet aussi d’établir des similarités entre documents (ou entre chunks) sur la base des entités qu’ils ont en commun. Il est intéressant de noter que cette extraction est similaire à une extraction complète (incluant entités et relations, voir section ci-dessous), si ce n’est qu’ici seules les entités sont extraites, et pas les relations qui les interconnectent. Il s’agit d’une solution plus légère et facile à mettre en place, lorsqu’une extraction complète n’est pas nécessaire.</p>
<p>Ce genre d’extraction peut se faire facilement par l’utilisation de LLM avec outputs structurés. Le package <code>pydantic</code> permet de créer des templates sur mesure pour la structure attendue en sortie. Par exemple&nbsp;:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from pydantic import BaseModel, Field
from typing import List
class Entity(BaseModel):
    category: str = Field(description="The category of the entity.")
    name: str = Field(description="The name of the entity.")
class Extraction(BaseModel):
    entityList: List&#91;Entity&#93; = Field(description="The list of extracted entities.")
structured_llm = llm.with_structured_output(Extraction)
extracted=structured_llm.invoke(myPrompt)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> pydantic </span><span style="color: #AF00DB">import</span><span style="color: #000000"> BaseModel, Field</span></span>
<span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> typing </span><span style="color: #AF00DB">import</span><span style="color: #000000"> List</span></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">Entity</span><span style="color: #000000">(</span><span style="color: #267F99">BaseModel</span><span style="color: #000000">):</span></span>
<span class="line"><span style="color: #000000">    category: </span><span style="color: #267F99">str</span><span style="color: #000000"> = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The category of the entity.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">    name: </span><span style="color: #267F99">str</span><span style="color: #000000"> = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The name of the entity.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #0000FF">class</span><span style="color: #000000"> </span><span style="color: #267F99">Extraction</span><span style="color: #000000">(</span><span style="color: #267F99">BaseModel</span><span style="color: #000000">):</span></span>
<span class="line"><span style="color: #000000">    entityList: List&#91;Entity&#93; = Field(</span><span style="color: #001080">description</span><span style="color: #000000">=</span><span style="color: #A31515">&quot;The list of extracted entities.&quot;</span><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">structured_llm = llm.with_structured_output(Extraction)</span></span>
<span class="line"><span style="color: #000000">extracted=structured_llm.invoke(myPrompt)</span></span></code></pre></div>



<p><br />Dans cet exemple simple, on demande au LLM de retourner une sortie structurée de type « Extraction », avec comme attribut « entityList » qui est une liste d’objets « Entity » définis juste avant.</p>
<p>Il est intéressant de noter que ce type de template peut être enrichi si l’on souhaite extraire des informations supplémentaires ou contraindre le type d’entités détectées. Par exemple, si l’on souhaite uniquement détecter des entités de type « personne » et « entreprise », le template peut être modifié en créant des classes « Personne » et « Entreprise », dans lesquelles on listera les attributs que l’on souhaite extraire pour chaque instance de ces entités, et en remplaçant le champs « entityList » par deux champs « personList » et « enterpriseList » dans l’objet final à retourner.</p>
<p>L’avantage d’utiliser la méthode <code>with_structured_output</code> est que langchain vérifiera automatiquement que la sortie du LLM est bien conforme au template.</p>



<h3 class="wp-block-heading">Extraction d’entités et de relations</h3>



<p>L’objectif ici est la construction d’un graphe qui va représenter la connaissance contenue au sein du ou des documents sous la forme d’entités (nœuds) interconnectées (relations). Il s’agit de la tâche la plus complète (et la plus compliquée), sur laquelle nous allons nous pencher le plus en détail.</p>
<p>Prenons le chunk de texte suivant, afin d’illustrer le genre d’extraction que nous souhaitons réaliser ici :</p>
<p><em>“The San Fransisco-based 9th U.S. Circuit Court of Appeals rejected the legal challenge by the Federal Trade Commission to Microsoft’s $69</em><em> </em><em>billion acquisition of Activision Blizzard, the developer of </em><em>“</em><em>Call of Duty.</em><em>”</em><em> A three</em><em>‑</em><em>judge panel unanimously upheld a lower court</em><em>’</em><em>s decision denying a preliminary injunction, finding that the FTC had not demonstrated a likelihood of success in proving the merger would harm competition. The acquisition, completed in late</em><em> </em><em>2023 following UK regulatory approval, is the largest ever in the video gaming industry.”<br /></em>(Source: adapted from <a href="https://www.reuters.com/legal/microsoft-wins-ftc-appeal-challenging-69-bln-activision-blizzard-deal-2025-05-07/">Reuters, 2025</a>).</p>
<p>Une fois l’information extraite, voici un exemple de graphe qu’il est possible de construire depuis ce texte :</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/09/Full_Extracted_KG.png"><img loading="lazy" decoding="async" width="1024" height="537" src="/wp-content/uploads/2025/09/Full_Extracted_KG-1024x537.png" alt="" class="wp-image-23761" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-1024x537.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-300x157.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG-768x402.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/09/Full_Extracted_KG.png 1330w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figure 6&nbsp;: Exemple d’extraction depuis un texte</figcaption></figure>



<p>Ce type d’extraction peut se faire de nombreuses façons différentes. La prochaine section sera spécialement dédiée aux différentes approches qui peuvent être adoptées pour réaliser une extraction complète, leurs avantages et inconvénients.</p>



<h2 class="wp-block-heading">Quelles approches pour réaliser une extraction d’entités et de relations&nbsp;?</h2>



<h3 class="wp-block-heading">Extraction manuelle VS outils dédiés</h3>



<p>La construction d’un graphe de ce type peut se faire de manière manuelle en suivant la technique présentée dans la section précédente (envoyer un prompt incluant les instructions et le chunk au LLM, récupérer et décomposer l’output structuré renvoyé en sortie, puis mettre à jour le graphe via requêtes), ou alors langchain propose un outil permettant d’automatiser ces différentes tâches via le <a href="https://python.langchain.com/api_reference/experimental/graph_transformers/langchain_experimental.graph_transformers.llm.LLMGraphTransformer.html">LLM Graph Transformer</a>.</p>
<p>Cet outil permet de simplifier la procédure, en prenant en charge les instructions au LLM, la construction du template et le traitement de la sortie structurée. Il offre plusieurs possibilités de personnalisation, comme la possibilité de restreindre les types de nœud que l’on souhaite détecter (par ex. uniquement des nœuds de type « Person », « Company » et « Location »), de restreindre les types de relation, ou encore de personnaliser le prompt d’instructions.</p>
<p>De plus, une instance <code>LLMGraphTransformer</code> renvoie en sortie liste d’objets de type <code>GraphDocument</code>, contenant les nœuds et relations détectés, qui est exploitable directement par plusieurs drivers langchain vers des bases de données orientées graphe (telles que Memgraph, TigerGraph, Neo4j, etc.), afin de réaliser directement l’importation des entités et relations extraites vers le graphe.</p>
<p>Ci-dessous, un exemple illustratif de l’extraction des données depuis une liste de chunks via l’outil <code>LLMGraphTransformer</code>, suivie de l’importation des entités et relations vers Neo4j&nbsp;:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>doc_transformer=LLMGraphTransformer(llm=llm)
graph_docs=doc_transformer.convert_to_graph_documents(listOfChunks)

from langchain_neo4j import Neo4jGraph
graph=Neo4jGraph(
    url='XXXXX',
    username='YYYYY',
    password='ZZZZZ'
)
graph.add_graph_documents(graph_docs)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #000000">doc_transformer=LLMGraphTransformer(</span><span style="color: #001080">llm</span><span style="color: #000000">=llm)</span></span>
<span class="line"><span style="color: #000000">graph_docs=doc_transformer.convert_to_graph_documents(listOfChunks)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #AF00DB">from</span><span style="color: #000000"> langchain_neo4j </span><span style="color: #AF00DB">import</span><span style="color: #000000"> Neo4jGraph</span></span>
<span class="line"><span style="color: #000000">graph=Neo4jGraph(</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">url</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;XXXXX&#39;</span><span style="color: #000000">,</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">username</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;YYYYY&#39;</span><span style="color: #000000">,</span></span>
<span class="line"><span style="color: #000000">    </span><span style="color: #001080">password</span><span style="color: #000000">=</span><span style="color: #A31515">&#39;ZZZZZ&#39;</span></span>
<span class="line"><span style="color: #000000">)</span></span>
<span class="line"><span style="color: #000000">graph.add_graph_documents(graph_docs)</span></span></code></pre></div>



<p><br />Il existe aussi une alternative gratuite pour Neo4j, qui ne requiert aucune programmation, le <a href="https://llm-graph-builder.neo4jlabs.com/">Neo4j LLM Knowledge Graph Builder</a>. Cet outil en ligne prend toutes les étapes en charge, en allant du prétraitement des documents (pdf, page web) jusqu’à la construction du graphe de connaissances résultant, et offre de multiples options de personnalisation (contraindre les types d’entité et/ou de relation à détecter, etc.). Voir <a href="https://neo4j.com/labs/genai-ecosystem/llm-graph-builder/">ici</a> pour plus de détails.</p>



<h3 class="wp-block-heading">Extraction libre VS extraction supervisée</h3>



<p>Il est à noter que si aucune contrainte (sur les types d’entité et de relation à extraire) n’est définie avec ces outils, ils vont librement extraire toutes les informations qu’ils peuvent trouver. Ce genre d’extraction « à l’aveugle » peut éventuellement être utilisée pour des petits documents, ou dans des cas où l’on ne sait pas à l’avance le genre de structure que l’on peut extraire, mais il est généralement préférable d’établir à l’avance l’ontologie que l’on souhaite adopter pour le graphe.</p>
<p>Une extraction libre est en effet souvent problématique pour plusieurs raisons :</p>
<p><strong>Explosion des types d’entité et de relation </strong></p>
<p>Lorsque la taille ou le nombre de documents augmente, l&#8217;on risque rapidement de se retrouver avec un très grand nombre de types différents d’entités et de relations au sein du graphe, ce qui peut le rendre difficile à exploiter (par ex. pour des applications de RAG).</p>
<p><strong>Incohérence de types</strong></p>
<p>En l’absence d’une ontologie fournissant une nomenclature claire, il y a des risques d’incohérence dans les types détectés (par exemple, une entreprise pourra être labelisée comme « Enterprise », une autre comme « Company », et une troisième comme « Organization »). En pratique, ce genre de soucis peut potentiellement être réglé a posteriori en listant tous les types de nœud et en rassemblant les types sémantiquement proches.</p>
<p><strong>Soucis de réification</strong></p>
<p>Par définition, une relation dans un graphe relie un nœud à un autre nœud. Un souci peut émerger lorsqu’une entité doit se connecter à une information qui a été modélisée sous la forme d’une relation. Pour illustrer le problème, reprenons en guise d&#8217;exemple l’acquisition d’Activision Blizzard par Microsoft. Supposons qu&#8217;un premier chunk de texte mentionne simplement cette acquisition sans plus de détails, elle sera fort potentiellement enregistrée sous la forme&nbsp;:</p>
<p><code>(Microsoft)-[ACQUIRES]-&gt;(Activision Blizzard)</code></p>
<p>Si maintenant le chunk suivant mentionne l’information « <em>The FTC challenged the acquisition&#8230;</em> », nous avons un problème car il n’est plus possible de modéliser</p>
<p><code>(FTC)-[CHALLENGES]-&gt;(Acquisition)</code></p>
<p>puisque l’acquisition a été précédemment modélisée sous la forme d’une relation, et non d’un nœud pouvant être référencé par une relation.</p>
<p>Dans ce cas, la relation peut par exemple être supprimée puis remplacée par un nœud, afin de la rendre référençable :</p>
<p><code>(Microsoft)-[INITIATES]-&gt;(Acquisition)-[TARGETS]-&gt;(Activision Blizzard)</code></p>
<p>Ce processus, appelé <strong>réification</strong>, n’est pas automatique et demande l’ajout d’une étape d’enrichissement pour détecter de potentielles références à des informations modélisées sous forme de relations, et les réifier si nécessaire.</p>



<h2 class="wp-block-heading">Quelques alternatives aux LLM</h2>



<p>Maintenant que nous avons vu une série d’approches basées spécifiquement sur les LLM, cette section propose quelques outils alternatifs basés sur des méthodes de NLP classique.</p>
<p>Si l&#8217;objectif est uniquement de faire l’extraction d’entités nommées, vous pouvez trouver <a href="/named-entity-recognition-une-application-du-nlp-utile/">ici un article de blog dédié à ce sujet</a>, ainsi qu’un <a href="/pii-filtering-fr/">exemple d’application de NER en PII filtering</a>. Il existe de nombreux modèles de NER préentrainés disponibles sur des plateformes telles que <a href="https://huggingface.co/">Hugging Face</a>.</p>
<p>Concernant l’extraction d’entités et de relations, elle peut se faire typiquement de 2 façons distinctes&nbsp;:</p>



<ul class="wp-block-list">
<li><strong>L’extraction en 2 étapes séparées&nbsp;:</strong> l&#8217;on commence par l’utilisation d’un NER pour la détection et la catégorisation des entités, suivie d&#8217;une extraction de relations sur la base du texte et des entités détectées, afin de déterminer les relations entre ces dernières. Quelques exemples d’outils pour l’extraction de relations incluent <a href="https://github.com/thunlp/OpenNRE">openNRE</a>, <a href="https://github.com/alimirzaei/spacy-relation-extraction">spacy-relation-extraction</a> ou encore <a href="https://github.com/jackboyla/GLiREL">GliREL</a>.</li>



<li><strong>L’extraction conjointe (end-to-end) &nbsp;:</strong> il s’agit d’outils qui réalisent l’extraction d’entités et de relations en une seule étape, tels que <a href="https://nlp.stanford.edu/software/openie.html">OpenIE</a>, <a href="https://github.com/SapienzaNLP/relik">Relik</a>,&nbsp;<a href="https://github.com/Babelscape/rebel">REBEL</a> ou <a href="https://www.diffbot.com/products/natural-language/">Diffbot</a> (solution commerciale).</li>
</ul>



<h2 class="wp-block-heading">Vérifier la conformité de ce qui a été détecté</h2>



<p>La grande force des LLM pour ce genre de tâche d’extraction est leur compréhension du langage naturel, ce qui permet de personnaliser l’extraction en adaptant le prompt d’instructions. Par exemple, en l’absence de template de sortie pour la réponse structurée (que le LLM peut peiner à respecter si le template devient trop compliqué), il est possible d’obtenir des nœuds et relations conformes à l’ontologie en décrivant l’ontologie directement dans le prompt d’instructions, mais il est important de rester vigilant aux extractions. En effet, il n’y a aucune garantie que le LLM ne fasse pas d’erreur, et ne renvoie pas en sortie une relation/entité non-conforme.</p>
<p>De manière générale, lorsqu’un LLM (ou tout autre outil) est utilisé pour extraire de l’information de façon automatique depuis un texte vers un graphe de connaissances, il est utile de vérifier que ce qui a été extrait est bien conforme à l’ontologie et fidèle à l’information qui se trouve dans la source.</p>
<ol>
<li>Vérifier que l’extraction respecte l’ontologie</li>
</ol>
<p>Comme nous l’avons déjà mentionné dans un <a href="/shacl-logische-en-vormcontroles-met-kg-technologieen/">précédent article de blog</a>, il est possible de valider la structure et le contenu d’un graphe de connaissances à l’aide du standard SHACL. Il s’agit d’un langage qui va contenir les différentes contraintes qui s’appliquent sur un graphe de connaissances. Il est possible soit d’effectuer une validation finale du graphe, pour vérifier que le contenu respecte effectivement les contraintes énoncées en SHACL (et de lister les données qui violent ces contraintes), soit d’effectuer ces validations de façon transactionnelle à chaque nouvelle information qui est ajoutée, afin de refuser tout nouvel ajout illégal. Bien qu’initialement prévu pour des graphes en RDF, certaines bases de données peuvent tout de même interpréter des contraintes en SHACL et valider le graphe, comme <a href="https://neo4j.com/labs/neosemantics/">neo4j avec le package <em>neosemantics</em> (n10s)</a>.</p>
<ol start="2">
<li>Vérifier que l’extraction est correcte</li>
</ol>
<p>Le risque d’une extraction automatique est qu’une information introduite dans le graphe soit factuellement incorrecte vis-à-vis du texte d’origine, ce qui peut être particulièrement problématique si ce graphe est utilisé comme potentielle source d’information (par exemple pour une application de graphRAG). Plusieurs approches peuvent être suivies. La plus simple est une vérification humaine des informations extraites, mais cela peut devenir difficile, voire infaisable, lorsque les documents deviennent trop longs/nombreux. L’autre approche consiste à utiliser un second LLM afin de vérifier ce qui a été extrait de chaque chunk. Comme nous l’avons mentionné dans <a href="/experiences-pratiques-avec-levaluation-automatique-de-la-rag/">l’article d’évaluation de LLM</a>, il est plus facile, pour les LLM, de détecter les erreurs a posteriori que de les éviter.</p>



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



<p>Ces technologies, bien que performantes, ne sont jamais parfaites. Sauf extraction libre (à l’aveugle), mais qui risque d’aboutir à la création d’un graphe difficilement exploitable, la construction d’un graphe de connaissances à partir de texte est une tâche qui demande du travail, tant en amont (prétraitement des textes, établissement d’une ontologie pour le graphe sur la base du contenu du texte) qu’en aval (validation de la structure du graphe vis-à-vis de l’ontologie et vérification de la véracité et la fiabilité de son contenu).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><em>Ce post est une contribution individuelle de Pierre Leleux, data scientist et network data analyst chez Smals Research. Cet article est écrit en son nom propre et n’impacte en rien le point de vue de Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Ethiek en artificiële intelligentie: hoe een bias meten en corrigeren?</title>
		<link>https://www.smalsresearch.be/ethiek-en-artificiele-intelligentie-hoe-een-bias-meten-en-corrigeren/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Wed, 11 Jun 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[classification]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<guid isPermaLink="false">/?p=22871</guid>

					<description><![CDATA[Dit artikel gaat in op de manier waarop algoritmische bias kan worden gemeten en op de verschillende manieren om deze te corrigeren om eerlijke voorspellingen te genereren.]]></description>
										<content:encoded><![CDATA[
<p><em><a href="/ethique-et-intelligence-artificielle-comment-mesurer-et-corriger-un-biais/">Version en français</a></em></p>
<p>Artificiële intelligentie en machine learning spelen een steeds grotere rol in de menselijke samenleving ter ondersteuning van besluitvormingsprocessen. De aandacht naar hun eerlijkheid (fairness) is de afgelopen jaren dan ook steeds belangrijker geworden. Predictieve modellen kunnen namelijk problematisch worden wanneer ze biases (vooringenomenheden) die ze tijdens hun trainingsfase uit historische gegevens hebben geleerd, beginnen te reproduceren of versterken. Deze bias leidt vaak tot discriminatie van een of meer groepen individuen. Dit is vooral problematisch in het kader van gevoelige beslissingen, zoals het verwerken van sollicitaties, het toekennen van leningen of justitie. Dit artikel gaat in op de manier waarop deze algoritmische bias kan worden gemeten en op de verschillende manieren om deze te corrigeren om eerlijke voorspellingen te genereren.</p>
<p>Zoals we al in een <a href="/lethique-dans-lintelligence-artificielle/">eerdere blogpost</a> hebben besproken, kan een bias verschillende oorzaken hebben. Het kan bijvoorbeeld gaan om een designfout in het algoritme zelf, een ondervertegenwoordiging van een groep in de trainingsdata, of om historische data die bevooroordeeld is door racisme/seksisme in de samenleving [<a href="#footnote-1">1</a>]. In dit artikel richten we ons op het geval waarin het probleem bij de gegevens ligt en niet bij het model zelf, namelijk wanneer het model leert op basis van bevooroordeelde gegevens en deze vooringenomenheid vervolgens reproduceert in zijn voorspellingen.</p>
<p>Een van de bekendste voorbeelden is de COMPAS-case. Het COMPAS-algoritme werd gebruikt in de Verenigde Staten om het risico op recidive van gedetineerden in het kader van een mogelijke vervroegde vrijlating in te schatten. In 2016 stelde een <a href="https://www.propublica.org/article/how-we-analyzed-the-compas-recidivism-algorithm">studie van ProPublica</a> dat Afro-Amerikanen door het algoritme werden gediscrimineerd omdat ze meer kans hadden om als “<em>high-risk</em>” te worden geclassificeerd. De studie stelde meer bepaald dat een persoon met een donkere huidskleur meer kans had om ten onrechte als “<em>high-risk</em>” te worden geclassificeerd en dat een blanke daarentegen meer kans had om ten onrechte als “<em>low-risk</em>” te worden geclassificeerd. Deze zaak leidde tot een groot debat en de publicatie van honderden artikelen over dit onderwerp.</p>
<p>In het geval van COMPAS, lag het probleem niet bij het algoritme zelf, maar eerder bij de gegevens waarop het was getraind. Het model was namelijk getraind op historische strafrechtelijke gegevens die een systematische racistische vooringenomenheid weerspiegelen, zoals discriminerende politiepraktijken. Deze bevooroordeelde gegevens leidden er dus toe dat het model eveneens vooroordelen vertoonde in zijn voorspellingen.</p>



<h2 class="wp-block-heading">Hoe meet je de oneerlijkheid van een model?</h2>



<p>Problemen met fairness veronderstellen het bestaan van een zogenaamde<strong> gevoelige variabele</strong>. Dit is de variabele waarvoor men geen discriminatie wenst. Het kan bijvoorbeeld gaan om het geslacht of de etnische afkomst van een persoon. De gevoelige variabele is vaak <strong>categorisch</strong>, maar kan, afhankelijk van het geval, ook <strong>continu</strong> zijn (bijvoorbeeld de leeftijd van een persoon). Voor het gemak gaan we ervan uit dat er slechts een gevoelige variabele is, maar in sommige problemen kunnen er meerdere zijn.</p>
<p>Op basis van deze gevoelige variabele worden doorgaans twee groepen gedefinieerd. De groep die door het model negatief wordt gediscrimineerd, wordt de “beschermde groep” genoemd.</p>
<p>Stel dat we een predictief model hebben dat voorspellingen moet doen over het toekennen van een lening. Dit algoritme wordt als “eerlijk” beschouwd als de kans dat een persoon voor de lening wordt geselecteerd (positieve beslissing van het model) gelijk is, ongeacht de groep waartoe de persoon behoort. Wiskundig gezien willen we dus het volgende opleggen:</p>
<p>P(Y<sub>d</sub> = 1 | Z = 1) = P(Y<sub>d</sub> = 1 | Z = 0)</p>
<p>waarbij Y<sub>d</sub> de beslissing van het model is en Z een binaire variabele die aangeeft of een persoon al dan niet behoort tot de beschermde groep. Deze kansen worden berekend op groepsniveau, niet op individueel niveau.</p>
<p>Een bekende maatstaf voor algoritmische oneerlijkheid is dus gewoon het verschil tussen deze twee termen. Indien er een verschil is, betekent het dat het model een van de twee groepen bevoordeelt. Deze maatstaf voor het verschil tussen voorspellingen binnen de twee groepen wordt “<em>demographic parity</em>” of “<em>statistical parity</em>” genoemd.</p>
<p>Hoewel deze maatstaf relatief eenvoudig is, is dit een van de bekendste op het gebied van algoritmische rechtvaardigheid, die algemeen wordt erkend en gebruikt. Het is echter duidelijk niet de enige maatstaf die bestaat (voor enkele alternatieven, zie bijvoorbeeld [<a href="#footnote-2">2</a>, <a href="#footnote-3">3</a>]). Opgemerkt moet worden dat, aangezien demographic parity wordt gemeten op groepsniveau, het een maatstaf is voor groepsrechtvaardigheid (group fairness). Er bestaan ook alternatieve maatstaven op individueel niveau (individual fairness).</p>



<h2 class="wp-block-heading">Waarom wordt de gevoelige variabele niet gewoon uit het model verwijderd?</h2>



<p>Op het eerste gezicht lijkt het probleem eenvoudig op te lossen. Een voorspellend machine learning-model neemt gegevens X als input en voorspelt een variabele Y als output op basis van de gegevens in X. Het zou dus in principe voldoende zijn om de variabele Z niet op te nemen in de gegevens X, zodat de voorspellingen van het model niet meer worden beïnvloed door Z.</p>
<p>Helaas zijn de variabelen waaruit X bestaat in de praktijk zelden onafhankelijk van elkaar. De database X kan dus variabelen bevatten die gecorreleerd zijn met de gevoelige variabele, het model kan deze variabelen gebruiken als proxy van de gevoelige variabele en vertekende voorspellingen geven, ook al maakt Z niet expliciet deel uit van de gebruikte inputgegevens. Zo kan in een steekproef het inkomen van een persoon worden gebruikt als proxy voor zijn leeftijd, omdat het inkomen van personen doorgaans stijgt naarmate ze ouder worden.</p>
<p>In het geval van COMPAS werd de etnische afkomst van de gedetineerde bijvoorbeeld niet expliciet gebruikt in het model als variabele, maar door de aanwezigheid van gecorreleerde proxyvariabelen (bijv. postcode, sociaaleconomische indicatoren) werd de raciale vertekening altijd weerspiegeld in de voorspellingen van het model.</p>



<h2 class="wp-block-heading"><strong>Hoe een algoritmische bias in de praktijk corrigeren?</strong></h2>



<p>Er onderscheiden zich drie grote families van correcties: voorbewerking (“pre-processing”: het verwijderen van de bias uit de trainingsdata), verwerking (“in-processing”: het verwijderen van de bias tijdens het trainen van het model) en nabewerking (“post-processing”: het verwijderen van de bias uit een getraind model). Deze benaderingen hebben elk hun voor- en nadelen en zijn uitgebreid beschreven in tal van publicaties. De geïnteresseerde lezer kan de volgende survey raadplegen [<a href="#footnote-4">4</a>], waarin de verschillende publicaties op het gebied van fairness zijn verzameld en geordend per aanpak (pre-, in-, post-processing), per type algoritme (logistische regressie, random forest, neurale netwerken, enz.), per gebruikte fairness-maatstaf, enz. Dit biedt een goed gestructureerd overzicht van wat er op dit gebied wordt gedaan.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/05/Biased_Process.png"><img loading="lazy" decoding="async" width="1024" height="437" src="/wp-content/uploads/2025/05/Biased_Process-1024x437.png" alt="" class="wp-image-22699" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/05/Biased_Process-1024x437.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/05/Biased_Process-300x128.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/05/Biased_Process-768x328.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/05/Biased_Process.png 1056w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 1: Overzicht van een classificatieproces met een vooringenomenheid in de gegevens.</figcaption></figure>



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



<p>Het idee is eenvoudig: de trainingsgegevens ontdoen van vooringenomenheid om ze dichter bij de werkelijkheid te brengen, zodat de vooroordelen niet in het machine learning-model terechtkomen. Enkele voorbeelden van pre-processingsmethoden zijn:</p>



<ul class="wp-block-list">
<li>De steekproef (sampling) opnieuw in evenwicht brengen (door waarnemingen toe te voegen of te verwijderen);</li>



<li>De inhoud van bepaalde variabelen van data X corrigeren of zelfs volledig vervangen door nieuwe variabelen (<em>representational learning</em>) die geen gevoelige informatie bevatten;</li>



<li>Het label (variabele Y) van bepaalde waarnemingen wijzigen.</li>
</ul>



<p>Pre-processing biedt het voordeel dat het niet afhankelijk is van het gebruikte model en dat het doorgaans eenvoudig uit te leggen en te begrijpen is. Het correct corrigeren van historische gegevens kan echter ingewikkeld zijn en het is moeilijk om de fairness van het resulterende model te garanderen. Ook moet het risico van verlies aan nauwkeurigheid worden vermeld, aangezien het wijzigen van data mogelijk relevante patterns uit de data verwijdert.</p>
<p>Figuur 2 toont hoe fairness wordt toegevoegd via een pre-processing-aanpak. Zoals uit het schema blijkt, is pre-processing niet altijd noodzakelijk voor nieuwe data. Sommige methoden (bijv. resampling, relabeling) vereisen enkel een wijziging van de trainingsdata om te voorkomen dat het algoritme de bias leert. Sommige algoritmen (bijv. representation learning) vereisen echter ook dat de nieuwe te voorspellen waarnemingen worden gewijzigd.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/05/PreProcessing.png"><img loading="lazy" decoding="async" width="1024" height="355" src="/wp-content/uploads/2025/05/PreProcessing-1024x355.png" alt="" class="wp-image-22702" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/05/PreProcessing-1024x355.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PreProcessing-300x104.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PreProcessing-768x266.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PreProcessing.png 1474w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 2: Fairness via een pre-processing-aanpak.</figcaption></figure>



<h2 class="wp-block-heading">In-processing-methoden</h2>



<p>Deze methoden bestaan uit het rechtstreeks wijzigen van het voorspellingsmodel zelf, zodat de voorspellingen fair zijn. Dit kan bijvoorbeeld worden gedaan door een regularisatieterm toe te voegen aan de doelfunctie van het algoritme, of door er fairness-beperkingen aan toe te voegen.</p>
<p>In-processing-methoden hebben het voordeel dat, zodra het model is getraind, fairness direct in het model wordt opgenomen en het model vrij kan worden gebruikt, zonder dat de invoergegevens of de voorspellingen van het model verder hoeven te worden aangepast. Bovendien biedt het rechtstreeks wijzigen van het model een grote flexibiliteit, omdat complexe fairness-beperkingen kunnen worden gecodeerd.</p>
<p>Deze grote flexibiliteit vereist echter voldoende theoretische en praktische kennis om het algoritme zelf te kunnen wijzigen. Bovendien kan het aanbrengen van wijzigingen in een model, zoals beperkingen, de trainingstijd aanzienlijk verlengen. Aangezien in-processing-methoden de training van een algoritme wijzigen, zijn de meeste gepubliceerde methoden doorgaans specifiek voor een bepaald model.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/05/InProcessing.png"><img loading="lazy" decoding="async" width="1024" height="534" src="/wp-content/uploads/2025/05/InProcessing-1024x534.png" alt="" class="wp-image-22700" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/05/InProcessing-1024x534.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/05/InProcessing-300x156.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/05/InProcessing-768x400.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/05/InProcessing.png 1063w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 3: Fairness door in-processing.</figcaption></figure>



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



<p>Bij de laatste benadering worden het model en de historische data niet aangepast, maar worden de voorspellingen van het model aangepast om aan de fairness-beperkingen te voldoen. Een post-processing-algoritme wijzigt dus meestal ofwel de waarschijnlijkheid dat een waarneming tot de door het model voorspelde klassen behoort, ofwel rechtstreeks de beslissingen (definitieve classificaties) voor bepaalde waarnemingen.</p>
<p>Post-processingsalgoritmen zijn eenvoudig te implementeren: ze zijn onafhankelijk van het gebruikte voorspellingsmodel en kunnen dus worden gebruikt met ‘black-box’-modellen. Bovendien vereist post-processing geen wijzigingen aan de gegevens of het model en blijft de integriteit van het bestaande proces dus behouden.</p>
<p>Dit soort methoden leidt echter doorgaans tot een groter verlies aan modelprestaties dan het gebruik van in-processingsmethoden. Een model vrij trainen en vervolgens achteraf de voorspellingen aanpassen om aan bepaalde beperkingen te voldoen, is namelijk vaak minder effectief dan een model dat specifiek is geoptimaliseerd om voorspellingen te doen die aan de beperkingen voldoen.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/05/PostProcessing.png"><img loading="lazy" decoding="async" width="1024" height="336" src="/wp-content/uploads/2025/05/PostProcessing-1024x336.png" alt="" class="wp-image-22701" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/05/PostProcessing-1024x336.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PostProcessing-300x98.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PostProcessing-768x252.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PostProcessing.png 1323w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 4: Fairness door middel van post-processing.</figcaption></figure>



<h2 class="wp-block-heading">Eerlijke voorspellingen evalueren</h2>



<p>Vanaf het moment dat beperkingen aan de voorspellingen van een model worden toegevoegd of de toegang tot bepaalde informatie wordt beperkt, zal dit de classificatieprestaties van het model logischerwijs verminderen. Het integreren van fairness in een classificatieprobleem houdt dus in dat er een juiste balans moet worden gevonden tussen de nauwkeurigheid van het model en de fairness ervan.</p>
<p>Bovendien is het raadzaam om, zelfs wanneer een evenwicht tussen nauwkeurigheid en eerlijkheid is gevonden, altijd te controleren welke wijzigingen het toevoegen van fairness-beperkingen met zich meebrengt.</p>
<p>Een voorbeeld ter illustratie: stel dat een algoritme voorspellingen doet die bevooroordeeld zijn en relatief meer gunstige beslissingen neigt te nemen voor leden van groep A dan voor leden van groep B. Het risico bestaat dat het algoritme bij de invoering van een fairness-beperking reageert door simpelweg het aantal gunstige beslissingen voor groep A te verminderen om hetzelfde niveau als groep B te bereiken. Dit nieuwe model is dus in<strong><em> theorie</em></strong> eerlijker dan het vorige, maar het is duidelijk slechter omdat deze eerlijkheid alleen is bereikt door een van de groepen te benadelen.</p>
<p>Dit voorbeeld illustreert hoe belangrijk het is om bij het invoeren van eerlijkheid in een model niet alleen te kijken naar prestatiemaatstaven (<em>accuracy, demographic parity</em>, enz.), maar ook te onderzoeken hoe de beslissingen van het model in de praktijk worden beïnvloed.</p>



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



<p>In dit artikel hebben we gezien hoe de oneerlijkheid van een machine learning-model kan worden gemeten. Ook hebben we een overzicht gegeven van de verschillende benaderingen die worden gebruikt om te voorkomen dat het model een in de historische gegevens aangeleerde bias reproduceert of versterkt.</p>
<p>Belangrijk is dat de verschillende benaderingen elkaar niet uitsluiten en vaak kunnen worden gecombineerd (bijvoorbeeld voorbewerking van de trainingsdata, gevolgd door een in-processing-methode op het model). Sommige publicaties op dit gebied stellen methoden voor die op verschillende niveaus van het classificatieproces werken.</p>



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



<p id="footnote-1">[1] Mehrabi, N., Morstatter, F., Saxena, N., Lerman, K., &amp; Galstyan, A. (2021). A survey on bias and fairness in machine learning. <em>ACM computing surveys (CSUR)</em>, <em>54</em>(6), 1-35.</p>
<p id="footnote-2">[2] Castelnovo, A., Crupi, R., Greco, G., Regoli, D., Penco, I. G., &amp; Cosentini, A. C. (2022). A clarification of the nuances in the fairness metrics landscape. <em>Scientific Reports</em>, <em>12</em>(1), 4209.</p>
<p id="footnote-3">[3] Corbett-Davies, S., Gaebler, J. D., Nilforoshan, H., Shroff, R., &amp; Goel, S. (2023). The measure and mismeasure of fairness. <em>Journal of Machine Learning Research</em>, <em>24</em>(312), 1-117.</p>
<p id="footnote-4">[4] Hort, M., Chen, Z., Zhang, J. M., Harman, M., &amp; Sarro, F. (2024). Bias mitigation for machine learning classifiers: A comprehensive survey. <em>ACM Journal on Responsible Computing</em>, <em>1</em>(2), 1-52.</p>
<p>Voor een soortgelijk onderwerp, zie de blogpost <a href="/ia-lethique-en-pratique/">IA : L&#8217;éthique en pratique</a>.</p>
<hr />
<p><em>Dit is een ingezonden bijdrage van Pierre Leleux, data scientist et network data analyst bij Smals Research. Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Ethique et intelligence artificielle&#160;: comment mesurer et corriger un biais ?</title>
		<link>https://www.smalsresearch.be/ethique-et-intelligence-artificielle-comment-mesurer-et-corriger-un-biais/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Tue, 20 May 2025 12:00:00 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[classification]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<guid isPermaLink="false">/?p=22692</guid>

					<description><![CDATA[Cet article s'intéresse à la manière dont les biais algorithmiques peuvent être mesurés et corrigés pour générer des prédictions équitables.]]></description>
										<content:encoded><![CDATA[
<p><em><a href="/ethiek-en-artificiele-intelligentie-hoe-een-bias-meten-en-corrigeren/">Nederlandstalige versie</a></em></p>
<p>Tandis que l’intelligence artificielle et le machine learning jouent un rôle croissant dans la société humaine pour soutenir les processus de prise de décision, les préoccupations concernant leur équité (fairness) ont attiré l’attention au cours des dernières années. Les modèles prédictifs peuvent en effet devenir problématiques lorsqu’ils commencent à reproduire ou renforcer des biais qu’ils ont appris dans les données historiques utilisées durant leur phase d’entrainement. Ce biais crée souvent une discrimination injuste à l’encontre d’un ou plusieurs groupe(s) d’individus, ce qui est particulièrement problématique dans le cadre de décisions sensibles, telles que le traitement de candidatures d’emploi, l’accord de prêts ou la justice, entre autres. Cet article s&#8217;intéresse à la manière dont ces biais algorithmiques peuvent être mesurés et les différentes façons de les corriger pour générer des prédictions équitables.</p>
<p>Comme nous en avions déjà discuté dans un <a href="/lethique-dans-lintelligence-artificielle/">précédent article de blog</a>, un biais peut avoir plusieurs sources. Il peut par exemple s’agir d’un problème de design de l’algorithme en lui-même, d’un souci de sous-représentation d’un groupe dans les données d’entrainement, ou de données historiques biaisées par du racisme/sexisme présent dans la société [<a href="#footnote-1">1</a>]. Dans le cadre de cet article, nous nous concentrerons sur le cas où le problème vient des données et non pas du modèle en lui-même, à savoir lorsque le modèle apprend sur des données biaisées et reproduit ensuite ce biais dans ses prédictions.</p>
<p>L’un des exemples les plus connus est le cas COMPAS. L’algorithme COMPAS était utilisé aux États-Unis pour estimer le risque de récidive de détenus dans le cadre d’une potentielle libération anticipée. En 2016, <a href="https://www.propublica.org/article/how-we-analyzed-the-compas-recidivism-algorithm">une étude de ProPublica</a> affirmait que les Afro-Américains étaient discriminés par l’algorithme car ils avaient plus de chance d’être classifiés comme « high-risk ». Plus précisément, l’étude mentionnait qu’une personne noire avait plus de chance d’être erronément classifiée comme « high-risk » et, qu’à l’inverse, une personne blanche avait plus de chance d’être erronément classifiée comme « low-risk ». Cette affaire entraina un grand débat et la publication de centaines d’articles sur le sujet.</p>
<p>Dans le cas de COMPAS, le problème n’était pas l’algorithme en lui-même, mais les données sur lesquelles il a été entrainé. Le modèle a en effet été entrainé sur des données historiques de la justice pénale qui reflètent un biais raciste systémique, telles que des pratiques policières discriminatoires. Ces données biaisées ont donc entrainé un modèle produisant des prédictions elles aussi biaisées.</p>



<h2 class="wp-block-heading">Comment mesurer l’iniquité d’un modèle&nbsp;?</h2>



<p>Les problèmes de fairness supposent l’existence d’une variable appelée <strong>variable sensible</strong>. Il s’agit de la variable vis-à-vis de laquelle on souhaite qu’il n’y ait pas de discrimination. Il peut par exemple s’agir du genre de la personne, ou de son origine ethnique. La variable sensible est souvent <strong>catégorielle</strong>, mais suivant le cas de figure, elle peut aussi être <strong>continue</strong> (e.g. l’âge d’une personne). Pour des raisons de simplicité, nous faisons l’hypothèse qu’il n’y a qu’une seule variable sensible, mais dans certains problèmes il peut y en avoir plusieurs.</p>
<p>Sur base de cette variable sensible, on définit généralement deux groupes. Le groupe qui est discriminé négativement par le modèle est appelé « groupe protégé ».</p>
<p>Supposons un modèle prédictif ayant pour objectif de fournir des prédictions concernant l’accord d’un prêt. Cet algorithme sera considéré comme « équitable » si la probabilité pour un individu d’être sélectionné pour le prêt (décision positive du modèle) est la même peu importe le groupe dont est issu l’individu. Mathématiquement, on cherche donc à imposer&nbsp;:</p>
<p>P(Y<sub>d</sub> = 1 | Z = 1) = P(Y<sub>d</sub> = 1 | Z = 0)</p>
<p>Où Y<sub>d</sub> est la décision du modèle et Z est une variable binaire indiquant l’appartenance ou non au groupe protégé. Ces probabilités sont calculées à l’échelle du groupe, et non pas de façon individuelle.</p>
<p>Une mesure bien connue de l’iniquité algorithmique consiste donc simplement à calculer la différence entre ces deux termes. S’il y a une différence, cela implique que le modèle favorise l’un des deux groupes. Cette mesure de la différence entre les prédictions au sein des deux groupes est appelée la « demographic parity » ou « statistical parity ».</p>
<p>Bien que relativement simple, il s’agit de l’une des mesures les plus connues dans le domaine de l’équité algorithmique, largement reconnue et utilisée. Cependant, ce n’est évidemment pas la seule mesure qui existe (pour quelques alternatives, voir e.g., [<a href="#footnote-2">2</a>, <a href="#footnote-3">3</a>]). Il est à noter que, puisqu’elle se mesure à l’échelle des groupes, la demographic parity est donc une mesure d’équité de groupe (group fairness), il existe aussi des mesures alternatives au niveau des individus (individual fairness).</p>



<h2 class="wp-block-heading"><strong>Pourquoi ne pas simplement enlever la variable sensible du modèle&nbsp;?</strong></h2>



<p>Le problème semble, à première vue, simple à régler. Un modèle prédictif de machine learning prend en entrée des données X et prédit une variable Y en sortie sur base des données contenues dans X. Il suffirait donc, a priori, simplement d’enlever la variable Z de la base de données X pour que les prédictions du modèle ne soient plus impactées par Z.</p>
<p>Malheureusement, dans la pratique, les variables qui composent X sont rarement indépendantes les unes des autres. La base de données X peut donc contenir des variables corrélées avec la variable sensible, et le modèle pourra se servir de ces variables comme d’un proxy de la variable sensible et fournir des prédictions biaisées, bien que Z ne fasse pas explicitement partie des données utilisées en entrée. Par exemple, dans un échantillon, le revenu d’une personne peut être utilisée comme proxy de son âge, car les revenus des individus ont tendance à augmenter avec l’âge.</p>
<p>Dans le cas COMPAS par exemple, l’origine ethnique du détenu n’était pas explicitement utilisée en tant que variable du modèle, mais à cause de la présence de variables proxy corrélées (e.g., le code postal, des indicateurs socio-économiques), le biais racial se reflétait toujours dans les prédictions du modèle.</p>



<h2 class="wp-block-heading"><strong>Comment corriger un biais algorithmique en pratique&nbsp;?</strong></h2>



<p>Il existe 3 grandes familles de corrections : le prétraitement (« pre-processing » : enlever le biais des données d’entrainement), le traitement en cours (« in-processing » : enlever le biais durant l’entrainement du modèle) et le post-traitement (« post-processing » : enlever le biais d’un modèle entrainé). Chacune de ces approches a ses avantages et ses inconvénients et a fait l’objet de nombreuses publications. Le lecteur intéressé pourra se référer au survey suivant [<a href="#footnote-4">4</a>], qui rassemble et organise les différentes publications dans le domaine de la fairness par approche (pre-, in-, post-processing), type d’algorithme utilisé (régression logistique, random forest, réseaux de neurones, etc.), mesure de fairness utilisée, etc., offrant une vue d’ensemble bien structurée de ce qui se fait dans le domaine.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/05/Biased_Process.png"><img loading="lazy" decoding="async" width="1024" height="437" src="/wp-content/uploads/2025/05/Biased_Process-1024x437.png" alt="" class="wp-image-22699" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/05/Biased_Process-1024x437.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/05/Biased_Process-300x128.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/05/Biased_Process-768x328.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/05/Biased_Process.png 1056w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figure 1&nbsp;: Vue d’ensemble d’un processus de classification présentant un biais dans les données.</figcaption></figure>



<h2 class="wp-block-heading"><strong>Les méthodes «&nbsp;pre-processing&nbsp;»</strong></h2>



<p>L’idée est simple&nbsp;: il s’agit simplement de débiaiser les données d’entrainement pour les rendre plus proches de la réalité, de sorte que le biais ne parvienne pas jusqu’au modèle de machine learning. Quelques exemples de méthodes de pre-processing incluent par exemple&nbsp;:</p>



<ul class="wp-block-list">
<li>Rééquilibrer l’échantillonnage (en ajoutant ou supprimant des observations) ;</li>



<li>Corriger le contenu de certaines variables des données X, voire complètement remplacer les variables par des nouvelles (representation learning) qui ne contiennent pas d’information sensible ;</li>



<li>Changer le label (variable Y) de certaines observations.</li>
</ul>



<p>Le pre-processing offre l’avantage de ne pas dépendre du modèle utilisé et d’être (généralement) facile à expliquer et à comprendre. Cependant, corriger adéquatement les données historiques peut être compliqué à réaliser, et il est difficile de garantir l’équité du modèle résultant. Il faut aussi mentionner le risque de perte de précision, car altérer les données peut potentiellement enlever des patterns pertinents des données.</p>
<p>La figure 2 montre l’ajout d’équité via une approche pre-processing. Comme visible sur le schéma, le pre-processing ne s’applique pas toujours nécessairement aux nouvelles données. Certaines méthodes (e.g. rééchantillonnage, relabeliser) ne demandent que de modifier les données d’entrainement, pour éviter que l’algorithme n&#8217;apprenne le biais. Par contre, certains algorithmes (e.g. representation learning) nécessitent aussi de modifier les nouvelles observations à prédire.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/05/PreProcessing.png"><img loading="lazy" decoding="async" width="1024" height="355" src="/wp-content/uploads/2025/05/PreProcessing-1024x355.png" alt="" class="wp-image-22702" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/05/PreProcessing-1024x355.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PreProcessing-300x104.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PreProcessing-768x266.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PreProcessing.png 1474w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figure 2&nbsp;: Equité par approche pre-processing.</figcaption></figure>



<h2 class="wp-block-heading"><strong>Les méthodes «&nbsp;in-processing&nbsp;»</strong></h2>



<p>Ces méthodes consistent à modifier directement le modèle prédictif en lui-même, de sorte que ses prédictions soient équitables. Cela peut par exemple se faire en ajoutant un terme de régularisation sur la fonction objectif de l&#8217;algorithme, ou en lui ajoutant des contraintes de fairness.</p>
<p>Les méthodes in-processing ont l’avantage qu’une fois le modèle entrainé, la fairness est directement inclue dans le modèle et celui-ci peut être utilisé librement, sans nécessiter de modification supplémentaire des données entrées ou des prédictions du modèle. De plus, modifier directement le modèle offre une grande flexibilité, car on peut y encoder des contraintes de fairness complexes.</p>
<p>Cette grande flexibilité requiert, en contrepartie, des connaissances théoriques et pratiques suffisamment approfondies pour pouvoir modifier l’algorithme en lui-même. En outre, introduire des modifications dans un modèle, telles que des contraintes, peut significativement augmenter son temps d’entrainement. Enfin, puisque les méthodes d’in-processing modifient l’entrainement d’un algorithme, la plupart des méthodes publiées sont généralement spécifiques à un modèle précis.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/05/InProcessing.png"><img loading="lazy" decoding="async" width="1024" height="534" src="/wp-content/uploads/2025/05/InProcessing-1024x534.png" alt="" class="wp-image-22700" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/05/InProcessing-1024x534.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/05/InProcessing-300x156.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/05/InProcessing-768x400.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/05/InProcessing.png 1063w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figure 3&nbsp;: Equité par approche in-processing.</figcaption></figure>



<h2 class="wp-block-heading"><strong>Les méthodes «&nbsp;post-processing&nbsp;»</strong></h2>



<p>Pour la dernière approche, on ne touche pas au modèle ou aux données historiques, on va simplement appliquer un ajustement aux prédictions fournies par le modèle de sorte à satisfaire les contraintes de fairness. Un algorithme de post-processing va donc généralement soit modifier les probabilités d’appartenance aux classes prédites par le modèle, soit directement modifier les décisions (classifications finales) pour certaines observations.</p>
<p>Les algorithmes de post-processing sont des solutions simples à mettre en place&nbsp;: ils sont indépendants du modèle prédictif utilisé, et peuvent donc s’utiliser avec des modèles « black-box ». De plus, le post-processing ne demande aucune modification ni des données, ni du modèle, et préserve donc l’intégrité du processus existant.</p>
<p>Ce genre de méthodes tend cependant généralement à dégrader plus fortement les performances du modèle que l’utilisation de méthodes d’in-processing. En effet, entrainer un modèle librement et ensuite altérer ses prédictions a posteriori pour que ces dernières remplissent des contraintes sera souvent moins efficace que d’avoir un modèle ayant été spécifiquement optimisé pour fournir des prédictions remplissant les contraintes.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/05/PostProcessing.png"><img loading="lazy" decoding="async" width="1024" height="336" src="/wp-content/uploads/2025/05/PostProcessing-1024x336.png" alt="" class="wp-image-22701" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/05/PostProcessing-1024x336.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PostProcessing-300x98.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PostProcessing-768x252.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/05/PostProcessing.png 1323w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figure 4&nbsp;: Equité par approche post-processing.</figcaption></figure>



<h2 class="wp-block-heading"><strong>Evaluer les prédictions équitables</strong></h2>



<p>Par définition, à partir du moment où on ajoute des contraintes sur les prédictions d’un modèle, ou si on limite l’accès à certaines informations, cela va logiquement réduire les performances de classification du modèle. Par conséquent, incorporer de l’équité dans un problème de classification implique de trouver la juste balance entre la précision du modèle et sa fairness.</p>
<p>De plus, même une fois qu’un équilibre entre précision et équité a été trouvé, il convient toujours de vérifier les modifications qui résultent de l’ajout des contraintes de fairness.</p>
<p>Prenons un exemple illustratif&nbsp;: supposons un algorithme fournissant des prédictions biaisées, qui a tendance à donner relativement plus de décisions favorables aux membres du groupe A comparé au groupe B. Il y a un risque qu’à l’introduction d’une contrainte de fairness, l’algorithme réponde en réduisant simplement le nombre de décisions favorables pour le groupe A pour atteindre le même niveau que le groupe B. Ce nouveau modèle est donc <em><strong>théoriquement</strong></em> plus équitable que le précédent, mais il est manifestement pire puisque cette équité a été réalisée uniquement en pénalisant l’un des groupes.</p>
<p>Cet exemple illustre l’importance, lors de l’introduction d’équité dans un modèle, de ne pas regarder uniquement les mesures de performance (accuracy, demographic parity, etc.), mais aussi d’investiguer la façon dont les décisions du modèle sont impactées en pratique.</p>



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



<p>Dans cet article, nous avons vu comment mesurer l’iniquité d’un modèle de machine learning, et présenté un aperçu des différentes approches utilisées pour éviter que le modèle ne reproduise ou ne renforce un biais appris dans les données historiques.</p>
<p>Il est important de signaler que les différentes approches ne sont pas mutuellement exclusives, et peuvent souvent être combinées (e.g. un pre-processing des données d’entrainement, suivi d’une méthode in-processing sur le modèle). Certaines publications dans le domaine proposent d’ailleurs des méthodes qui agissent à plusieurs niveaux du processus de classification.</p>



<h2 class="wp-block-heading">Références</h2>



<p id="footnote-1">[1] Mehrabi, N., Morstatter, F., Saxena, N., Lerman, K., &amp; Galstyan, A. (2021). A survey on bias and fairness in machine learning. <i>ACM computing surveys (CSUR)</i>, <i>54</i>(6), 1-35.</p>
<p id="footnote-2">[2] Castelnovo, A., Crupi, R., Greco, G., Regoli, D., Penco, I. G., &amp; Cosentini, A. C. (2022). A clarification of the nuances in the fairness metrics landscape. <i>Scientific Reports</i>, <i>12</i>(1), 4209.</p>
<p id="footnote-3">[3] Corbett-Davies, S., Gaebler, J. D., Nilforoshan, H., Shroff, R., &amp; Goel, S. (2023). The measure and mismeasure of fairness. <i>Journal of Machine Learning Research</i>, <i>24</i>(312), 1-117.</p>
<p id="footnote-4">[4] Hort, M., Chen, Z., Zhang, J. M., Harman, M., &amp; Sarro, F. (2024). Bias mitigation for machine learning classifiers: A comprehensive survey. <i>ACM Journal on Responsible Computing</i>, <i>1</i>(2), 1-52.</p>
<p>Sur un sujet similaire, voir le post <a href="/ia-lethique-en-pratique/">IA: L&#8217;éthique en pratique</a>.</p>



<hr />
<p><em>Ce post est une contribution individuelle de Pierre Leleux, data scientist et network data analyst chez Smals Research. Cet article est écrit en son nom propre et n’impacte en rien le point de vue de Smals.</em></p>


]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Graphtechnologieën, de toepassingen ervan en tools: een overzicht (deel 2)</title>
		<link>https://www.smalsresearch.be/graphtechnologieen-toepassingen-en-tools-2/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Thu, 20 Feb 2025 10:01:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[Graph Databases]]></category>
		<category><![CDATA[Information management]]></category>
		<category><![CDATA[Knowledge Graph]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[methodology]]></category>
		<guid isPermaLink="false">/?p=21956</guid>

					<description><![CDATA[Dit tweede deel is gewijd aan graph databases en aan knowledge graphs, hun verschillen en tools.]]></description>
										<content:encoded><![CDATA[
<p><em><a href="/graphes_applications_et_outils_2/">Version française</a></em></p>



<p>Deze blogpost volgt op <a href="/graphtechnologieen-toepassingen-en-tools/">deel 1</a>, die de grondbeginselen van graphtechnologieën, hun algoritmes en toepassingen toelicht. Dit tweede deel is gewijd aan graph databases en aan knowledge graphs, hun verschillen en tools.</p>



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



<p>Zoals bij een relationele database is ook bij een graph database het doel om gegevens op een persistente manier op te slaan en te beheren en om complexe query&#8217;s uit te voeren. Het verschil is dat de gegevens worden opgeslagen in de vorm van een graph, d.w.z. een verzameling nodes die onderling verbonden zijn door bogen.</p>
<p>Graph databases hebben een aantal voordelen ten opzichte van traditionele relationele databases, omdat het graph model eenvoudige, geoptimaliseerde doorloop van gegevens via bogen mogelijk maakt, terwijl het verkennen van relaties in een relationele database een groot aantal joints kan vereisen. Meer details over de voordelen van graph databases en de situaties waarin ze gebruikt kunnen worden, zijn te vinden in de blogposts [<a href="#footnote-1">1</a>] en [<a href="#footnote-2">2</a>].</p>
<p>De drie componenten van een graph database zijn nodes, bogen en properties. Deze eigenschappen kunnen ofwel op de nodes, ofwel op de bogen, ofwel op beide worden geplaatst. Laten we eens kijken naar het voorbeeld in Figuur 1, de node “Paul” kan bijvoorbeeld gelinkt worden met eigenschappen zoals zijn geboortedatum en adres, voor de nodes die films voorstellen kunnen we eigenschappen associëren zoals het jaar van uitgave, het budget en de IMDb identifier, en op de “RATED” relaties tussen een gebruiker en een film kunnen we eigenschappen associëren zoals de kijkdatum en de waardering (op 5) die de gebruiker aan de film geeft.</p>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2025/02/LPG_EN.png"><img loading="lazy" decoding="async" width="1024" height="373" src="/wp-content/uploads/2025/02/LPG_EN-1024x373.png" alt="" class="wp-image-21938" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/02/LPG_EN-1024x373.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/02/LPG_EN-300x109.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/02/LPG_EN-768x280.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/02/LPG_EN.png 1372w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 1: Voorbeeld van nodes en arcs met eigenschappen in Neo4J.</figcaption></figure>



<p>Merk op dat de graph algoritmes die we in <a href="/graphtechnologieen-toepassingen-en-tools/">deel 1</a> hebben gepresenteerd vaak niet zijn geïmplementeerd in graph database software, met een paar uitzonderingen (Neo4j en TigerGraph hebben een “Graph Data Science (GDS)” library die verschillende algoritmes bevat). Over het algemeen is het daarom nodig om de graph (of een deel ervan) te exporteren naar een analysetool.</p>



<h2 class="wp-block-heading">Tools voor graph databases</h2>



<p>Laten we eens snel kijken naar enkele van de bekendste tools. Merk op dat alle hieronder genoemde tools compatibel zijn met <a href="https://nl.wikipedia.org/wiki/ACID">ACID</a>-eigenschappen. Er bestaan een groot aantal tools voor het beheren van graph databases, en deze post noemt er maar een paar. Bekijk <a href="https://db-engines.com/en/ranking/graph+dbms">hier</a> gerust een uitgebreidere lijst.</p>
<ol>
<li>Neo4j</li>
</ol>
<p>Neo4j biedt het voordeel van een native graphformaat, wat het doorlopen van de graph zeer efficiënt maakt (en dus ook de query&#8217;s) De query&#8217;s gebeuren via Cypher, een taal die gemakkelijk te leren is, Neo4J is bovendien goed gedocumenteerd en beschikt over een grote community. Neo4J is in zijn “community”-versie gratis, maar een betalende versie bestaat ook (Neo4J Enterprise), de gratis versie kan een aantal schaalbaarheidsproblemen opleveren bij zeer grote hoeveelheden data.</p>
<ol start="2">
<li>ArangoDB</li>
</ol>
<p>ArangoDB biedt een flexibel datamodel (multimodel), met een graphmodel, een documentmodel (gebaseerd op JSON-objecten) en een key-value model. Het heeft zijn eigen querytaal, AQL (Arango Query Language), die ingewikkelder kan zijn om te leren dan Cypher vanwege het multimodel dat aan de grondslag ligt van ArangoDB. Het programma is betalend, hoewel er ook een opensourceversie bestaat (community edition), maar die is (uiteraard) beperkter dan de betalende versie.</p>
<ol start="3">
<li>TigerGraph</li>
</ol>
<p>TigerGraph is een betalende tool, die geoptimaliseerd is voor gebruik op zeer grote databases. De query&#8217;s gebeuren via de taal GSQL, die het mogelijk maakt om verschillende taken uit te voeren, maar die ingewikkelder is dan Cypher. TigerGraph beschikt over verschillende algoritmes die geïmplementeerd zijn via de GDS library.</p>
<ol start="4">
<li>Memgraph</li>
</ol>
<p>Memgraph is een speciale tool in die zin dat hij gegevens direct in het geheugen bewaart (in RAM). Dit levert zeer hoge prestaties op voor query&#8217;s, maar maakt het aan de andere kant moeilijk te gebruiken, of op zijn minst kostbaar in termen van infrastructuur, als de graph groot is, omdat je genoeg RAM moet hebben om de gegevens op te slaan. Memgraph wordt daarom over het algemeen gebruikt als prestaties de hoogste prioriteit hebben. Query&#8217;s worden gedaan in Cypher.</p>
<ol start="5">
<li>GraphDB</li>
</ol>
<p>GraphDB gebruikt een zeer specifiek graphmodel dat het Resource Description Framework (RDF) wordt genoemd. Dit framework, dat meer in detail zal worden besproken in de sectie Knowledge graphs, heeft zijn eigen querytaal die SPARQL heet. Er bestaat een gratis opensourceversie (graphDB Free) en een betalende enterpriseversie (graphDB Enterprise).</p>
<ol start="6">
<li>Apache TinkerPop en de implementaties ervan</li>
</ol>
<p>Het gaat om een opensource framework voor het definiëren van een graph database en een querytaal die “Gremlin” heet. Het wordt gebruikt in veel graph database management software, zoals JanusGraph (opensource software), Amazon Neptune dat andere modellen biedt dan die van TinkerPop zoals RDF, of nog andere tools voor databasebeheer die niet gespecialiseerd zijn in graphs, zoals Azure Cosmos DB.</p>



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



<p>Laten we, voordat we naar werkwijzen en tools kijken, eerst definiëren wat een knowledge graph is en hoe deze verschilt van een graph database. Het is een graph die zich richt op semantiek en inferentie. Elke node vertegenwoordigt een concept en elke boog een relatie. Zoals we al hebben gezien in de blogposts [<a href="#footnote-3">3</a>, <a href="#footnote-4">4</a>], wordt een knowledge graph gedefinieerd als een graph die aan drie voorwaarden voldoet [<a href="#footnote-5">5</a>]:</p>
<ol>
<li>De integratie van informatie uit verschillende heterogene bronnen.</li>
</ol>
<p>Een knowledge graph verzamelt en combineert gegevens uit verschillende (on)gestructureerde bronnen op een coherente manier.</p>
<ol>
<li>Het gebruik van een ontologie.</li>
</ol>
<p>Een ontologie beschrijft formeel de concepten en relaties die aanwezig zijn in de graph, evenals eventuele beperkingen en regels. Het is dus een gestructureerd model dat de semantische basis biedt voor logische bewerkingen en coherentietesten. Een ontologieschema (zie Figuur 2), ook bekend als een &#8216;ontology graph&#8217;, biedt bijvoorbeeld een representatie van de entiteittypes en relaties van een knowledge graph, en biedt zo een conceptuele structuur zonder specifieke gegevens te bevatten.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/02/Ontology_EN.png"><img loading="lazy" decoding="async" width="868" height="561" src="/wp-content/uploads/2025/02/Ontology_EN.png" alt="" class="wp-image-21937" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/02/Ontology_EN.png 868w, https://www.smalsresearch.be/wp-content/uploads/2025/02/Ontology_EN-300x194.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/02/Ontology_EN-768x496.png 768w" sizes="auto, (max-width: 868px) 100vw, 868px" /></a><figcaption class="wp-element-caption">Figuur 2: Voorbeeld van ontologieschema</figcaption></figure>



<ol>
<li>Inferentie van impliciete informatie op basis van expliciete informatie.</li>
</ol>
<p>Het is mogelijk om informatie te vinden die niet aanwezig was in de oorspronkelijke gegevens op basis van inferentieregels (zie Figuur 3).</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/01/image-6.png"><img loading="lazy" decoding="async" width="748" height="287" src="/wp-content/uploads/2025/01/image-6.png" alt="" class="wp-image-21762" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/01/image-6.png 748w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-6-300x115.png 300w" sizes="auto, (max-width: 748px) 100vw, 748px" /></a><figcaption class="wp-element-caption">Figuur 3: Voorbeelden van inferentie. Uit een vorige <a href="/les-graphes-de-connaissance-incontournable-pour-lintelligence-artificielle-2/">blogpost</a>.</figcaption></figure>



<h2 class="wp-block-heading">Een overzicht van het RDF-model (Resource Description Framework)</h2>



<p>Het RDF-model, oorspronkelijk ontworpen voor de formele beschrijving van web resources en de metadata ervan, wordt vaak gebruikt bij knowledge graphs omdat het robuust semantisch rederneren en een zeer hoge interoperabiliteit biedt.</p>
<p>Een RDF-document heeft de vorm van een set RDF-triples waarbij elk triple een associatie is: subject (te beschrijven bron), predicaat (eigenschap van de bron), object (gegevens of andere bron).</p>
<p>Bijvoorbeeld:</p>
<p><code>:Alice&nbsp;:knows&nbsp;:Bob .<br />:Alice&nbsp;:livesIn&nbsp;:Paris .<br />:Alice&nbsp;:age 30 .</code></p>
<p>Deze semantic triples vertegenwoordigen dus zowel relaties tussen nodes (bijvoorbeeld de relatie tussen Alice en Bob) als eigenschappen (de leeftijd van Alice).</p>
<p>Kenmerkend voor RDF is dat elk element van een triple (met uitzondering van het object als het een simpele waarde is, zoals de waarde 30 voor de leeftijd van Alice) door een URI (<em>Uniform Resource Identifier</em>) of IRI (<em>Internationalized Resource Identifier</em>) moet worden geïdentificeerd. Dit zorgt voor een hoge mate van interoperabiliteit, omdat het voorkomt dat er duplicaten ontstaan wanneer verschillende informatiebronnen worden gecombineerd. Als we teruggaan naar de eerder gebruikte triples, krijgen we het volgende fragment (in Turtle-taal):</p>
<p><code>&lt;http://example.org/Alice&gt; &lt;http://example.org/knows&gt; &lt;http://example.org/Bob&gt; .<br />&lt;http://example.org/Alice&gt; &lt;http://example.org/livesIn&gt; &lt;http://example.org/Paris&gt; .<br />&lt;http://example.org/Alice&gt; &lt;http://example.org/age&gt; "30"^^&lt;http://www.w3.org/2001/XMLSchema#integer&gt; .</code></p>
<p>Het gebruik van RDF impliceert daarom een URI om alle concepten (subjecten, predikaten en objecten) in de graph te kunnen identificeren op dezelfde manier als een primaire sleutel in relationele databases.</p>
<p>Bovendien bestaan er twee hulpmiddelen om semantische betekenis toe te voegen aan RDF-gegevens door relaties te beschrijven om redeneren mogelijk te maken, namelijk RDFS (<em>RDF Schema</em>) en OWL (<em>Web Ontology Language</em>). Zoals we al hebben gezien, vereist RDF dat elk concept wordt geïdentificeerd door een URI. RDFS en OWL bieden een voorgedefinieerde set URI&#8217;s voor veelgebruikte concepten waarnaar verwezen kan worden in RDF. Dit maakt het mogelijk om een gestandaardiseerd gemeenschappelijk vocabularium te hebben, wat de integratie met andere databanken vergemakkelijkt, en om inferentieregels op te stellen. Aangezien OWL en RDFS <strong>gestandaardiseerde concepten</strong> aanbieden, kunnen OWL-gebaseerde &#8216;reasoners&#8217; (zoals FaCT++ of HermiT) op een systematische manier impliciete relaties afleiden of tegenstrijdigheden detecteren op basis van de ontologie.</p>
<p>Query&#8217;s op een RDF database worden gedaan via SPARQL.</p>



<h2 class="wp-block-heading">Alternatieven voor RDF en tools voor het werken met een knowledge graph</h2>



<p>Natuurlijk is het voor een knowledge graph niet noodzakelijk om het RDF-model te gebruiken. Een graph wordt als een knowledge graph beschouwd als voldaan is aan de 3 voorwaarden die beschreven zijn aan het begin van het hoofdstuk over knowledge graphs. Het is dus perfect mogelijk om een knowledge graph te creëren in een klassieke graph databasemanagementtool, zolang de implementatie data uit verschillende bronnen combineert, voldoet aan een ontologie en gebruikt kan worden voor semantische inferentie.</p>
<p>De voornaamste kracht van het RDF-model is zijn hoge standaardisatieniveau. Enerzijds laat het een hoge mate van interoperabiliteit toe dankzij de URI-identificatievereiste en de gestandaardiseerde woordenschat en querytaal. Anderzijds bieden de RDFS- en OWL-uitbreidingen een schat aan semantische informatie voor automatisch redeneren. Omgekeerd beperkt de complexiteit het gebruik in zakelijke toepassingen waar deze semantische nauwkeurigheid niet noodzakelijk is en waar het gebruik van een eenvoudiger graphmodel (zoals Neo4j of TigerGraph) volstaat. Het gebruik van eenvoudigere modellen heeft het voordeel dat ze eenvoudiger en sneller op te zetten zijn en optimale query prestaties bieden, maar ten koste van het verlies van de semantische rijkdom die RDF biedt.</p>
<p>In deze sectie worden (niet-exhaustieve) tools met betrekking tot RDF voorgesteld, maar zoals vermeld blijven de tools die eerder werden vermeld voor graph databases geldig voor het creëren van een knowledge graphs zolang aan de voorwaarden wordt voldaan.</p>
<p>Hier is een lijst van enkele tools gerelateerd aan knowledge graphs in RDF:</p>



<ul class="wp-block-list">
<li><strong>Ontwerp van ontologieën</strong>: de opensourcetool <a href="https://protege.stanford.edu/">Protégé</a> wordt vaak gebruikt om ontologieën te creëren. De website <a href="https://schema.org/">Schema.org</a> biedt een groot aantal standaard schema&#8217;s en vocabulaires voor verschillende domeinen, maar wordt over het algemeen gebruikt voor knowledge graphs met betrekking tot webgegevens.</li>



<li><strong>Gegevens omzetten naar RDF</strong>: de tool <a href="https://www.w3.org/TR/r2rml/">R2RML</a> kan gebruikt worden om relationele gegevens om te zetten in RDF. Ook het vermelden waard is <a href="https://d2rq.org/">D2RQ</a>, dat toegang biedt tot een relationele database via een virtuele RDF knowledge graph.</li>



<li><strong>Dataopslag</strong>: naast de hierboven genoemde oplossingen (GraphDB en Amazon Neptune), kunnen we ook BlazeGraph en Apache Jena (opensource) vermelden, alsook Stardog en AllegroGraph (businessoplossingen).</li>



<li><strong>OWL reasoners</strong>: er bestaan veel OWL reasoners. Ze worden echter niet allemaal actief onderhouden of zijn niet altijd bruikbaar. De meest recente OWL reasoners lijst die we konden vinden dateert uit 2023 en is <a href="https://arxiv.org/pdf/2309.06888">hier</a> beschikbaar [<a href="#footnote-6">6</a>].</li>
</ul>



<p>Tot slot willen we nog het RDF4J framework (Java framework) en rdflib (python library) vermelden voor interactie met RDF data.</p>



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



<p>Laten we afsluiten met een korte samenvatting van de belangrijkste concepten die een wiskundige graph onderscheiden van een graph database en een knowledge graph.</p>
<p>Een wiskundige graph is een verzameling van nodes en bogen die gemakkelijk kan worden voorgesteld in matrixvorm zodat er algoritmes op kunnen worden toegepast. Het is de onderliggende structuur van elke graph database of knowledge graph.</p>
<p>Een graph database bestaat uit een set van nodes, bogen en properties. De nadruk ligt op het opslaan van grote hoeveelheden gegevens binnen een graph structuur en het optimaliseren van query&#8217;s.</p>
<p>Een knowledge graph heeft als doel om kennis binnen een graph weer te geven met de nadruk op:</p>



<ul class="wp-block-list">
<li><strong>Semantiek</strong>: de graph volgt een ontologie en relaties hebben betekenis.</li>



<li><strong>Integratie</strong>: verschillende databronnen zijn gekoppeld in een uniforme graph.</li>



<li><strong>Inferentie</strong>: het vermogen om kennis af te leiden door redeneren.</li>
</ul>



<p>Daarom is het gericht op de integratie en de semantische verrijking van data.</p>
<p>Het spreekt voor zich dat deze post slechts een tipje van de sluier oplicht van de uitgebreide literatuur over graphs en de verschillende toepassingen ervan. Vele punten moeten nog verder uitgewerkt worden en zullen ongetwijfeld het onderwerp zijn van toekomstige blogposts.</p>



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



<p id="footnote-1">[1] <a href="/graph-db-vs-rdbms/">Graph DB vs RDBMS</a></p>
<p id="footnote-2">[2] <a href="/sept-bonnes-raisons-dutiliser-une-graph-database/">Sept (bonnes) raisons d’utiliser une Graph Database</a></p>
<p id="footnote-3">[3] <a href="/les-graphes-de-connaissance-incontournable-pour-lintelligence-artificielle-2/">Les graphes de connaissance, incontournable pour l’intelligence artificielle</a></p>
<p id="footnote-4">[4] <a href="/smalls-kg-checklist/">Smals KG Checklist: déterminer si un graphe de connaissances peut résoudre un problème concret</a></p>
<p id="footnote-5">[5] Ehrlinger, L., &amp; Wöß, W. (2016). Towards a definition of knowledge graphs. SEMANTiCS 2016, 48(1-4), 2.</p>
<p id="footnote-6">[6] <a href="https://arxiv.org/pdf/2309.06888">Abitch, K., (2023). &#8220;OWL Reasoners still useable in 2023&#8221;</a></p>
<hr />
<p><em>Dit is een ingezonden bijdrage van Pierre Leleux, data scientist et network data analyst bij Smals Research. Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Graphtechnologieën, de toepassingen ervan en tools: een overzicht (deel 1)</title>
		<link>https://www.smalsresearch.be/graphtechnologieen-toepassingen-en-tools/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Thu, 20 Feb 2025 10:00:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[Graph Databases]]></category>
		<category><![CDATA[Information management]]></category>
		<category><![CDATA[Knowledge Graph]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[methodology]]></category>
		<guid isPermaLink="false">/?p=21941</guid>

					<description><![CDATA[Dit eerste deel richt zich op graphs in hun fundamentele wiskundige vorm.]]></description>
										<content:encoded><![CDATA[
<p><a href="/graphes_applications_et_outils/"><em>Version française</em></a></p>



<p>Dankzij hun vermogen om complexe relaties tussen gegevens te begrijpen en te benutten, worden graphtechnologieën steeds populairder op veel gebieden van kunstmatige intelligentie en gegevensbeheer. Deze blog heeft al meerdere artikels gepubliceerd over verschillende graphtechnologieën, waaronder graph databases [<a href="#footnote-1">1</a>, <a href="#footnote-2">2</a>, <a href="#footnote-3">3</a>] en knowledge graphs [<a href="#footnote-4">4</a>, <a href="#footnote-5">5</a>, <a href="#footnote-6">6</a>].</p>
<p>Maar wat betekent de term &#8216;graph&#8217; eigenlijk? Tussen de wiskundige modellen die als basis dienen, graph databases en knowledge graphs, kan het moeilijk zijn om je weg te vinden en de tools te identificeren die het best passen bij je behoeften. Hierbij komt nog het feit dat werken met graph data op het eerste gezicht complex kan lijken en dat het gebruik van graphalgoritmes niet tot de kernvaardigheden van de meeste data engineers en data scientists behoort. Dit alles kan het creëren en exploiteren van graph data en modellen tot een ontmoedigend vooruitzicht maken.</p>
<p>Dit artikel geeft daarom een overzicht van graphtechnologieën, waarbij de drie bovengenoemde aspecten worden verkend:</p>



<ul class="wp-block-list">
<li>Graphs vanuit een theoretisch oogpunt, hun eigenschappen en hun belangrijkste toepassingen;</li>



<li>Graph databases, gespecialiseerd in de opslag en exploitatie van gekoppelde gegevens;</li>



<li>Knowledge graphs, die kennis semantisch structureren.</li>
</ul>



<p>Daarom is het de bedoeling om deze concepten en de – soms vage – grenzen ertussen te presenteren, en hun toepassingen en de bijbehorende tools en software te belichten.</p>
<p>Dit artikel is opgesplitst in twee delen. Het eerste deel richt zich op graphs in hun fundamentele wiskundige vorm, hoe ze kunnen worden gecodeerd en geëxploiteerd, en de belangrijkste algoritmes en de toepassingen ervan. Het <a href="/graphtechnologieen-toepassingen-en-tools-2/">tweede deel</a> richt zich op graph databases en knowledge graphs, en de bijbehorende tools.</p>



<h2 class="wp-block-heading">Back to basics: graphs als wiskundige structuur</h2>



<p>Laten we eerst definiëren wat een graph is. Deze theoretische basis is cruciaal aangezien de concepten van graph databases en knowledge graphs op deze basis zijn gebouwd. Deze meer geavanceerde concepten kunnen op elk moment worden teruggebracht tot hun onderliggende wiskundige vorm en bij uitbreiding zijn alle modellen en algoritmes die hieronder worden gepresenteerd toepasbaar op graph databases en knowledge graphs.</p>
<p>In zijn meest basale vorm is een graph een wiskundige structuur die bestaat uit een verzameling nodes en arcs die de nodes paarsgewijs verbinden. Nodes stellen meestal objecten of mensen voor en bogen stellen links tussen deze objecten of mensen voor. In het geval van een sociaal netwerk kan een boog bijvoorbeeld een vriendschapsband tussen twee gebruikers voorstellen.</p>
<p>De graph kan zowel gericht als ongericht zijn. In het geval van een ongerichte graph zijn de relaties tussen nodes altijd wederkerig (bijvoorbeeld een vriendschapslink op Facebook), terwijl in een gerichte graph een boog die van node i naar node j gaat, niet noodzakelijk een boog in de tegenovergestelde richting impliceert (bijvoorbeeld een website A die een link heeft naar een website B).</p>
<p>Afhankelijk van de situatie of toepassing kan een graph al dan niet gewogen zijn. Een graph is als gewogen omschreven als er aan elke boog een gewicht wordt toegekend dat varieert van boog tot boog en dat het mogelijk maakt om bepaalde bogen een grotere “kracht” te geven. De interpretatie van deze gewichten hangt af van de context; ze kunnen bijvoorbeeld een mate van verwantschap, gelijkenis, afhankelijkheid, enz. weergeven.</p>
<p>Een graph wordt over het algemeen voorgesteld door een vierkante matrix van dimensie (<em>n</em> × <em>n</em>), waarbij n het aantal nodes in de graph voorstelt, genaamd een adjacency matrix (aangeduid als <strong>A</strong>). Het element op positie (<em>i</em>, <em>j</em>) in de matrix is het gewicht van de boog van node <em>i</em> naar node <em>j</em> als deze bestaat, en anders 0 (zie figuur 1). De adjacency matrix is gewoon een binaire matrix als de graph ongewogen is.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/02/Adjacency.png"><img loading="lazy" decoding="async" width="1024" height="465" src="/wp-content/uploads/2025/02/Adjacency-1024x465.png" alt="" class="wp-image-21940" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/02/Adjacency-1024x465.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/02/Adjacency-300x136.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/02/Adjacency-768x349.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/02/Adjacency.png 1089w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 1: Matrixvoorstelling van een gewogen gerichte graph.</figcaption></figure>



<p>Hier gaat een boog van gewicht 3 van node 1 naar node 3 en een boog van gewicht 5 in de tegenovergestelde richting. De matrix A bevat daarom de waarde 3 op positie (1,3) en de waarde 5 op positie (3,1).</p>
<p>Merk op dat adjacency matrices vaak grotendeels nullen bevatten en daarom over het algemeen worden gecodeerd met behulp van <em>sparse matrices</em> om het geheugen te optimaliseren.</p>
<p>Deze voorstelling van een graph in matrixvorm maakt het veel eenvoudiger om algoritmes op de graph te gebruiken, aangezien veel graphalgoritmes, die soms complex zijn in de vorm van vergelijkingen, vaak gereduceerd kunnen worden tot een reeks elementaire matrixbewerkingen. Dit maakt hun uitvoering zeer efficiënt in wetenschappelijke programmeertalen die geoptimaliseerd zijn voor matrixberekeningen, zoals R, MATLAB, Julia of Python (numpy, scipy).</p>



<h2 class="wp-block-heading">Gebruiken van graphalgoritmes en praktische toepassingen</h2>



<p>Om het nut van een graph beter te begrijpen, kijken we eerst naar de hoofdcategorieën van graphalgoritmes, met voor elke categorie een paar voorbeelden van het praktische gebruik ervan.</p>



<ul class="wp-block-list">
<li>Het optimale pad bepalen om een paar nodes te verbinden.</li>
</ul>



<p>Hierbij kan het gaan om het minimaliseren van het aantal overgangen dat nodig is om van de ene node naar de andere te gaan of, als er kosten zijn verbonden aan elke boog, het vinden van het pad met de laagste kosten. De kosten kunnen gedefinieerd worden als het gewicht van een boog, of gecodeerd worden in een tweede matrix (kostenmatrix, onafhankelijk van de adjacency matrix). De manier waarop de kosten van een boog worden bepaald hangt af van de toepassing, afhankelijk van wat je wilt minimaliseren. Dit kan bijvoorbeeld een maat voor de lengte van de boog zijn (de lengte van een weg), een maat voor de tijd (de tijd die nodig is om de boog over te steken) of financiële kosten. Dit type algoritme kan worden gebruikt in de logistiek om transport te optimaliseren. De bekendste algoritmes zijn de algoritmes <a href="https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm">Dijkstra</a>, <a href="https://en.wikipedia.org/wiki/A*_search_algorithm">A*</a> en <a href="https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm">Bellman-Ford</a>.</p>



<ul class="wp-block-list">
<li>Maatstaven bepalen voor gelijkenis of afstand tussen nodes in een graph.</li>
</ul>



<p>Afhankelijk van de context kan het nuttig zijn om een similariteitsmaat te bepalen tussen twee nodes in een graph om te bepalen hoe dicht ze bij elkaar liggen. Similariteitsmaten worden vaak gebruikt in aanbevelingstoepassingen. Door een consumptiegraph te ontwerpen die gebruikers koppelt aan de producten die ze hebben geconsumeerd, maakt het meten van de similariteit tussen nodes het voor een bepaalde gebruiker mogelijk om gebruikers met een gelijkaardig consumptieprofiel te identificeren, gebaseerd op hun connecties met de producten. Een product wordt meestal aanbevolen aan een gebruiker omdat het door veel vergelijkbare gebruikers is geconsumeerd (<em>user-based recommendation</em>) of omdat het product vergelijkbaar is met producten die de gebruiker al heeft geconsumeerd (<em>item-based recommendation</em>). De bekendste similariteitsmaten zijn over het algemeen gebaseerd op <em>common-neighbour</em> maten (het aantal buren dat twee nodes gemeen hebben), zoals de Jaccard-index of cosinus-similariteit, maar andere methoden houden ook rekening met indirecte buren, zoals de Katz-kernel [<a href="#footnote-12">12</a>] (ook bekend als de “von Neumann kernel”). Zie [<a href="#footnote-13">13</a>] voor enkele klassieke similariteitsmaten en het gebruik ervan in aanbevelingen.</p>
<p>Het tegenovergestelde van een similariteitsmaat is een dissimilariteitsmaat, die toeneemt naarmate twee nodes verder van elkaar verwijderd zijn. Een afstandsmaat is per definitie een dissimilariteit, omdat deze toeneemt naarmate twee nodes verder van elkaar verwijderd zijn. De bekendste en meest intuïtieve maat voor dissimilariteit tussen twee nodes is de lengte van het kortste pad tussen hen.</p>



<ul class="wp-block-list">
<li>De centraliteit meten.</li>
</ul>



<p>Een maat voor de centraliteit van een node of boog, soms ook een <em>prestige measure</em> genoemd, wordt gebruikt om te kwantificeren hoe belangrijk een node of boog is binnen een graph. De bekendste maat voor centraliteit is de score die wordt berekend door het algoritme PageRank [<a href="#footnote-14">14</a>]. PageRank werd oorspronkelijk ontwikkeld en gebruikt door de zoekmachine Google om webpagina&#8217;s te rangschikken. Het is gebaseerd op een willekeurige beweging in een graph waarin elke node een webpagina voorstelt en elke gerichte boog een hyperlink tussen twee pagina&#8217;s voorstelt. Het PageRank-algoritme kent naast het rangschikken van webpagina&#8217;s heel wat andere toepassingen:</p>
<blockquote>
<p>“Google’s PageRank method was developed to evaluate the importance of web-pages via their link structure. The mathematics of PageRank, however, are entirely general and apply to any graph or network in any domain. Thus, PageRank is now regularly used in bibliometrics, social and information network analysis, and for link prediction and recommendation. It’s even used for systems analysis of road networks, as well as biology, chemistry, neuroscience, and physics.” – <em>Gleich (2014) [<a href="#footnote-15">15</a>]</em></p>
</blockquote>
<p>Een ander bekend algoritme dat lijkt op PageRank is het HITS-algoritme (Hyperlink-Induced Topic Search) [<a href="#footnote-16">16</a>].</p>
<p>Als we het over centraliteit hebben, is PageRank vaak het algoritme dat wordt voorgesteld, maar centraliteit kan op verschillende manieren worden begrepen. Het kan bijvoorbeeld verwijzen naar een node of boog die een kritieke intermediair is voor communicatie en informatieoverdracht binnen het netwerk. Centrale nodes identificeren kan het bijvoorbeeld mogelijk maken om informatie optimaal te verspreiden in een netwerk of om nodes of bogen op te sporen die van vitaal belang zijn voor de graph (waarvan de verdwijning de informatieoverdracht in de graph ernstig zou belemmeren). Veel voorkomende maatstaven voor node- of boog-centraliteit op basis van dit principe gebruiken over het algemeen tussen-maatstaven (<em>betweenness centrality</em>).</p>
<p>Centraliteit kan ook worden beschouwd als een maat voor de representativiteit van een node binnen een gemeenschap (in termen van nabijheid tot de andere nodes in de graph), in dit geval gemeten door middel van een maat van nabijheid (<em>closeness centrality</em>). Merk op dat we het gebruik van verschillende centraliteitsalgoritmes in een fraudedetectiecontext al hebben vermeld in eerdere blogposts, met name PageRank (in de vorm van een verspreidingsalgoritme) [<a href="#footnote-7">7</a>] en betweenness centrality [<a href="#footnote-8">8</a>].</p>



<ul class="wp-block-list">
<li>De graph partitioneren.</li>
</ul>



<p>Beter bekend als “<em>clustering</em>”, bestaat graph partitioning uit het groeperen van nodes in communities (clusters) zodat nodes binnen een community “similair” zijn en twee nodes die tot verschillende communities behoren “dissimilair” zijn. Dit partitioneren kan op verschillende manieren gebeuren. Door bijvoorbeeld een maat voor similariteit of dissimilariteit tussen de nodes in de graph te gebruiken en vervolgens een clusteralgoritme zoals k-medoids uit te voeren op basis van deze (dis)similariteiten.</p>
<p>Een andere manier is om direct op de graph te werken en te proberen dichte gebieden binnen de graph te detecteren. Dit kan worden gedaan met behulp van labelpropagatie [<a href="#footnote-17">17</a>], of door het optimaliseren van een objectieve functie die de kwaliteit van de partitionering meet, zoals modulariteit. Het bekendste algoritme voor modulariteitsoptimalisatie is de Louvain-methode [<a href="#footnote-18">18</a>].</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/01/image-2.png"><img loading="lazy" decoding="async" width="508" height="444" src="/wp-content/uploads/2025/01/image-2.png" alt="" class="wp-image-21743" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/01/image-2.png 508w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-2-300x262.png 300w" sizes="auto, (max-width: 508px) 100vw, 508px" /></a><figcaption class="wp-element-caption">Figuur 2: Voorbeeld van een eenvoudige graph met 3 communities.</figcaption></figure>



<p>We hebben het gebruik van ‘graph partitioning’-methodes al genoemd in verschillende blogposts [<a href="#footnote-9">9</a>, <a href="#footnote-10">10</a>]. Deze algoritmes worden met name gebruikt in communicatie en marketing om gerichte advertenties te produceren.</p>



<ul class="wp-block-list">
<li>Kenmerken of representaties extraheren.</li>
</ul>



<p>De traditionele modellen voor <em>machine learning</em> hebben als limiet dat ze alleen rekening houden met de gegevens (continue en categorische variabelen) die betrekking hebben op de waarnemingen, en de informatie negeren die kan worden afgeleid uit de relaties tussen de waarnemingen. Indien er relaties bestaan tussen deze gegevens, kan er een graph worden geconstrueerd en kunnen de machine learning modellen worden verrijkt door nieuwe variabelen uit de graph toe te voegen (er is ook een blogpost over dit onderwerp [<a href="#footnote-11">11</a>]). Deze nieuwe variabelen kunnen bijvoorbeeld een maat voor centraliteit zijn (continue variabele) of het resultaat van partitionering (categorische variabele), of ze kunnen worden verkregen met behulp van ‘graph embedding’-methoden (continue variabelen). Graph embedding moet leiden tot een representatie van de nodes in een multidimensionale ruimte. Deze ruimte wordt zo berekend dat als twee nodes dicht bij elkaar liggen in de graph, ze ook dicht bij elkaar liggen in deze ruimte. Zo&#8217;n ruimte kan worden verkregen met methoden die direct op de graph werken (node2vec [<a href="#footnote-19">19</a>], fastRP [<a href="#footnote-20">20</a>]) of door te werken op basis van bijvoorbeeld similariteiten (kernelPCA [<a href="#footnote-21">21</a>]) of afstanden (t-SNE [<a href="#footnote-22">22</a>]). Zie figuur 3 voor een voorbeeld van een tweedimensionale weergave van een eenvoudige gewogen graph.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/02/Representation_NL.png"><img loading="lazy" decoding="async" width="1024" height="651" src="/wp-content/uploads/2025/02/Representation_NL-1024x651.png" alt="" class="wp-image-21939" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/02/Representation_NL-1024x651.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/02/Representation_NL-300x191.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/02/Representation_NL-768x489.png 768w, https://www.smalsresearch.be/wp-content/uploads/2025/02/Representation_NL.png 1050w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Figuur 3: Weergave van een graph in een 2-dimensionale ruimte met behulp van node2vec (boven) en t-SNE (onder)</figcaption></figure>



<ul class="wp-block-list">
<li>Links voorspellen.</li>
</ul>



<p>Het concept van linkvoorspelling is relatief eenvoudig: het gaat om het inschatten van de waarschijnlijkheid dat er een link bestaat tussen twee nodes. Dit maakt het mogelijk om potentieel ontbrekende bogen (incomplete graph) te detecteren, of om het verschijnen van nieuwe bogen te voorspellen. Aanbevelingsalgoritmes zijn een veelvoorkomend voorbeeld van het voorspellen van links tussen gebruikers en producten, maar deze algoritmes kunnen ook worden gebruikt om potentiële, nog onbekende interacties binnen biologische netwerken te detecteren. Dit type voorspelling wordt vaak verricht met behulp van methoden gebaseerd op overeenkomsten tussen nodes, matrixfactorisatie, probabilistische modellen of kunstmatige neurale netwerken [<a href="#footnote-23">23</a>].</p>



<ul class="wp-block-list">
<li></li>
</ul>



<h2 class="wp-block-heading">Welke hulpmiddelen?</h2>



<p>Zoals hierboven vermeld betekent de weergave van graphs in matrixvorm dat ze efficiënt gebruikt kunnen worden in wetenschappelijke programmeertalen. Er bestaan echter ook library&#8217;s of softwares die gebruikt kunnen worden om graphs te creëren en te exploiteren.</p>
<p>Enkele voorbeelden van library&#8217;s voor het werken met graphs. Deze library&#8217;s kunnen worden gebruikt om een graph object te maken dat op verschillende manieren kan worden opgebouwd. Het kan leeg worden opgebouwd, voordat handmatig nodes en bogen worden toegevoegd, of vanuit een adjacency matrix of een lijst van bogen, of rechtstreeks vanuit bestanden die een beschrijving van de graph bevatten in de vorm van een lijst van nodes en bogen. Voorbeelden van graph-georiënteerde library’s zijn igraph, NetworkX, graph-tool of NetworKit voor Python, igraph voor R en Graphs voor Julia.</p>
<p>Voor gebruikers die al een van deze talen kennen, hebben deze library&#8217;s het voordeel dat ze intuïtief en gemakkelijk te leren zijn en veel voorgeïmplementeerde graph algoritmes bevatten.</p>



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



<p>In het eerste deel van deze blogpost hebben we ons toegespitst op de verschillende graph tools, we hebben de graphtheorie kort ingeleid, alsook de voornaamste toepassingen en algoritmes voor graphs. Het <a href="/graphtechnologieen-toepassingen-en-tools-2/">tweede deel</a> richt zich op graph databases en knowledge graphs, het verschil tussen deze concepten en de bijbehorende tools.</p>



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



<p>Enkele blogposts van Smals Research over graphs:</p>
<p id="footnote-1">[1] <a href="/graph-db-vs-rdbms/">Graph DB vs RDBMS</a></p>
<p id="footnote-2">[2] <a href="/sept-bonnes-raisons-dutiliser-une-graph-database/">Sept (bonnes) raisons d’utiliser une Graph Database</a></p>
<p id="footnote-3">[3] <a href="/een-graph-database-verkennen/">Een graph database verkennen</a></p>
<p id="footnote-4">[4] <a href="/les-graphes-de-connaissance-incontournable-pour-lintelligence-artificielle-2/">Les graphes de connaissance, incontournable pour l’intelligence artificielle</a></p>
<p id="footnote-5">[5] <a href="/les-graphes-de-connaissance-quelques-applications/">Les graphes de connaissance&nbsp;: quelques applications</a></p>
<p id="footnote-6">[6] <a href="/smalls-kg-checklist/">Smals KG Checklist: déterminer si un graphe de connaissances peut résoudre un problème concret</a></p>
<p id="footnote-7">[7] <a href="/un-fraudeur-ne-fraude-jamais-seul/">Un fraudeur ne fraude jamais seul</a></p>
<p id="footnote-8">[8] <a href="/un-fraudeur-ne-fraude-jamais-seul-partie-2/">Un fraudeur ne fraude jamais seul, partie 2</a></p>
<p id="footnote-9">[9] <a href="/ce-quun-reseau-social-peut-nous-apprendre/">Ce qu’un réseau social peut nous apprendre</a></p>
<p id="footnote-10">[10] <a href="/facebook-peut-on-vraiment-cacher-sa-liste-damis/">Facebook&nbsp;: peut-on vraiment cacher sa liste d’amis&nbsp;?</a></p>
<p id="footnote-11">[11] <a href="/ameliorer-le-machine-learning-avec-des-donnees-graphes/">Améliorer le Machine Learning avec des données graphes</a><br /><br />Wetenschappelijke bronnen:</p>
<p id="footnote-12">[12] Katz, L. (1953). A new status index derived from sociometric analysis. Psychometrika, 18(1), 39-43.</p>
<p id="footnote-13">[13] Fouss, F., Pirotte, A., Renders, J. M., &amp; Saerens, M. (2007). Random-walk computation of similarities between nodes of a graph with application to collaborative recommendation. IEEE Transactions on knowledge and data engineering, 19(3), 355-369.</p>
<p id="footnote-14">[14] Page, L., Brin, S., Motwani, R., &amp; Winograd, T. (1998). The pagerank citation ranking: Bringing order to the web. Technical report, Stanford Digital Libraries.</p>
<p id="footnote-15">[15] Gleich, D. F. (2015). PageRank beyond the web. siam REVIEW, 57(3), 321-363.</p>
<p id="footnote-16">[16] Kleinberg, J. M. (1999). Authoritative sources in a hyperlinked environment. Journal of the ACM (JACM), 46(5), 604-632.</p>
<p id="footnote-17">[17] Raghavan, U. N., Albert, R., &amp; Kumara, S. (2007). Near linear time algorithm to detect community structures in large-scale networks. Physical Review E—Statistical, Nonlinear, and Soft Matter Physics, 76(3), 036106.</p>
<p id="footnote-18">[18] Blondel, V. D., Guillaume, J. L., Lambiotte, R., &amp; Lefebvre, E. (2008). Fast unfolding of communities in large networks. Journal of statistical mechanics: theory and experiment, 2008(10), P10008.</p>
<p id="footnote-19">[19] Grover, A., &amp; Leskovec, J. (2016). node2vec: Scalable feature learning for networks. In Proceedings of the 22nd ACM SIGKDD international conference on Knowledge discovery and data mining (pp. 855-864).</p>
<p id="footnote-20">[20] Chen, H., Sultan, S. F., Tian, Y., Chen, M., &amp; Skiena, S. (2019, November). Fast and accurate network embeddings via very sparse random projection. In Proceedings of the 28th ACM international conference on information and knowledge management (pp. 399-408).</p>
<p id="footnote-21">[21] Schölkopf, B., &amp; Smola, A. J. (2002). Learning with kernels: support vector machines, regularization, optimization, and beyond.</p>
<p id="footnote-22">[22] Van der Maaten, L., &amp; Hinton, G. (2008). Visualizing data using t-SNE. Journal of machine learning research, 9(11).</p>
<p id="footnote-23">[23] Lü, L., &amp; Zhou, T. (2011). Link prediction in complex networks: A survey. Physica A: statistical mechanics and its applications, 390(6), 1150-1170.</p>



<hr />
<p><em>Dit is een ingezonden bijdrage van Pierre Leleux, data scientist et network data analyst bij Smals Research. Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Les technologies graphes, leurs applications et leurs outils: un tour d’horizon (Partie 2)</title>
		<link>https://www.smalsresearch.be/graphes_applications_et_outils_2/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Thu, 06 Feb 2025 10:00:00 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[Graph Databases]]></category>
		<category><![CDATA[Information management]]></category>
		<category><![CDATA[Knowledge Graph]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[methodology]]></category>
		<guid isPermaLink="false">/?p=21755</guid>

					<description><![CDATA[Cette seconde partie est consacrée aux bases de données orientées graphe et aux graphes de connaissances.]]></description>
										<content:encoded><![CDATA[
<p><a href="/graphtechnologieen-toepassingen-en-tools-2/"><em>Nederlandstalige versie</em></a></p>



<p>Cet article fait suite à la <a href="/graphes_applications_et_outils/">Partie 1</a>, qui présente les fondamentaux des technologies graphes, algorithmes et applications. Cette seconde partie est consacrée aux bases de données orientées graphe et aux graphes de connaissances, leurs différences et leurs outils.</p>



<h2 class="wp-block-heading">Les bases de données orientées graphe</h2>



<p>A l’instar d’une base de données relationnelle, l’objectif d’une base de données orientée graphe est de pouvoir stocker et gérer des données de manière persistante et d’effectuer des requêtes complexes. La différence étant que les données sont stockées sous la forme d’un graphe, à savoir un ensemble de nœuds interconnectés par le biais d’arcs.</p>
<p>Les bases de données orientées graphe ont plusieurs avantages par rapport aux bases de données relationnelles classiques, car le modèle de graphe permet une traversée simple et optimisée des données via les arcs, là où l’exploration de relations dans une base de données relationnelle peut demander un nombre important de jointures. Plus de détails sur les avantages des bases de données orientées graphe, ainsi que les cas de figure où les utiliser, se trouvent dans les articles de blog [<a href="#footnote-1">1</a>] et [<a href="#footnote-2">2</a>].</p>
<p>Les trois composants de toute base de données orientée graphe sont&nbsp;: nœuds, arcs et propriétés. Ces propriétés peuvent être placées soit sur les nœuds, soit sur les arcs, ou sur les deux. Si nous considérons le petit exemple illustratif dans la Figure 1, le nœud « Paul » peut par exemple être associé à des propriétés telles que sa date de naissance et son adresse, pour les nœuds représentant des films on peut y associer les propriétés telles que l’année de sortie, le budget et son identifiant IMDb, et sur les relations « A_VU » entre un utilisateur et un film, on pourrait associer des propriétés telles que la date de visionnage et la note (sur 5) que l’utilisateur donne au film.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/01/image-4.png"><img loading="lazy" decoding="async" width="940" height="395" src="/wp-content/uploads/2025/01/image-4.png" alt="" class="wp-image-21758" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/01/image-4.png 940w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-4-300x126.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-4-768x323.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></a><figcaption class="wp-element-caption">Figure 1&nbsp;: Exemple de nœuds et d’arcs avec des propriétés dans Neo4J.</figcaption></figure>



<p>Il est à noter que les algorithmes de graphe que nous avons présentés dans la <a href="/graphes_applications_et_outils/">Partie 1</a> ne sont souvent que peu ou pas implémentés dans les logiciels de bases de données orientées graphe, à quelques exceptions près (Neo4j et TigerGraph disposent d’une libraire « Graph Data Science (GDS) » contenant plusieurs algorithmes). Il est donc généralement nécessaire d’exporter le graphe (ou une partie de celui-ci) vers un outil d’analyse.</p>



<h2 class="wp-block-heading">Les outils pour bases de données orientées graphe</h2>



<p>Passons rapidement en revue quelques-uns des outils les plus connus. Notez que tous les outils listés ci-après sont compatibles avec les propriétés <a href="https://fr.wikipedia.org/wiki/Propri%C3%A9t%C3%A9s_ACID">ACID</a>. Il existe un grand nombre d’outils pour la gestion de base de données graphe, cet article n’en mentionne qu’une partie. N’hésitez pas à aller jeter un coup d’œil à une liste plus détaillée trouvable <a href="https://db-engines.com/en/ranking/graph+dbms">ici</a>.</p>
<ol>
<li>Neo4j</li>
</ol>
<p>Neo4j offre l’avantage d’avoir un format de graphe natif, ce qui rend très efficace la traversée du graphe (et donc, les requêtes). Les requêtes se font en Cypher, un langage facile à prendre en main, et Neo4J est bien documenté et dispose d’une grande communauté. Neo4J dans sa version « community » est gratuit, mais une version payante existe (Neo4j Enterprise), et la version gratuite peut poser quelques soucis de scalabilité face à de très grandes quantités de données.</p>
<ol start="2">
<li>ArangoDB</li>
</ol>
<p>ArangoDB propose un modèle de données flexible (multi-modèle), intégrant un modèle graphe, un modèle document (basé sur des objets JSON) et un modèle clé-valeur. Il dispose de son propre langage de requêtes AQL (Arango Query Language) qui peut être plus compliqué à prendre en main que Cypher en raison du multi-modèle sous-jacent à ArangoDB. C’est un logiciel payant, bien qu’une version open source existe (community edition), mais est (évidement) plus limitée que la version payante.</p>
<ol start="3">
<li>TigerGraph</li>
</ol>
<p>TigerGraph est un outil payant, optimisé pour pouvoir être utilisés sur de très grandes bases de données. Les requêtes se font via le langage GSQL, qui est un langage permettant d’effectuer de nombreuses tâches, mais plus compliqué à prendre en main que Cypher. TigerGraph dispose de nombreux algorithmes implémentés via la librairie GDS.</p>
<ol start="4">
<li>Memgraph</li>
</ol>
<p>Memgraph est un outil particulier en ce sens qu’il stocke les données directement en mémoire (dans la RAM). Cela lui permet d’avoir des très hautes performances pour le requêtage, mais en contrepartie cela rend son utilisation difficile, ou du moins coûteuse en termes d’infrastructure, lorsque le graphe est de grande taille, puisqu’il faut avoir suffisamment de RAM que pour stocker les données. Memgraph s’utilise donc généralement lorsque les performances sont la première priorité. Les requêtes se font en Cypher.</p>
<ol start="5">
<li>GraphDB</li>
</ol>
<p>GraphDB utilise un modèle de graphe bien spécifique appelé Resource Description Framework (RDF). Ce framework, qui sera discuté un peu plus en détails dans la section relative aux graphes de connaissances, a son langage de requête propre nommé SPARQL. Il existe en version gratuite open-source (graphDB Free) et en version entreprise payante (graphDB Enterprise).</p>
<ol start="6">
<li>Apache TinkerPop et ses implémentations</li>
</ol>
<p>Il s’agit d’un framework open-source qui vise à définir un modèle de base de données graphes, ainsi qu’un langage de requête nommé « Gremlin ». Il est utilisé dans de nombreux logiciels de gestion de base de données orientées graphe, tels que JanusGraph (un logiciel open-source), Amazon Neptune qui propose d’autres modèles que celui de TinkerPop tels que RDF, ou encore des outils de gestion de base de données non spécialisés en graphe, tels qu’Azure Cosmos DB.</p>



<h2 class="wp-block-heading">Les graphes de connaissances</h2>



<p>Avant de s’intéresser aux pratiques et outils, commençons dans un premier temps par définir ce qu’est un graphe de connaissances et ce qui le distingue d’une base de données orientée graphe. Il s’agit d’un graphe qui met l’accent sur la sémantique et sur l’inférence. Chaque nœud représente un concept et chaque arc une relation. Comme nous l’avons déjà vu dans les articles de blog [<a href="#footnote-3">3</a>, <a href="#footnote-4">4</a>], un graphe de connaissances se définit comme un graphe remplissant trois conditions [<a href="#footnote-5">5</a>]&nbsp;:</p>
<ol>
<li>L’intégration d’informations en provenance de différentes sources hétérogènes.</li>
</ol>
<p>Un graphe de connaissances rassemble et combine des données issues de diverses sources (structurées ou non) de manière cohérente.</p>
<ol start="2">
<li>L’utilisation d’une ontologie.</li>
</ol>
<p>Une ontologie décrit de façon formelle les concepts et les relations présentes dans le graphe, ainsi que les éventuelles contraintes et règles. Il s’agit donc d’un modèle structuré qui fournit les fondations sémantiques afin de permettre des opérations de raisonnement et des tests de cohérence. Par exemple, un schéma d’ontologie (voir Figure 2), également appelé graphe ontologique, fournit une représentation des types d&#8217;entités et des relations d’un graphe de connaissances, fournissant ainsi une structure conceptuelle sans contenir de données spécifiques.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/01/image-5.png"><img loading="lazy" decoding="async" width="872" height="559" src="/wp-content/uploads/2025/01/image-5.png" alt="" class="wp-image-21761" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/01/image-5.png 872w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-5-300x192.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-5-768x492.png 768w" sizes="auto, (max-width: 872px) 100vw, 872px" /></a><figcaption class="wp-element-caption">Figure 2&nbsp;: Exemple de schéma d’ontologie</figcaption></figure>



<ol start="3">
<li>L’inférence d’informations implicites sur base d’informations explicites.</li>
</ol>
<p>Il est possible de trouver des informations qui n’étaient pas présentes dans les données initiales sur base de règles d’inférence (Voir Figure 3).</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/01/image-6.png"><img loading="lazy" decoding="async" width="748" height="287" src="/wp-content/uploads/2025/01/image-6.png" alt="" class="wp-image-21762" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/01/image-6.png 748w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-6-300x115.png 300w" sizes="auto, (max-width: 748px) 100vw, 748px" /></a><figcaption class="wp-element-caption">Figure 3&nbsp;: Exemple d’inférence. Tiré d’un précédent <a href="/les-graphes-de-connaissance-incontournable-pour-lintelligence-artificielle-2/">article de blog</a>.</figcaption></figure>



<h2 class="wp-block-heading">Un aperçu du modèle RDF (Resource Description Framework)</h2>



<p>Initialement conçu pour la description formelle de ressources web et leurs métadonnées, le modèle RDF est fréquemment utilisé pour les graphes de connaissances car il permet un raisonnement sémantique robuste et une très grande interopérabilité.</p>
<p>Un document en RDF prend la forme d’un ensemble de <strong>triplets RDF</strong>, chaque triplet est une association&nbsp;: sujet (ressource à décrire), prédicat (propriété de la ressource), objet (donnée ou autre ressource).</p>
<p>Par exemple&nbsp;:</p>
<p><code>:Alice&nbsp;:knows&nbsp;:Bob .<br />:Alice&nbsp;:livesIn&nbsp;:Paris .<br />:Alice&nbsp;:age 30 .</code></p>
<p>Ces triplets représentent donc aussi bien des relations entre nœuds (par exemple : la relation entre Alice et Bob) que des propriétés (l’âge d’Alice).</p>
<p>Une spécificité de RDF est qu’il nécessite que chaque élément d’un triplet (à l’exception de l’objet s’il s’agit d’une valeur simple, tel que la valeur 30 pour l’âge d’Alice) soit identifié par un URI (<em>Uniform Resource Identifier</em>) ou IRI (<em>Internationalized Resource Identifier</em>). Cela permet une grande interopérabilité car cela évite la création de doublons lorsque plusieurs sources d’information sont combinées. Si nous reprenons les triplets utilisés précédemment, nous obtenons le fragment suivant (en langage turtle) :</p>
<p><code>&lt;http://example.org/Alice&gt; &lt;http://example.org/knows&gt; &lt;http://example.org/Bob&gt; .<br />&lt;http://example.org/Alice&gt; &lt;http://example.org/livesIn&gt; &lt;http://example.org/Paris&gt; .<br />&lt;http://example.org/Alice&gt; &lt;http://example.org/age&gt; "30"^^&lt;http://www.w3.org/2001/XMLSchema#integer&gt; .</code></p>
<p>L&#8217;utilisation de RDF implique donc d’avoir un URI afin de pouvoir identifier tous les concepts (sujets, prédicats et objets) du graphe à l’instar d’une clé primaire dans les bases de données relationnelles.</p>
<p>De plus, il existe deux outils permettant d’ajouter de la signification sémantique aux données RDF, en décrivant les relations afin de permettre le raisonnement, à savoir RDFS (<em>RDF Schema</em>) et OWL (<em>Web Ontology Language</em>). Comme nous l’avons vu, RDF impose que chaque concept soit identifié par un URI. RDFS et OWL fournissent un ensemble prédéfini d’URI pour des concepts fréquemment utilisés, auxquels on peut faire référence dans RDF. Ceci permet d’une part d’avoir un vocabulaire commun standardisé, ce qui facilite l’intégration d’autres bases de données, et d’autre part d’établir des règles d’inférence. En effet, puisque OWL et RDFS proposent des <strong>concepts standardisés</strong>, cela permet à des « raisonneurs » basés sur OWL (tels que FaCT++ ou HermiT) d’inférer les relations implicites de façon systématique ou de détecter des contradictions, sur base de l’ontologie.</p>
<p>Les requêtes sur une base de données RDF se font via SPARQL.</p>



<h2 class="wp-block-heading">Les alternatives à RDF, et les outils pour travailler avec un graphe de connaissances</h2>



<p>Bien évidemment, un graphe de connaissances ne nécessite pas forcément l’utilisation du modèle RDF. Un graphe sera considéré comme graphe de connaissances tant que les 3 conditions décrites en début de section sur les graphes de connaissances sont remplies. Il est donc parfaitement possible de créer un graphe de connaissances dans un outil classique de gestion de base de données orientée graphe, tant que l’implémentation combine des données de plusieurs sources, qu’elle est conforme à une ontologie et qu’elle peut être utilisée pour de l’inférence sémantique.</p>
<p>La principale force du modèle RDF est son niveau de standardisation élevé. D’une part, via son exigence d’identification par URI, ainsi que son vocabulaire et son langage de requête standardisés, elle permet une haute interopérabilité. D’autre part, les extension RDFS et OWL permettent d’offrir une richesse sémantique rendant possible un raisonnement automatique. En contrepartie, sa complexité limite son adoption dans des applications business où cette rigueur sémantique n’est pas forcément nécessaire et où l’utilisation d’un modèle de graphe plus simple (tel que Neo4j ou TigerGraph) suffit. L’utilisation de modèles plus simples offre l’avantage d’être plus facile et rapide à mettre en place et d’offrir des performances de requêtage optimisées, mais au prix de la perte de la richesse sémantique offerte par RDF.</p>
<p>Cette section présente des outils (de façon non exhaustive) relatifs à RDF mais, comme mentionné, les outils précédemment cités pour les bases de données orientées graphe restent valides pour créer un graphe de connaissances tant que les <strong>conditions</strong> sont remplies.</p>
<p>Voici une liste de quelques outils liés aux graphes de connaissances en RDF :</p>
<ul>
<li><strong>La conception d’ontologies :</strong> l’outil open-source <a href="https://protege.stanford.edu/">Protégé</a> est fréquemment utilisé pour créer des ontologies. Le site <a href="https://schema.org/">schema.org</a> fournit un grand nombre de schéma et vocabulaires standards pour différents domaines, mais est généralement plutôt utilisé pour des graphes de connaissances relatifs aux données web.</li>
<li><strong>La transformation de données vers RDF :</strong> l’outil <a href="https://www.w3.org/TR/r2rml/">R2RML</a> permet de transformer des données relationnelles vers RDF. Nous pouvons aussi mentionner <a href="https://d2rq.org/">D2RQ</a>, qui donne accès à une base de données relationnelle via un graphe de connaissances RDF virtuel.</li>
<li><strong>Le stockage de données :</strong> en plus des solutions mentionnées précédemment (GraphDB et Amazon Neptune), nous pouvons aussi mentionner BlazeGraph et Apache Jena (open-source) ou encore Stardog et AllegroGraph (solutions commerciales).</li>
<li><strong>Les raisonneurs OWL :</strong> il existe de nombreux raisonneurs OWL. Tous ne sont cependant pas forcément activement maintenus ou toujours utilisables. La liste de raisonneurs OWL la plus récente que nous ayons pu trouver date de 2023 et est accessible <a href="https://arxiv.org/pdf/2309.06888">ici</a> [<a href="#footnote-6">6</a>].</li>
</ul>
<p>Terminons par mentionner le framework RDF4J (framework Java) et rdflib (libraire python) permettant d’interagir avec des données RDF.</p>



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



<p>Terminons par une rapide synthèse des concepts clés qui séparent un graphe mathématique d’une base de données orientée graphe et d’un graphe de connaissances.</p>
<p>Un graphe mathématique est un ensemble de nœuds et d’arcs facilement représentable sous forme matricielle afin d’y appliquer des algorithmes. C’est la structure sous-jacente de toute base de données orientée graphe ou graphe de connaissances.</p>
<p>Une base de données graphe comporte un ensemble de nœuds, d’arcs et de propriétés. L’accent est mis sur le stockage de grandes quantités de données au sein d’une structure graphe et sur l’optimisation du requêtage.</p>
<p>Un graphe de connaissances a pour but de représenter le savoir au sein d’un graphe mettant l’accent sur :</p>
<ul>
<li><strong>La sémantique :</strong> Le graphe suit une ontologie et les relations ont une signification.</li>
<li><strong>L’intégration :</strong> Diverses sources de données sont liées dans un graphe unifié.</li>
<li><strong>L’inférence :</strong> La capacité à dériver des connaissances via un raisonnement.</li>
</ul>
<p>Il est donc concentré sur l’intégration et l’enrichissement sémantique des données.</p>
<p>Il va sans dire que cet article ne fait qu’effleurer la surface de la vaste littérature des graphes et leurs applications diverses, et que nombreux points mériteraient un développement plus poussé et feront d’ailleurs sans doute l’objet de futurs articles.</p>



<h2 class="wp-block-heading">Références</h2>



<p id="footnote-1">[1] <a href="/graph-db-vs-rdbms/">Graph DB vs RDBMS</a></p>
<p id="footnote-2">[2] <a href="/sept-bonnes-raisons-dutiliser-une-graph-database/">Sept (bonnes) raisons d’utiliser une Graph Database</a></p>
<p id="footnote-3">[3] <a href="/les-graphes-de-connaissance-incontournable-pour-lintelligence-artificielle-2/">Les graphes de connaissance, incontournable pour l’intelligence artificielle</a></p>
<p id="footnote-4">[4] <a href="/smalls-kg-checklist/">Smals KG Checklist: déterminer si un graphe de connaissances peut résoudre un problème concret</a></p>
<p id="footnote-5">[5] Ehrlinger, L., &amp; Wöß, W. (2016). Towards a definition of knowledge graphs. <i>SEMANTiCS 2016</i>, <i>48</i>(1-4), 2.</p>
<p id="footnote-6">[6] <a href="https://arxiv.org/pdf/2309.06888">Abitch, K., (2023). &#8220;OWL Reasoners still useable in 2023&#8221;</a></p>
<hr />
<p><em>Ce post est une contribution individuelle de Pierre Leleux, data scientist et network data analyst chez Smals Research. Cet article est écrit en son nom propre et n’impacte en rien le point de vue de Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Les technologies graphes, leurs applications et leurs outils : un tour d’horizon (Partie 1)</title>
		<link>https://www.smalsresearch.be/graphes_applications_et_outils/</link>
		
		<dc:creator><![CDATA[Pierre Leleux]]></dc:creator>
		<pubDate>Tue, 28 Jan 2025 10:00:00 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[Graph Databases]]></category>
		<category><![CDATA[Information management]]></category>
		<category><![CDATA[Knowledge Graph]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[methodology]]></category>
		<guid isPermaLink="false">/?p=21737</guid>

					<description><![CDATA[Cette première partie est consacrée aux graphes dans leur forme mathématique fondamentale.]]></description>
										<content:encoded><![CDATA[
<p><a href="/graphtechnologieen-toepassingen-en-tools/"><em>Nederlandstalige versie</em></a></p>



<p>Grâce à leur capacité à comprendre et exploiter les relations complexes entre les données, les technologies relatives aux graphes ont actuellement le vent en poupe, gagnant en popularité dans de nombreux domaines de l’intelligence artificielle et la gestion de données. Plusieurs articles ont d’ailleurs déjà été postés sur ce blog concernant différentes technologies de graphes, notamment sur les bases de données orientées graphe (graph database) [<a href="#footnote-1">1</a>, <a href="#footnote-2">2</a>, <a href="#footnote-3">3</a>] et les graphes de connaissances (knowledge graph) [<a href="#footnote-4">4</a>, <a href="#footnote-5">5</a>, <a href="#footnote-6">6</a>].</p>
<p>Mais que recouvre réellement le terme « graphe »&nbsp;? Entre les modèles mathématiques qui servent de fondation, les bases de données orientées graphe et les graphes de connaissances, il peut être difficile de s’y retrouver et d’identifier les outils adaptés à ses besoins. Ajoutez à cela le fait que travailler sur des données organisées en réseau peut sembler complexe à première vue et que l’utilisation d’algorithmes de graphe ne fait pas partie des compétences de base de la plupart des data engineers et data scientists, et tout cela peut rendre décourageant la création et l’exploitation de données et de modèles de graphes.</p>
<p>Cet article a donc pour objectif de faire le point sur les technologies graphes, en explorant les 3 aspects mentionnés ci-dessus&nbsp;:</p>
<ul>
<li>Les graphes d’un point de vue théorique, leurs propriétés, leurs applications principales ;</li>
<li>Les bases de données orientées graphe, spécialisées dans le stockage et l’exploitation de données connectées ;</li>
<li>Les graphes de connaissances qui structurent le savoir de manière sémantique.</li>
</ul>
<p>Le but est donc de présenter ces concepts, les frontières – parfois floues – qui les séparent, ainsi que de mettre en lumière leurs utilisations et les outils et logiciels qui y sont associés.</p>
<p>Cet article est divisé en deux parties. Cette première partie est consacrée aux graphes dans leur forme mathématique fondamentale, comment les encoder et les exploiter, ainsi qu&#8217;aux principaux algorithmes et leurs applications. La <a href="/graphes_applications_et_outils_2/">seconde partie</a> portera sur les bases de données orientées graphe et graphes de connaissances et les outils qui y sont associés.</p>



<h2 class="wp-block-heading">Retour aux fondamentaux&nbsp;: les graphes en tant que structure mathématique</h2>



<p>Avant toute chose, commençons par définir ce qu’est un graphe. Cette base théorique est cruciale car c’est dessus que se construisent les concepts de base de données orientée graphe et de graphe de connaissances. À tout moment, ces concepts plus avancés peuvent être ramenés à leur forme mathématique sous-jacente et, par extension, tous les modèles et algorithmes présentés ci-dessous sont applicables à des bases de données orientées graphe et graphes de connaissances.</p>
<p>Dans sa forme la plus fondamentale, un graphe est une structure mathématique constituée d’un ensemble de nœuds et d’arcs qui joignent des nœuds deux à deux. Les nœuds représentent typiquement des objets ou des personnes, et les arcs représentent des liens entre ces objets ou personnes. Par exemple, dans le cas d’un réseau social, un arc peut représenter un lien d’amitié entre deux utilisateurs.<br />Le graphe peut être soit dirigé soit non-dirigé. Dans le cas d’un graphe non-dirigé, les relations entre les nœuds sont toujours réciproques (par exemple, un lien d’amitié sur Facebook) alors que dans un graphe dirigé, un arc allant d’un nœud <em>i</em> à un nœud <em>j</em> n’implique pas forcément d’arc de sens opposé (par exemple, un site internet A ayant un hyperlien qui pointe vers un site B).</p>
<p>Suivant la situation ou l’application, un graphe peut aussi être pondéré ou non. Un graphe est dit pondéré lorsqu’un poids est associé à chaque arc, qui varie d’un arc à l’autre, et qui permet de donner plus de « force » à certains arcs. L’interprétation de ces poids dépend du contexte, ces poids peuvent par exemple représenter un degré d’affinité, de similarité, de dépendance, etc.</p>
<p>Un graphe est généralement représenté par une matrice carrée de dimension (<em>n</em> × <em>n</em>), où n est le nombre de nœuds du graphe, appelée matrice d’adjacence (notée <strong>A</strong>). L’élément en position (<em>i</em>, <em>j</em>) dans la matrice vaut le poids de l’arc allant du nœud <em>i</em> au nœud <em>j</em> s’il existe, et 0 sinon (voir Figure 1). La matrice d’adjacence est simplement une matrice binaire lorsque le graphe n’est pas pondéré.</p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2025/01/image-1.png"><img loading="lazy" decoding="async" width="736" height="330" src="/wp-content/uploads/2025/01/image-1.png" alt="" class="wp-image-21740" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/01/image-1.png 736w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-1-300x135.png 300w" sizes="auto, (max-width: 736px) 100vw, 736px" /></a><figcaption class="wp-element-caption">Figure 1&nbsp;: Représentation matricielle d’un graphe pondéré dirigé.</figcaption></figure>



<p>Dans l’exemple illustratif, il y a un arc de poids 3 allant du nœud 1 au nœud 3, et un arc de poids 5 allant dans le sens inverse. La matrice <strong>A</strong> contient donc la valeur 3 en position (1,3) et la valeur 5 en position (3,1).</p>
<p>Il est à noter que les matrices d’adjacence contiennent souvent une très large majorité de zéros, et sont donc généralement encodées via des matrices creuses (<em>sparse matrix</em>) afin d’optimiser la mémoire.</p>
<p>Cette représentation d’un graphe sous forme d’une matrice facilite fortement l’utilisation d’algorithmes sur le graphe, car nombre d’algorithmes de graphe, parfois complexes sous forme d’équations, peuvent souvent être résumés à une série d’opérations matricielles élémentaires. Ceci rend leur exécution très efficace dans des langages de programmation scientifiques optimisés pour les calculs matriciels, tels que R, MATLAB, Julia ou Python (numpy, scipy).</p>



<h2 class="wp-block-heading">Utilisations d’algorithmes de graphe et applications pratiques</h2>



<p>Pour mieux comprendre l’intérêt d’un graphe, commençons dans un premier temps par regarder les grandes catégories d’algorithmes de graphe, avec, pour chaque catégorie, quelques exemples d’utilisation pratique de ceux-ci.</p>
<ul>
<li>Déterminer le chemin optimal permettant de joindre une paire de nœuds.</li>
</ul>
<p>Il peut simplement s’agir de minimiser le nombre de transitions nécessaires pour passer d’un nœud à l’autre, ou alors, si un coût est associé à chaque arc, de trouver le chemin associé au coût le plus faible. Le coût peut-être défini en tant que poids d’un arc, ou encodé dans une seconde matrice (matrice de coût, indépendante de la matrice d’adjacence). La façon dont le coût d’un arc est déterminé dépend de l’application, en fonction de ce que l’on souhaite minimiser. Il peut s’agir, par exemple, d’une mesure de longueur de l’arc (telle que la longueur d’une route), une mesure de temps (le temps nécessaire pour franchir l’arc) ou un coût financier. Ce genre d’algorithme peut être utilisé en logistique pour optimiser le transport. Les algorithmes les plus connus en la matière étant les algorithmes de <a href="https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm">Dijkstra</a>, <a href="https://en.wikipedia.org/wiki/A*_search_algorithm">A*</a>, ou encore l’algorithme de <a href="https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm">Bellman-Ford</a>.</p>
<ul>
<li>Établir des mesures de similarité ou de distance entre des nœuds d’un graphe.</li>
</ul>
<p>Suivant le contexte, il peut être intéressant d’établir une mesure de similarité entre deux nœuds d’un graphe afin de déterminer à quel point ils sont proches l’un de l’autre. L’utilisation de mesures de similarité est une approche souvent utilisée dans les applications de recommandation. En construisant un graphe de consommation qui lie les utilisateurs aux produits qu’ils ont consommés, mesurer la similarité entre les nœuds permet d’identifier, pour un utilisateur donné, des utilisateurs ayant un profil de consommation similaire, en se basant sur leurs liens avec les produits. Typiquement, un produit sera recommandé à un utilisateur soit parce qu’il a été consommé par de nombreux utilisateurs similaires (<em>user-based recommendation</em>) soit car le produit est similaire à ceux déjà consommés par l’utilisateur (<em>item-based recommendation</em>). Les mesures de similarité les plus connues se basent généralement sur des mesures de voisinage commun (le nombre de voisins en commun que possèdent deux nœuds), telles que l’indice de Jaccard ou la similarité cosinus, mais d’autres méthodes permettent de prendre aussi en compte le voisinage indirect, telles que le kernel de Katz [<a href="#footnote-12">12</a>] (aussi connu sous le nom de « von Neumann kernel »). Pour voir quelques mesures de similarité classiques et leur utilisation en recommandation, voir [<a href="#footnote-13">13</a>].</p>
<p>L’opposé d’une mesure de similarité est une mesure de dissimilarité, qui augmente à mesure que les deux nœuds sont différents. Une mesure de distance est, par définition, une dissimilarité, puisqu’elle augmente lorsque deux nœuds sont éloignés. La mesure de dissimilarité la plus connue et la plus intuitive entre deux nœuds est la longueur du plus court chemin qui les sépare.</p>
<ul>
<li>Mesurer la centralité.</li>
</ul>
<p>Une mesure de centralité d’un nœud ou d’un arc, parfois aussi appelée mesure de prestige, sert à quantifier à quel point un nœud ou un arc est important au sein d’un graphe. La mesure de centralité la plus connue est, de loin, le score calculé par l’algorithme PageRank [<a href="#footnote-14">14</a>]. Initialement développé et utilisé par le moteur de recherche Google pour hiérarchiser les pages web, PageRank se base sur une marche aléatoire sur un graphe où chaque nœud représente une page web et chaque arc dirigé représente un hyperlien entre deux pages. L’algorithme PageRank trouve de nombreuses applications au-delà de la hiérarchisation de pages web&nbsp;:</p>
<blockquote>
<p style="text-align: center;">“Google’s PageRank method was developed to evaluate the importance of web-pages via their link structure. The mathematics of PageRank, however, are entirely general and apply to any graph or network in any domain. Thus, PageRank is now regularly used in bibliometrics, social and information network analysis, and for link prediction and recommendation. It’s even used for systems analysis of road networks, as well as biology, chemistry, neuroscience, and physics.” – <em>Gleich (2014) [<a href="#footnote-15">15</a>]</em></p>
</blockquote>
<p>Un autre algorithme très connu, similaire à PageRank, est l’algorithme HITS (Hyperlink-Induced Topic Search) [<a href="#footnote-16">16</a>].</p>
<p>Lorsque l’on parle de centralité, PageRank est souvent l’algorithme présenté, cependant, la centralité peut se comprendre de plusieurs manières. Il peut par exemple s’agir d’un nœud ou d’un arc constituant un intermédiaire critique pour la communication et la transmission d’information au sein du réseau. Repérer des nœuds centraux peut par exemple permettre d’optimiser la diffusion d’information dans un réseau ou de détecter des nœuds ou des arcs vitaux au graphe (dont la disparition nuirait fortement à la transmission d’information dans le graphe). Des mesures fréquentes de centralité de nœuds ou d’arcs se basant sur ce principe utilisent généralement des mesures « d’intermédiarité » (<em>betweenness centrality</em>).</p>
<p>La centralité peut aussi se comprendre comme la mesure de la représentativité d’un nœud au sein d’une communauté (en termes de proximité vis-à-vis des autres nœuds du graphe), se mesurant ici plutôt avec une mesure de proximité (<em>closeness centrality</em>). Il est à noter que nous avons déjà mentionné l’utilisation de différents algorithmes de centralité dans un cadre de détection de fraude dans des articles de blog précédents, notamment PageRank (sous forme d’un algorithme de diffusion) [<a href="#footnote-7">7</a>] et la betweenness centrality [<a href="#footnote-8">8</a>].</p>
<ul>
<li>Partitionner le graphe.</li>
</ul>
<p>Plus connu sous le nom de « <em>clustering</em> », le partitionnement de graphe consiste à regrouper des nœuds en communautés (<em>clusters</em>) tels que les nœuds au sein d’une communauté sont « similaires » et deux nœuds appartenant à des communautés différentes sont dissimilaires. Ce partitionnement peut se faire de plusieurs manières. Par exemple en utilisant une mesure de similarité ou de dissimilarité entre les nœuds du graphe, puis en exécutant un algorithme de clustering tel que le <em>k</em>-médoïdes sur base de ces (dis-)similarités.</p>
<p>Ou alors, en travaillant directement sur le graphe en cherchant à détecter des zones denses dans celui-ci. Cela peut se faire via de la propagation de label [<a href="#footnote-17">17</a>], ou via l’optimisation d’une fonction objectif mesurant la qualité du partitionnement, telle que la modularité. L’algorithme d’optimisation de la modularité le plus célèbre est la méthode de Louvain [<a href="#footnote-18">18</a>].</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2025/01/image-2.png"><img loading="lazy" decoding="async" width="508" height="444" src="/wp-content/uploads/2025/01/image-2.png" alt="" class="wp-image-21743" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/01/image-2.png 508w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-2-300x262.png 300w" sizes="auto, (max-width: 508px) 100vw, 508px" /></a><figcaption class="wp-element-caption">Figure 2&nbsp;: Exemple de graphe simple avec 3 communautés.</figcaption></figure>



<p>Nous avions déjà mentionné l’utilisation des méthodes de partitionnement de graphes dans plusieurs articles de blog [<a href="#footnote-9">9</a>, <a href="#footnote-10">10</a>], ces algorithmes sont utilisés notamment en communication et marketing afin de pouvoir réaliser des annonces ciblées.</p>
<ul>
<li>Extraire des caractéristiques ou des représentations.</li>
</ul>
<p>Une des limites des modèles de <em>machine learning</em> classique est qu’ils considèrent uniquement les données (variables continues et catégorielles) relatives aux observations, et ignorent l’information qui pourrait être tirée des relations entre les observations. Si des relations existent entre ces données, un graphe peut être construit, et les modèles de <em>machine learning</em> peuvent être enrichis via l’ajout de nouvelles variables extraites du graphe (il y a aussi un article de blog à ce sujet [<a href="#footnote-11">11</a>]). Ces nouvelles variables peuvent par exemple être une mesure de centralité (variable continue) ou le résultat d’un partitionnement (variable catégorielle), ou encore être obtenues via des méthodes de <em>graph embedding</em> (variables continues). Le <em>graph embedding</em> vise à obtenir une représentation des nœuds dans un espace multidimensionnel. Cet espace est calculé de sorte que, si deux nœuds sont proches dans le graphe, ils le seront aussi dans cet espace. Cet espace peut par exemple s’obtenir via des méthodes travaillant directement sur le graphe (node2vec [<a href="#footnote-19">19</a>], fastRP [<a href="#footnote-20">20</a>]) ou en travaillant sur base de similarités (kernelPCA [<a href="#footnote-21">21</a>]) ou de distances (t-SNE [<a href="#footnote-22">22</a>]) par exemple. Voir Figure 3 pour un exemple de représentation en 2 dimensions d&#8217;un graphe pondéré simple.</p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2025/01/image-3.png"><img loading="lazy" decoding="async" width="940" height="596" src="/wp-content/uploads/2025/01/image-3.png" alt="" class="wp-image-21744" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/01/image-3.png 940w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-3-300x190.png 300w, https://www.smalsresearch.be/wp-content/uploads/2025/01/image-3-768x487.png 768w" sizes="auto, (max-width: 940px) 100vw, 940px" /></a><figcaption class="wp-element-caption">Figure 3&nbsp;: Représentation d’un graphe dans un espace à 2 dimensions via node2vec (haut) et t-SNE (bas)</figcaption></figure>



<ul>
<li>Prédire des liens.</li>
</ul>
<p>Le concept de prédiction de lien est relativement explicite, il s’agit d’estimer la probabilité qu’un lien existe entre 2 nœuds. Cela permet de détecter des potentiels arcs manquants (graphe incomplet), ou de prédire l’apparition de nouveaux arcs. Les algorithmes de recommandations sont un exemple courant de prédiction de lien utilisateur-produit, mais ces algorithmes peuvent aussi servir à détecter des potentielles interactions encore inconnues à l’intérieur de réseaux biologiques. Ce genre de prédiction se fait souvent via des méthodes basées sur des similarités entre nœuds, de la factorisation matricielle, des modèles probabilistes ou des réseaux de neurones artificiels [<a href="#footnote-23">23</a>].</p>



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



<p>Comme mentionné précédemment, la représentation de graphes sous forme matricielle permet de les exploiter de façon efficace via des langages de programmation scientifiques. Cependant, il existe aussi des librairies ou logiciels permettant de créer et exploiter des données de graphe.</p>
<p>Voici quelques exemples de librairies dédiées au travail sur les graphes. Ces librairies permettent de créer un objet graphe, qui peut être construit de plusieurs manières. Il peut être construit à vide, avant d’y ajouter manuellement des nœuds et des arcs, ou alors à partir d’une matrice d’adjacence ou d’une liste d’arcs, ou bien encore directement depuis des fichiers contenant une description du graphe sous la forme d’une liste de nœuds et d’arcs. Quelques exemples de librairies orientées graphe incluent igraph, networkx, graph-tool ou networkit pour Python, igraph pour R et Graphs pour Julia.</p>
<p>Pour un utilisateur ayant déjà des connaissances dans l’un de ces langages, ces libraires ont l’avantage d’être intuitives et faciles à prendre en main, et contiennent de nombreux algorithmes de graphe pré-implémentés.</p>
<p>Il existe aussi de nombreux logiciels prévus pour l’analyse du contenu de bases de données orientées graphe, tels que Gephi ou Cytoscape (pour une liste plus détaillée, nous vous invitons à vous référer à l’un de nos précédents articles sur le sujet&nbsp;: [<a href="#footnote-3">3</a>]). Il s’agit bien de logiciels créés pour des analyses ponctuelles ou des explorations visuelles des relations dans des ensembles de données, mais qui ne sont pas conçus pour intégrer et gérer de grandes quantités de données de manière continue comme le ferait une base de données orientée graphe.</p>



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



<p>Dans la première partie de cet article dédié aux différentes technologies basées sur les graphes, nous avons fait une rapide présentation de la théorie des graphes, ainsi que des principaux algorithmes de graphe et leurs applications. La <a href="/graphes_applications_et_outils_2/">seconde partie</a> se penchera sur les bases de données orientées graphe et les graphes de connaissances, les différences entre ces concepts ainsi que les outils qui y sont associés.</p>



<h2 class="wp-block-heading">Références</h2>



<p>Quelques articles de blog Smals Research concernant les graphes&nbsp;:</p>
<p id="footnote-1">[1] <a href="/graph-db-vs-rdbms/">Graph DB vs RDBMS</a></p>
<p id="footnote-2">[2] <a href="/sept-bonnes-raisons-dutiliser-une-graph-database/">Sept (bonnes) raisons d’utiliser une Graph Database</a></p>
<p id="footnote-3">[3] <a href="/explorer-une-base-de-donnees-orientee-graphes/">Explorer une base de données orientée graphes</a></p>
<p id="footnote-4">[4] <a href="/les-graphes-de-connaissance-incontournable-pour-lintelligence-artificielle-2/">Les graphes de connaissance, incontournable pour l’intelligence artificielle</a></p>
<p id="footnote-5">[5] <a href="/les-graphes-de-connaissance-quelques-applications/">Les graphes de connaissance&nbsp;: quelques applications</a></p>
<p id="footnote-6">[6] <a href="/smalls-kg-checklist/">Smals KG Checklist: déterminer si un graphe de connaissances peut résoudre un problème concret</a></p>
<p id="footnote-7">[7] <a href="/un-fraudeur-ne-fraude-jamais-seul/">Un fraudeur ne fraude jamais seul</a></p>
<p id="footnote-8">[8] <a href="/un-fraudeur-ne-fraude-jamais-seul-partie-2/">Un fraudeur ne fraude jamais seul, partie 2</a></p>
<p id="footnote-9">[9] <a href="/ce-quun-reseau-social-peut-nous-apprendre/">Ce qu’un réseau social peut nous apprendre</a></p>
<p id="footnote-10">[10] <a href="/facebook-peut-on-vraiment-cacher-sa-liste-damis/">Facebook&nbsp;: peut-on vraiment cacher sa liste d’amis&nbsp;?</a></p>
<p id="footnote-11">[11] <a href="/ameliorer-le-machine-learning-avec-des-donnees-graphes/">Améliorer le Machine Learning avec des données graphes</a></p>
<p> </p>
<p>Sources scientifiques&nbsp;:</p>
<p id="footnote-12">[12] Katz, L. (1953). A new status index derived from sociometric analysis. Psychometrika, 18(1), 39-43.</p>
<p id="footnote-13">[13] Fouss, F., Pirotte, A., Renders, J. M., &amp; Saerens, M. (2007). Random-walk computation of similarities between nodes of a graph with application to collaborative recommendation. IEEE Transactions on knowledge and data engineering, 19(3), 355-369.</p>
<p id="footnote-14">[14] Page, L., Brin, S., Motwani, R., &amp; Winograd, T. (1998). The pagerank citation ranking: Bringing order to the web. Technical report, Stanford Digital Libraries.</p>
<p id="footnote-15">[15] Gleich, D. F. (2015). PageRank beyond the web. siam REVIEW, 57(3), 321-363.</p>
<p id="footnote-16">[16] Kleinberg, J. M. (1999). Authoritative sources in a hyperlinked environment. Journal of the ACM (JACM), 46(5), 604-632.</p>
<p id="footnote-17">[17] Raghavan, U. N., Albert, R., &amp; Kumara, S. (2007). Near linear time algorithm to detect community structures in large-scale networks. Physical Review E—Statistical, Nonlinear, and Soft Matter Physics, 76(3), 036106.</p>
<p id="footnote-18">[18] Blondel, V. D., Guillaume, J. L., Lambiotte, R., &amp; Lefebvre, E. (2008). Fast unfolding of communities in large networks. Journal of statistical mechanics: theory and experiment, 2008(10), P10008.</p>
<p id="footnote-19">[19] Grover, A., &amp; Leskovec, J. (2016). node2vec: Scalable feature learning for networks. In Proceedings of the 22nd ACM SIGKDD international conference on Knowledge discovery and data mining (pp. 855-864).</p>
<p id="footnote-20">[20] Chen, H., Sultan, S. F., Tian, Y., Chen, M., &amp; Skiena, S. (2019, November). Fast and accurate network embeddings via very sparse random projection. In Proceedings of the 28th ACM international conference on information and knowledge management (pp. 399-408).</p>
<p id="footnote-21">[21] Schölkopf, B., &amp; Smola, A. J. (2002). Learning with kernels: support vector machines, regularization, optimization, and beyond.</p>
<p id="footnote-22">[22] Van der Maaten, L., &amp; Hinton, G. (2008). Visualizing data using t-SNE. Journal of machine learning research, 9(11).</p>
<p id="footnote-23">[23] Lü, L., &amp; Zhou, T. (2011). Link prediction in complex networks: A survey. <em>Physica A: statistical mechanics and its applications</em>, <em>390</em>(6), 1150-1170.</p>
<hr />
<p><em>Ce post est une contribution individuelle de Pierre Leleux, data scientist et network data analyst chez Smals Research. Cet article est écrit en son nom propre et n’impacte en rien le point de vue de Smals.</em></p>


]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
