Synthetische evaluatiedata filteren op informatiedichtheid
Wanneer een taalmodel zijn eigen toetsmateriaal genereert, ontstaat er een sluipend validiteitsprobleem: synthetische datasets lijken qua omvang indrukwekkend, maar bevatten vaak een verwaarloosbare informatiedichtheid. Grote taalmodellen hebben een sterke neiging tot stilistische breedsprakigheid, herhalende syntactische patronen en triviale vraagstellingen. Als deze synthetische ruis ongefilterd in een evaluatieset belandt, meet een benchmark niet de redeneerkracht of domeinkennis van een getoetst model, maar puur het vermogen om oppervlakkige sjablonen te reproduceren. De beslissing die met dit artikel wordt voorbereid, is het bepalen van de exacte afkapgrens waarbij synthetisch gegenereerde prompts en antwoordparen voldoende signaal-ruisverhouding hebben om als formele benchmark te fungeren.
Dit artikel onderscheidt zich strikt van methodes die datasets verzamelen uit operationele applicaties; lees het fundament over productielogs omzetten naar evaluatiedata om te begrijpen hoe echte interacties afwijken van puur gegenereerde distributies. Waar productiedata kampt met privacyrisico's en ontbrekende annotaties, kampt synthetische data met een gebrek aan informatiediepte en onzichtbare redundantie. Door een kwantitatief filterproces in te richten op basis van informatiedichtheid, wordt voorkomen dat evaluatie-infrastructuur duizenden tokens verwerkt die geen enkel onderscheidend vermogen toevoegen aan de modelvergelijking.
Het probleem van semantische verdunning in gegenereerde toetsen
Synthetische datageneratie via een generator-LLM produceert over het algemeen teksten met een hoge grammaticale vloeibaarheid, maar een lage propositionele dichtheid. Dit fenomeen staat bekend als semantische verdunning: een prompt gebruikt honderd tokens om een logische relatie te beschrijven die in twintig tokens had gepast. Wanneer een te testen model wordt geëvalueerd op dergelijke prompts, meet de benchmark voornamelijk of het model bestand is tegen overbodige opvulling, in plaats van te toetsen op complexe inferentie of feitelijke synthese.
Een tweede complicatie is de distributionele verschuiving naar het midden van de waarschijnlijkheidsverdeling van het genererende model. Modellen genereren bij standaardinstellingen teksten die de gemiddelde patronen van hun trainingsdata weerspiegelen. Hierdoor ontbreken de grillige randgevallen, obscure vaktermen en onvoorspelbare constructies die menselijke data kenmerken. Als we een robuuste toets willen construeren, moeten we synthetische records die onder een bepaalde informatiedrempel vallen genadeloos wegsnijden.
Metrische definities voor informatiedichtheid
Om synthetische testdata te zuiveren, zijn objectieve metrieken vereist die geautomatiseerd kunnen worden berekend. Drie pijlers vormen de basis voor deze kwantitatieve filtering:
| Metriek | Wiskundige / Logische Basis | Wat het Meet in Evaluatiedata | Doelwaarde in Filter |
|---|---|---|---|
| Propositionele Dichtheid | Aantal atomaire proposities gedeeld door totaal aantal woorden | De verhouding tussen feitelijke beweringen en linguïstische opvulling | Boven de 0,35 proposities/woord |
| Voorwaardelijke Entropie | $H(X|C) = -\sum p(x,c) \log p(x|c)$ over tokenreeksen | De mate van onvoorspelbaarheid en uniciteit van de vraagstelling | Hoge lokale variatie ten opzichte van generator-basis |
| Sjabloon-Afstand (Jaccard/Levenshtein op n-grams) | Genormaliseerde afstand tussen syntactische ontleedbomen | Of de generator stiekem steeds dezelfde zinstructuur herhaalt | Afstand groter dan 0,45 ten opzichte van clustercentrum |
Propositionele extractie deconstrueert een prompt in minimale beweringen die onafhankelijk waar of onwaar kunnen zijn. Een vraag als "Gegeven het feit dat de contractant, die statutair gevestigd is te Utrecht, binnen veertien dagen moet reageren..." bevat drie atomaire proposities (contractant is gevestigd te Utrecht, er geldt een reactietermijn, de termijn bedraagt veertien dagen). Bevat een alinea van 150 woorden slechts twee proposities, dan is de dichtheid extreem laag en fungeert de prompt als ruis in de benchmark.
Om te voorkomen dat modellen bij het genereren van samenvattings- en evaluatietests vervallen in oppervlakkige structuren, biedt de iteratieve compressiemethode uitkomst; bekijk de techniek van Chain-of-Density voor informatiedichte teksten om te bestuderen hoe entiteitsdichtheid stapsgewijs wordt gemaximaliseerd zonder verlies van leesbaarheid. Deze principes kunnen rechtstreeks worden omgekeerd om binnenkomende testitems te beoordelen op hun entiteit-naar-token-ratio.
De filterpijplijn: van ruwe generatie naar zuivere benchmark
Het filterproces verloopt in vier opeenvolgende fasen. Elke fase elimineert een specifieke klasse van synthetische degradatie, beginnend bij goedkope heuristieken en eindigend bij computationeel zwaardere semantische analyses.
Fase 1: Oppervlakkige compressie en redundantiecontrole
In de eerste stap worden prompts getoetst op compressibiliteit met standaard algoritmes zoals zlib of gzip. Een tekst met een abnormaal hoge compressieratio bevat herhalende tokenpatronen en oppervlakkige opvulzinnen. Dit is een uiterst efficiënte voorfilter die zonder modelaanroepen 15% tot 25% van de laagwaardige synthetische output elimineert.
Fase 2: Semantische clustering en dichtheidsmeting
In de tweede stap worden de testvragen omgezet naar vectoren via een embedding-model. Vervolgens berekenen we de lokale dichtheid via k-nearest neighbors ($k\text{-NN}$). Testvragen die zich in extreem dichte clusters bevinden, zijn variaties van exact hetzelfde sjabloon. We selecteren per cluster uitsluitend het exemplaar met de hoogste variatie in named entities.
Het gevaar van datavervuiling ligt hier continu op de loer; raadpleeg de analyse over een testset bouwen zonder datalekken om te garanderen dat de voorbeelden die als seed voor de synthetische generator dienen, niet al aanwezig waren in de pre-training data van de te testen LLM's.
Fase 3: Logische constraint-dichtheid
Een hoogwaardige benchmarkvraag bevat specifieke restricties: randvoorwaarden, uitsluitingscriteria of tegenstrijdige bronfragmenten. Met behulp van een parser controleren we op de aanwezigheid van logische operatoren, numerieke condities en conditionele bijzinnen ("tenzij", "mits", "uitsluitend indien"). Vragen zonder restricties testen louter oppervlakkige associatie en worden verworpen.
Fase 4: Verificatie van oplosbaarheid via een arbiter
Wanneer de dichtheid kunstmatig wordt opgevoerd, ontstaat het risico dat een vraag logisch inconsistent of onoplosbaar wordt. In deze fase beoordeelt een strikt gekalibreerd model of de vraag eenduidig te beantwoorden is op basis van de meegeleverde context. Voor de fijnmechanica van deze verificatiestap verwijzen we naar de methode voor LLM-as-a-judge kalibratie, waarin systematische beoordelaarsbias en scoremethoden worden behandeld.
Praktijkvoorbeeld: Python-filter voor propositionele dichtheid
Onderstaand script demonstreert hoe een dataset geautomatiseerd kan worden gefilterd op basis van lexicale diversiteit (Type-Token Ratio) en de dichtheid van unieke inhoudswoorden (zelfstandige naamwoorden, werkwoorden, getallen) ten opzichte van functiewoorden.
import re
from typing import Dict, List
def analyseer_informatiedichtheid(tekst: str) -> Dict[str, float]:
woorden = re.findall(r'\b\w+\b', tekst.lower())
totaal_woorden = len(woorden)
if totaal_woorden == 0:
return {"dichtheid": 0.0, "ttr": 0.0, "geslaagd": 0.0}
# Eenvoudige lijst van Nederlandse functiewoorden (stopwoorden)
functiewoorden = {
"de", "het", "een", "en", "van", "ik", "te", "dat", "die", "in",
"is", "op", "niet", "met", "zijn", "voor", "maar", "er", "om", "als"
}
inhoudswoorden = [w for w in woorden if w not in functiewoorden]
unieke_woorden = set(woorden)
# Metrieken berekenen
inhouds_ratio = len(inhoudswoorden) / totaal_woorden
ttr = len(unieke_woorden) / totaal_woorden
# Samengestelde informatiedichtheidsscore (0.0 tot 1.0)
dichtheidsscore = (inhouds_ratio * 0.6) + (ttr * 0.4)
# Filterdrempel: minimaal 55% inhoudelijke lading en variatie
is_geschikt = 1.0 if (dichtheidsscore >= 0.55 and totaal_woorden >= 20) else 0.0
return {
"totaal_tokens": float(totaal_woorden),
"inhouds_ratio": round(inhouds_ratio, 3),
"ttr": round(ttr, 3),
"score": round(dichtheidsscore, 3),
"geslaagd": is_geschikt
}
# Illustratieve testdata
voorbeelden = [
"Het is van groot belang dat we kijken naar de manier waarop dingen gebeuren.",
"Artikel 7:900 BW vereist een vaststellingsovereenkomst ter beëindiging van een bestaand geschil."
]
for vb in voorbeelden:
resultaat = analyseer_informatiedichtheid(vb)
print(f"Tekst: {vb[:40]}... -> Score: {resultaat['score']} (Geschikt: {bool(resultaat['geslaagd'])})")
Valkuilen in de Nederlandse taalcontext
Bij het filteren van Nederlandstalige synthetische data treden specifieke taalkundige complicaties op die direct invloed hebben op dichtheidsmetingen:
Ten eerste leiden lange samenstellingen (zoals aansprakelijkheidsverzekeringsmaatschappij of uitvoeringskwaliteitseisen) tot vervorming van standaard woordentellers. Een model dat samenstellingen correct aaneenschrijft, lijkt volgens simpele token-tellers een lagere propositionele dichtheid te hebben dan een model dat Engelse spatiefouten maakt (aansprakelijkheid verzekering maatschappij). Filters moeten daarom gebruikmaken van morfologische decompositie om samenstellingen correct te waarderen.
Ten tweede introduceert de werkwoordelijke eindpositie in bijzinnen een syntactische spreiding die door simpele n-gram-modellen ten onrechte als 'hoge entropie' kan worden geïnterpreteerd. Een strikte scheiding tussen syntactische complexiteit en semantische dichtheid is essentieel om te voorkomen dat grammaticale constructies worden verward met feitelijke inhoud.
Ten derde leidt vertaalde synthetische data vaak tot anglicismen en leenvertalingen (zoals "maakt zin" in plaats van "heeft zin" of "aan het einde van de dag" als opvulling). Deze constructies blazen het tokental op zonder enige propositionele meerwaarde. Een specifiek filter op frequente AI-clichés in het Nederlands is daarom een verplicht onderdeel van de pijplijn.
Reproduceerbaarheid en meetopzet
Om een evaluatieset te publiceren die wetenschappelijk en operationeel standhoudt, moet de filtering volledig deterministisch en reproduceerbaar zijn. Dit vereist het vastleggen van vier harde parameters:
1. Vaste zaadwaarde (seed) en determinisme: Alle random sampling binnen de clustering en generatie moet worden vastgezet op een expliciete seed (bijvoorbeeld seed=42), met temperature=0.0 voor controlestappen.
2. Herhalingen en stabiliteit: Elke dichtheidsmeting via embedding-modellen moet worden gevalideerd op permutatie-invariantie: het veranderen van de volgorde van invoeritems mag de resulterende clustergrenzen niet beïnvloeden.
3. Scoringscriteria en afkapwaarden: De drempelwaarden voor afwijzing (zoals de 0,55 grens in het codevoorbeeld) moeten vooraf worden vastgelegd in een configuratiebestand en mogen niet achteraf worden aangepast om een specifieke datasetomvang te forceren.
4. IJking van de arbiter: Indien een LLM wordt ingezet voor propositionele extractie, moet de overeenstemming (Inter-Annotator Agreement via Cohen's Kappa) tussen het model en een menselijke expert op minimaal 100 steekproeven $\kappa \ge 0,80$ bedragen voordat het filter autonoom mag draaien.
Kosten- en doorvoeranalyse in tokens en tijd
Het implementeren van een geavanceerde filterpijplijn brengt infrastructurele kosten met zich mee, maar levert stroomafwaarts een forse besparing op tijdens de daadwerkelijke modelbenchmarks.
Laten we een synthetische ruwe dataset van 10.000 gegenereerde prompts analyseren. Een volledige filterrun doorloopt de volgende fasen:
Fase 1 (Heuristieken & Gzip) verwerkt 10.000 items in circa 4 seconden op een standaard CPU-core, zonder API-kosten, en reduceert de set met 20% naar 8.000 items.
Fase 2 (Embedding-clustering) zet 8.000 items om naar vectoren. Bij een gemiddelde lengte van 250 tokens per prompt kost dit circa 2.000.000 embedding-tokens. Lokale verwerking via een compact model vergt ongeveer 45 seconden op een moderne accelerator. Dit reduceert de dataset via deduplicatie naar 5.000 items.
Fase 3 & 4 (Propositionele extractie en validatie) verwerkt de resterende 5.000 items via een gestructureerde modelaanroep. Dit kost circa 1.250.000 invoertokens en 500.000 uitvoertokens. De doorlooptijd bedraagt 3 tot 5 minuten bij gangbare API-doorvoersnelheden.
Het eindresultaat is een gezuiverde set van 2.500 hoogwaardige testvragen. Hoewel het filterproces eenmalig rekentijd en tokens vraagt, bespaart het bij elke volgende benchmarkronde (waarbij tientallen kandidaat-modellen worden getoetst) 75% aan inferentiekosten en evaluatietijd. Bovendien stijgt de statistische betrouwbaarheid van de uiteindelijke benchmarkscores aanzienlijk doordat ruis en herhaling zijn geëlimineerd.
Zwakke punten en inherente beperkingen
Elk geautomatiseerd filter introduceert systematische blinde vlekken die expliciet moeten worden onderkend:
Overmatige bestraffing van domeinspecifieke conventies: In juridische en medische domeinen is redundant en formeel taalgebruik soms wettelijk verplicht of functioneel noodzakelijk. Een te agressief dichtheidsfilter kan legitieme contractuele clausules of medische disclaimers onterecht als 'opvulling' classificeren en verwijderen.
Bevoordeling van gecomprimeerde schrijfstijlen: Modellen die extreem beknopt antwoorden, scoren kunstmatig hoger op propositionele dichtheidsmetingen, zelfs als hun antwoorden te summier zijn voor menselijk gebruik. Het filter meet informatiedichtheid, geen pedagogische of communicatieve kwaliteit.
Circulaire bias door generator-arbiter overlap: Als hetzelfde modeltype wordt gebruikt voor zowel de datageneratie als de informatiedichtheidsbeoordeling, ontstaat er een blinde vlek voor de specifieke stijlfouten van die modelfamilie. Gebruik daarom altijd structureel verschillende architecturen voor generatie en validatie.


