Ga naar hoofdinhoud

Kernel Density Estimation: van theorie naar praktijk

Kernel-dichtheidsschatting is een niet-parametrische methode om de vorm van een dataverdeling te schatten zonder een vast model aan te nemen. Leer de formule, bandbreedtekeuze en hands-on implementatie in Python en R.
Bijgewerkt 16 jun 2026  · 11 min lezen

Ooit geprobeerd een verdeling te visualiseren, om vervolgens een histogram te krijgen dat van vorm verandert zodra je de aantal bins aanpast?

Zo gaat het meestal. Je kiest 10 bins en ziet een vloeiende curve. Dan schakel je over naar 30 en verschijnen er meerdere pieken. De data bleef hetzelfde, maar verschillende aantallen bins geven verschillende interpretaties. Dat is het grootste probleem met histogrammen: ze tonen je niet de verdeling, maar één versie ervan. En die versie wordt beïnvloed door een parameter die je willekeurig instelt.

KDE pakt het anders aan. In plaats van data in bins te hakken, plaatst het op elk datapunt een kleine, vloeiende curve en telt die allemaal bij elkaar op. Dat levert één continue schatting op van de onderliggende verdeling.

In dit artikel krijg je de intuïtie achter KDE, een doorloop van de formule, een uitleg over hoe bandbreedte de gladheid bepaalt, en praktische voorbeelden in Python en R.

Nieuw met histogrammen? Hier is een uitgebreide gids over frequentiehistogrammen om je op weg te helpen.

Wat is kernel-dichtheidsschatting?

Kernel-dichtheidsschatting is een niet-parametrische methode om de kansdichtheidsfunctie van een dataset te schatten.

Het niet-parametrische deel is wat het anders maakt.

Bij parametrische methoden ga je ervan uit dat je data een specifieke verdeling volgt — normaal, exponentieel — en pas je vervolgens parameters aan om die te laten overeenkomen. Als die aanname niet klopt, klopt je model niet. KDE maakt zulke aannames niet. Het laat de data voor zichzelf spreken en bouwt rechtstreeks op basis van de waarnemingen een schatting van de onderliggende verdeling.

De output is een vloeiende curve die laat zien waar waarden waarschijnlijk vallen — en hoe waarschijnlijk dat is. Hoge punten op de curve betekenen dichte regio’s. Lage punten betekenen schaarse.

Waarom kernel-dichtheidsschatting gebruiken?

Histogrammen zijn de standaardtool om verdelingen te visualiseren, maar ze hebben een probleem: de vorm die je ziet hangt af van het aantal gekozen bins. En die parameter kies jij. Twee mensen kunnen naar dezelfde dataset kijken en totaal verschillende conclusies trekken door simpelweg een ander aantal bins te kiezen.

Met KDE dwing je data niet in bins, maar krijg je een vloeiende, continue curve die niet verandert op basis van een willekeurige parameter die je vooraf instelt.

Dat maakt het handig voor een paar dingen:

  • De algemene vorm van een verdeling visualiseren zonder bias door bin-grootte
  • Patronen detecteren zoals meerdere pieken, scheefheid of zware staarten
  • Verdelingen vergelijken tussen groepen in dezelfde plot
  • Een schoner beeld van je data krijgen vóór het modelleren

Intuïtie achter KDE

Je neemt elk datapunt en plaatst er een kleine, vloeiende curve bovenop. Die curve heet een kernel. Vervolgens tel je al die individuele curves bij elkaar op tot één geheel.

Je eindigt met één vloeiende curve die de dichtheid van je data laat zien. Waar punten clusteren, overlappen meerdere kernels en stapelen ze zich op, waardoor de curve stijgt. Waar data schaars is, overlappen de kernels nauwelijks en blijft de curve laag. Elk punt draagt in gelijke mate bij aan de uiteindelijke schatting.

Stel, je hebt eindscores van een klas studenten opgenomen. In plaats van ze in een histogram te binnen, plaatst KDE een kleine vloeiende curve op elke score. Waar scores clusteren — bijvoorbeeld rond 70–75 — stapelen de curves zich op en stijgt de schatting. Een enkele student met 95 voegt slechts een kleine hobbel aan de staart toe.

De visual hieronder laat precies dit zien. De meeste studenten scoorden rond het gemiddelde, en één student scoorde veel hoger:

KDE gevisualiseerd

KDE gevisualiseerd

Formule voor kernel-dichtheidsschatting

De KDE-formule oogt intimiderender dan ze is.

KDE-formule

Dit betekent elk onderdeel:

  • n is het aantal datapunten

  • x_i zijn de individuele datapunten in je dataset

  • K is de kernelfunctie — de vloeiende curve die op elk punt wordt geplaatst

  • h is de bandbreedte — bepaalt hoe breed elke kernel is

  • x is het punt waar je de dichtheid evalueert

In gewone taal zegt de formule: voor elk punt x, kijk hoe dicht elk datapunt x_i erbij in de buurt ligt, weeg die nabijheid met de kernelfunctie K, en neem het gemiddelde over alle n punten. Doe dit voor elke x in het bereik en je krijgt de volledige dichtheidscurve.

De bandbreedte h staat in de noemer van de breuk binnen K. Een kleinere h maakt de kernel smaller, waardoor alleen heel nabije punten de schatting beïnvloeden. Een grotere h spreidt de invloed breder uit. Later in het artikel meer hierover.

Wat is een kernelfunctie?

De kernel is de vloeiende curve die je op elk datapunt plaatst. Die bepaalt hoe de invloed van dat punt zich verspreidt naar de buren.

Elke kernel is gecentreerd op een datapunt en kent gewichten toe op basis van afstand. Punten dicht bij het centrum krijgen een hoog gewicht. Punten ver weg krijgen een laag of helemaal geen gewicht. De exacte vorm van die weging hangt af van welke kernel je kiest.

Er zijn drie gangbare keuzes:

  • Gaussiaans: De klokvormige curve. Kent elk punt in de dataset gewicht toe, en de invloed neemt af met de afstand. Dit is de standaard in de meeste libraries en werkt in de praktijk goed
  • Uniform: Een vlakke rechthoek. Elk punt binnen een vaste afstand krijgt een gelijk gewicht, en alles daarbuiten niets. Simpel, maar levert minder gladde schattingen op
  • Epanechnikov: Een paraboolvorm die wiskundig optimaal is qua mean squared error. Efficiënter dan Gaussiaans maar zelden zichtbaar verschillend in de praktijk.

In de meeste gevallen maakt de kernelkeuze weinig uit. Twee verschillende kernels toegepast op dezelfde data met dezelfde bandbreedte leveren bijna identieke curves op. Wat veel meer uitmaakt, is bandbreedte — en daar kijken we nu naar.

De rol van bandbreedte in KDE

Bandbreedte is de ene parameter die de grootste impact heeft op je KDE-output, zelfs meer dan de gekozen kernel.

Het bepaalt hoe breed elke kernel is. Een smalle kernel haalt alleen invloed uit nabije punten. Een brede kernel spreidt die invloed over een veel groter bereik. Het resultaat is óf een curve die de data strak volgt, óf een die eroverheen strijkt.

Kleine bandbreedte

Een kleine bandbreedte maakt elke kernel strak en smal. De schatting reageert scherp op elk datapunt, wat betekent dat hij echte structuur in de data oppikt, maar ook ruis.

In de praktijk ziet dit eruit als een hoekige curve met meerdere kleine pieken. Sommige van die pieken laten echte clusters in je data zien. Andere zijn slechts artefacten van te weinig smoothing. Het is lastig te onderscheiden wat wat is — en dat is het probleem.

KDE met kleine bandbreedte

KDE met kleine bandbreedte

Grote bandbreedte

Een grote bandbreedte spreidt elke kernel breed uit. Aangrenzende kernels overlappen, en de uiteindelijke curve wordt glad.

Als het té glad wordt, verlies je echte structuur. Twee afzonderlijke clusters kunnen vervagen tot één curve. Een verdeling met een zware staart kan symmetrisch lijken. De visualisatie kan dingen voor je verbergen.

KDE met grote bandbreedte

KDE met grote bandbreedte

De juiste bandbreedte vinden

Er is geen universeel juiste bandbreedte. Het doel is een waarde te vinden die glad genoeg is om ruis te filteren, maar niet zo glad dat echte patronen verdwijnen.

De meeste libraries doen dit met automatische methoden voor bandbreedtekeuze. Silverman’s vuistregel is de meest gebruikte. Die kiest een bandbreedte op basis van de steekproefgrootte en standaarddeviatie van je data. Werkt goed voor ongeveer normale verdelingen, maar kan multimodale verdelingen te veel gladstrijken.

Als je twijfelt, probeer een paar bandbreedtewaarden en vergelijk de curves. De verschillen vertellen je veel over je data.

KDE vs. histogram

Zowel histogrammen als KDE laten de verdeling van je data zien — maar ze doen dat op een heel andere manier.

Histogram

Een histogram splitst je data in discrete bins en telt hoeveel punten in elk ervan vallen. Het is snel, intuïtief en makkelijk uit te leggen aan een niet-technisch publiek.

Het probleem is gevoeligheid voor bins. Als je het aantal bins verandert, verandert de vorm. Er is geen objectief correct aantal bins, wat betekent dat twee mensen naar dezelfde data kunnen kijken en andere conclusies trekken puur door die ene keuze.

Histogrammen leveren ook een getrapte, discontinue vorm op. Dat is prima voor een snelle blik, maar kan de echte onderliggende verdeling verhullen.

KDE

KDE geeft je een vloeiende, continue curve zonder bins. Het is beter in het blootleggen van de werkelijke vorm van een verdeling — dingen als scheefheid, meerdere pieken of zware staarten die een histogram kan missen of verkeerd weergeven afhankelijk van de bin-keuze.

De keerzijde is dat KDE een eigen parameter introduceert — bandbreedte — en meer rekenwerk vraagt. Het is ook minder intuïtief uit te leggen, omdat de y-as kansdichtheid toont en geen tellingen, wat lezers die met het concept niet vertrouwd zijn kan verwarren.

Wanneer gebruik je wat

Gebruik een histogram als je een snelle, goed te interpreteren samenvatting van je data nodig hebt of als je publiek niet bekend is met dichtheidsschattingen. Gebruik KDE wanneer de vorm van de verdeling ertoe doet — bijvoorbeeld als je groepen vergelijkt of meerdere modi in je data wilt opsporen.

Histogram vergeleken met KDE

Histogram vergeleken met KDE

In de praktijk worden ze vaak samen gebruikt: een histogram voor de tellingen, met daarbovenop een KDE-curve voor de vorm.

Kernel-dichtheidsschatting in Python

Python geeft je meerdere manieren om KDE te berekenen en te plotten, afhankelijk van of je een snelle grafiek nodig hebt of meer controle over de schatting zelf.

KDE visualiseren met seaborn

De snelste manier om een KDE-plot te krijgen is seaborn.kdeplot(). Meer heb je niet nodig:

import seaborn as sns
import numpy as np

np.random.seed(42)
scores = np.concatenate([
    np.random.normal(65, 4, 60),
    np.random.normal(80, 3, 40)
])

sns.kdeplot(scores, bw_adjust=1)

KDE met seaborn

KDE met seaborn

De parameter bw_adjust schaalt de automatisch geselecteerde bandbreedte. Waarden onder 1 maken de curve strakker, waarden boven 1 maken haar gladder. Het is een vermenigvuldigingsfactor bovenop welke bandbreedte seaborn intern kiest, dus je hoeft zelf geen ruwe bandbreedtewaarde te zetten.

De y-as toont kansdichtheid, geen tellingen. De curve vertelt je hoe waarschijnlijk een waarde is ten opzichte van de rest van de verdeling. Hoger betekent dat daar meer data geconcentreerd is.

KDE berekenen met scipy

Als je de daadwerkelijke dichtheidswaarden nodig hebt — niet alleen een plot — gebruik dan scipy.stats.gaussian_kde. Dat geeft je een aanroepbaar object dat je op elk punt kunt evalueren.

from scipy.stats import gaussian_kde
import numpy as np
import matplotlib.pyplot as plt

kde = gaussian_kde(scores, bw_method="scott")
x = np.linspace(45, 100, 500)
density = kde(x)

plt.plot(x, density)

bw_method="scott" gebruikt Scotts regel om automatisch de bandbreedte te kiezen. Dat is in de meeste gevallen een goede standaard. Je kunt ook een scalar doorgeven om de bandbreedte handmatig in te stellen.

KDE met scipy en matplotlib

KDE met scipy en matplotlib

Kernel-dichtheidsschatting in R

In R is KDE ingebouwd in de basis-taal. Je hebt geen extra packages nodig.

KDE berekenen met density()

De functie density() neemt een numerieke vector en geeft een KDE-object terug.

set.seed(42)
scores <- c(rnorm(60, mean = 65, sd = 4),
            rnorm(40, mean = 80, sd = 3))

kde <- density(scores, bw = "SJ")

Het argument bw regelt de bandbreedtekeuze. "SJ" gebruikt de Sheather-Jones-methode, die beter omgaat met multimodale verdelingen dan de standaard. Je kunt ook een numerieke waarde doorgeven om de bandbreedte handmatig in te stellen.

Het resultaat is een list-object met twee kernelementen:

  • kde$x: de reeks punten waarop de dichtheid is geëvalueerd
  • kde$y: de bijbehorende dichtheidswaarden

De curve plotten

Geef het resultaat gewoon direct door aan plot().

plot(kde,
     main = "Exam Score Distribution",
     xlab = "Score",
     ylab = "Density")

KDE geplot in R

Om de KDE over een histogram te leggen, gebruik je eerst hist() met freq = FALSE en voeg je daarna de curve toe met lines().

hist(scores, freq = FALSE, main = "Histogram + KDE", xlab = "Score")
lines(kde, col = "blue", lwd = 2)

Histogram met KDE in R

freq = FALSE schaalt het histogram naar dichtheid zodat zowel de balken als de curve dezelfde y-as delen.

Voordelen en beperkingen van KDE

KDE is een echt nuttige visualisatie, maar zoals altijd zijn er afruilen die je wilt kennen voordat je het als vervanging voor histogrammen gebruikt.

Voordelen

Het grootste pluspunt is dat KDE geen aannames doet over de verdeling van je data. Je hoeft vooraf niet te beslissen of je data normaal, exponentieel of iets anders is. De vorm komt uit de data zelf, waardoor KDE flexibel genoeg is voor multimodale verdelingen en alles wat niet in een standaard parametrische vorm past.

De output is ook een vloeiende, continue curve in plaats van een getrapte benadering. Dat maakt het makkelijker om patronen te zien — dingen als meerdere pieken of lange staarten — die een histogram afhankelijk van de bin-keuze voor je kan verbergen.

En omdat KDE werkt op ruwe data zonder dat je eerst een model hoeft te fitten, is het een goede eerste stap in elke exploratieve analyse.

Beperkingen

Bandbreedtekeuze is de belangrijkste zwakte. Als je die verkeerd kiest, jaagt de schatting óf de ruis achterna óf strijkt ze echte patronen glad. Automatische methoden zoals Silverman’s regel werken goed voor ongeveer normale data, maar kunnen je misleiden bij complexe verdelingen. Vaak moet je handmatig een paar bandbreedtes checken voordat je het resultaat vertrouwt.

Prestaties kunnen op schaal een probleem worden. KDE evalueert een kernelfunctie voor elk datapunt op elke evaluatielocatie, wat betekent dat de rekentijd snel groeit naarmate je dataset groter wordt. Voor de meeste exploratieve taken is dit geen issue, maar op datasets met honderdduizenden punten kan het traag zijn.

Rand-effecten zijn een subtieler probleem. Standaard KDE veronderstelt dat data in beide richtingen oneindig kan doorlopen. Wanneer je data een harde grens heeft — zoals waarden die niet onder nul kunnen — lekt de schatting kansmassa voorbij die grens, wat een curve oplevert die kunstmatig laag is bij de rand. Er bestaan randgecorrigeerde varianten van KDE, maar die zijn minder vaak geïmplementeerd in standaardbibliotheken.

Conclusie

KDE geeft je een schonere manier om naar de verdeling van je data te kijken dan histogrammen. Geen bin-keuzes en geen parametrische aannames — alleen een vloeiende curve die laat zien wat er daadwerkelijk in je dataset zit.

Bandbreedte is de ene parameter die echt telt. Probeer een paar waarden, vergelijk de curves, gebruik geautomatiseerde opties en zorg dat de schatting klopt met wat je over je data weet voordat je er conclusies uit trekt.

De beste manier om intuïtie voor KDE op te bouwen, is het op echte data draaien. Kies een dataset die je al kent, pas KDE toe en vergelijk met een histogram om te zien wat je gemist hebt.

Geïnteresseerd in datavisualisatie? Bekijk onze cursus Data Visualization with Seaborn als je Python gebruikt, of Data Visualization with ggplot2 als je R gebruikt.


Dario Radečić's photo
Author
Dario Radečić
LinkedIn
Senior Data Scientist, gevestigd in Kroatië. Top Tech-schrijver met meer dan 700 gepubliceerde artikelen en meer dan 10 miljoen weergaven. Auteur van het boek Machine Learning Automation with TPOT.

FAQs

Waarvoor wordt kernel-dichtheidsschatting gebruikt?

KDE wordt gebruikt om de kansverdeling van een dataset te schatten zonder aan te nemen dat die een specifieke vorm volgt, zoals een normale of exponentiële verdeling. Het is gangbaar in exploratieve data-analyse, waar je wilt visualiseren hoe je data is verdeeld voordat je gaat modelleren. Je vindt het ook terug bij anomaliedetectie, het vergelijken van verdelingen tussen groepen en als smoothing-stap in statistische pipelines.

Hoe verschilt KDE van een histogram?

Een histogram splitst data in discrete bins en telt hoeveel punten in elk ervan vallen. De vorm die je krijgt hangt af van hoeveel bins je kiest, waardoor het gevoelig is voor een willekeurige parameter. KDE omzeilt dit door op elk datapunt een vloeiende curve te plaatsen en die op te tellen, wat een continue schatting oplevert die niet verandert op basis van het aantal bins.

Heb je een grote dataset nodig om KDE te gebruiken?

KDE werkt op kleine datasets, maar de schattingen zijn minder betrouwbaar wanneer je heel weinig punten hebt. Bij beperkte data hebben individuele observaties een grote invloed op de uiteindelijke curve, waardoor het lastiger is om echte structuur van ruis te onderscheiden. Naarmate je dataset groeit, stabiliseert de schatting en weerspiegelt die de werkelijke verdeling nauwkeuriger.

Wat gebeurt er als je de verkeerde bandbreedte kiest?

Een te kleine bandbreedte levert een hoekige curve op die op elk individueel punt reageert, waardoor het lastig is om de algemene vorm van je data te zien. Een te grote bandbreedte strijkt de schatting te veel glad en kan afzonderlijke pieken samenvoegen tot één bult, waardoor echte structuur wordt verborgen. De meeste libraries bieden automatische methoden voor bandbreedtekeuze, zoals Silverman’s regel, als startpunt, maar het is goed gebruik om handmatig een paar waarden te testen voordat je conclusies trekt.

Werkt KDE goed nabij de grenzen van je data?

Standaard KDE gaat ervan uit dat data in beide richtingen oneindig kan doorlopen, wat problemen geeft wanneer je variabele een harde onder- of bovengrens heeft — zoals leeftijd, inkomen of elke telling die niet onder nul kan. Dicht bij die grenzen lekt de schatting kansmassa buiten het geldige bereik, waardoor de curve aan de randen kunstmatig laag wordt. Randgecorrigeerde KDE-methoden bestaan om dit aan te pakken, maar zijn niet in alle libraries beschikbaar en vergen extra setup.

Onderwerpen

Leren met DataCamp

Cursus

Support Vector Machines in R

4 Hr
11K
Deze cursus laat je op een makkelijke, visuele manier kennismaken met de support vector machine (SVM).
Bekijk detailsRight Arrow
Begin met de cursus
Meer zienRight Arrow