Cursus
Machine learning (ML)-algoritmen worden steeds vaker gebruikt om saaie taken te automatiseren en verborgen patronen in data te ontdekken. Maar ze zijn van nature probabilistisch, wat betekent dat hun voorspellingen niet altijd kloppen. Daarom heb je een manier nodig om de geldigheid van je ML-model te schatten om vertrouwen in zulke systemen op te bouwen.
Evaluatiematen zoals accuracy, precision, recall, mean squared error (MSE), mean absolute percentage error (MAPE) en soortgelijke maten worden vaak gebruikt om de modelprestaties te meten. Verschillende metrics helpen je de prestaties te beoordelen vanuit verschillende criteria en invalshoeken.
Deze metrics zorgen er ook voor dat het model zijn beoogde taak steeds beter leert. Want als je niet kunt meten, kun je de prestaties van het ML-systeem niet verbeteren.
Accuracy is zo'n metric die makkelijk te begrijpen is en goed werkt met een gebalanceerde dataset, dus een dataset waarin alle klassen evenredig vertegenwoordigd zijn. Maar in de echte wereld zijn verschijnselen niet gelijk verdeeld; zulke gebalanceerde datasets zijn dus lastig te vinden. Accuracy draait er vooral om of de meerderheid van de instanties correct is herkend, ongeacht tot welke klasse ze behoren. Bij belangrijke zeldzame gebeurtenissen, zoals een frauduleuze transactie of een klik op een advertentie-impressie, geeft accuracy een verkeerd beeld van een model dat simpelweg alles als de negatieve klasse voorspelt, dus geen fraude of geen kliks. Vanwege zulke beperkingen is accuracy niet de meest geschikte metric. Welke metric gebruik je dan beter om de prestaties van je modellen te meten?
Precision en recall zijn veelgebruikte metrics om de prestaties van een ongebalanceerd classificatiemodel te evalueren, zoals bij het voorspellen van klantverloop.
Precision en recall uitgelegd
Precision geeft aan met hoeveel vertrouwen een positieve klasse als positief wordt voorspeld, terwijl recall meet hoe goed het model het aantal positieve klassen in de dataset herkent. Let op: de positieve klasse is de klasse van interesse.
Empirisch gezien begrijp je precision en recall het best met behulp van een confusion matrix die uit vier kernbegrippen bestaat:
- True Positive (TP): aantal correct als positief herkende instanties
- False Positive (FP): aantal negatieve instanties die onterecht als positief zijn herkend
- True Negative (TN): aantal correct als negatief herkende instanties
- False Negative (FN): aantal positieve instanties die onterecht als negatief zijn herkend

Weergave door de auteur
Precision en recall zijn wiskundige uitdrukkingen van deze vier termen waarbij:
Precision de verhouding is van TP tot alle instanties met een positieve voorspelling (TP+FP). Recall is de verhouding van TP tot alle positieve instanties (TP+FN).
Dit wordt verder vereenvoudigd met de volgende notatie, die het verschil tussen beide benadrukt. In essentie hebben beide metrics dezelfde teller: de intersectie van daadwerkelijke positieve instanties met positief voorspelde instanties, dus TP.

Afbeelding door Shruti Saxena
Het onderscheid zit in de noemer: precision neemt alle positief voorspelde instanties (TP+FP), terwijl recall kijkt naar de daadwerkelijke positieve instanties (TP+FN).
De intuïtie achter precision en recall
De confusion matrix heet niet voor niets zo – het is inderdaad verwarrend als je deze concepten voor het eerst probeert te begrijpen.
Laten we het begrip daarom eigen maken met een voorbeeld. Stel, je hebt een staalfabriek waar uit ijzererts ijzer wordt gewonnen en gemengd met andere mineralen en elementen (soms onbedoeld). Als we inzoomen op het winningsproces, heb je een paar keuzes wat betreft de zuiverheid van het gewonnen metaal en de hoeveelheid afval die daarbij ontstaat:
Scenario 1: Je wilt uitsluitend de zuiverheid van het gewonnen ijzer prioriteren, ongeacht hoeveel metaal er in het proces verloren gaat.
Scenario 2: Je wilt de efficiëntie maximaliseren, dus de hoeveelheid gewonnen ijzer per eenheid erts, waarbij je de zuiverheid van het gewonnen metaal buiten beschouwing laat.
Scenario 3: Je wilt het beste van beide werelden: de zuiverheid van het gewonnen metaal zo hoog mogelijk houden en tegelijkertijd het afval verminderen (het gewonnen ijzer per eenheid erts maximaliseren).
Zie de hoogoven of elektrische boogoven als modelopties die verschillende resultaten opleveren (zuiverheid van het ijzer en afval). Stel dat een van de winningsmethoden 97,5% zuiver ijzer oplevert en 4% van het ijzer in het slib verloren laat gaan. Dan kunnen we onze precision definiëren als het aandeel zuiver ijzer in het gewonnen metaal, dus 97,5%, terwijl recall de hoeveelheid gewonnen ijzer is ten opzichte van al het beschikbare ijzer in het erts, namelijk 96% (4% van al het ijzer gaat verloren).

Illustratie door de auteur
Stel dat je de tweede methode volgt omdat je zuiverder ijzer uit de oven wilt, wat op zijn beurt meer afval tijdens de winning betekent. Neem aan dat als je de zuiverheid van ijzer met 0,5% verhoogt tot 98%, je metaalverlies met 11% toeneemt. Dat betekent dat de recall-waarde bij een precision van 98% uitkomt op 85%. Deze ruil van recall in ruil voor hogere precision, en andersom, laat de inverse relatie tussen precision en recall zien.
Zou het niet geweldig zijn als je alle waarden van precision en de bijbehorende recall-waarden kon zien, zodat je een beslissing kunt nemen die het beste bij je doel past?
De precision-recall-curve helpt je die keuze te maken, en dat ga je in de volgende secties goed begrijpen. Maar voordat we dat doen, bekijken we eerst een belangrijk concept: de drempelwaarde, die centraal staat in de PR-curve.
Het concept van een drempelwaarde
Laten we een voorbeeld nemen van het identificeren van frauduleuze transacties om te begrijpen hoe een drempel (of cutoff) werkt. De onderstaande tabel bevat vier transacties met transactie-ID’s van 1 tot en met 4; een transactie kan frauduleus of regulier zijn. Het fraudedetectiemodel geeft de kans dat een transactie frauduleus is (gemarkeerd in de gele kolom), wat impliciet de kans op een reguliere transactie weergeeft.
Een transactie wordt als frauduleus voorspeld als de kans hoger is dan de gekozen drempel in de kolom Probability of Fraud transaction; anders wordt deze als regulier aangemerkt.
|
Transaction ID |
Probability of Fraud transaction |
Probability of regular transaction |
Is fraudulent? (Threshold = 0.9) |
Is fraudulent? (Threshold = 0.5) |
Is fraudulent? (Threshold = 0.4) |
|
1 |
0.3 |
0.7 |
No |
No |
No |
|
2 |
0.4 |
0.6 |
No |
No |
Yes |
|
3 |
0.6 |
0.4 |
No |
Yes |
Yes |
|
4 |
0.95 |
0.05 |
Yes |
Yes |
Yes |
Wanneer een strenge drempel van 0,9 wordt toegepast, worden de eerste drie transacties als regulier aangemerkt, terwijl de laatste transactie als frauduleus wordt bestempeld. Zo'n hoge drempel straalt vertrouwen in de voorspellingen uit en leidt tot een scenario met hoge precision. In ruil daarvoor lever je recall in doordat je sommige frauduleuze transacties mist.
Zo’n scenario is niet wenselijk ondanks de hoge precision. Weet je waarom?
Omdat het bedrijf een hogere prijs betaalt voor het missen van fraudeherkenning, wat juist het doel is van het bouwen van zo’n model. Let op: de kosten van een frauduleuze transactie zijn veel hoger dan de kosten van geblokkeerde maar reguliere transacties, dus FP.
Bekijk nu de andere kant van het spectrum met een lage drempelwaarde van 0,4, die de onderste drie transacties als frauduleus markeert. Zo'n ruime drempel blokkeert het merendeel van de transacties, wat veel klanten kan irriteren. En er komt extra druk op menskracht te liggen om de gemarkeerde transacties door te lopen en echte fraudes te identificeren.
Het bedrijf moet daarom doelmetrics en bijbehorende streefwaarden definiëren om het beste van beide werelden te krijgen, met inachtneming van de volgende kosten:
- De kosten van een frauduleuze transactie die als regulier wordt aangemerkt (False Negatives)
- De kosten van een reguliere transactie die als frauduleus wordt aangemerkt (False Positives)
Kijkend naar de definitie van precision zie je dat false positives in de noemer van de formule staan, wat betekent dat het minimaliseren van false positives de precision maximaliseert. Op dezelfde manier maximaliseert het minimaliseren van false negatives de recall van het model.
Of een transactie als frauduleus of regulier wordt voorspeld, hangt dus grotendeels af van de drempelwaarde.
Wat is een precision-recall-curve?
Een precision-recall-curve helpt je een drempel te bepalen op basis van de gewenste waarden voor precision en recall. Hij is ook handig om verschillende modelprestaties te vergelijken door de “Area Under the Precision-Recall Curve” te berekenen, afgekort AUC.
Zoals via de confusion matrix uitgelegd, levert een binair classificatiemodel TP, FP, TN en FN op voor uiteenlopende drempelwaarden, waarbij elke drempelwaarde een bijbehorend paar van precision- en recall-waarden oplevert.
Als je recall op de x-as uitzet en de bijbehorende precision op de y-as, krijg je een PR-curve die een negatieve helling laat zien. Die representeert de trade-off tussen precision (het terugdringen van FPs) en recall (het terugdringen van FNs) voor een gegeven model. Gezien de inverse relatie tussen precision en recall is de curve doorgaans niet-lineair: het verhogen van de ene metric verlaagt de andere, maar die afname is mogelijk niet evenredig.

Afbeelding van StackExchange
Stel dat een organisatie een minimale acceptabele recall van 98% kiest. De precision bedraagt 30% op het snijpunt dat wordt weergegeven door de ster met het label “Low Threshold, Low Precision, High Recall.”
De andere twee uiterste punten vertegenwoordigen de gevallen waarin de drempel:
- Te laag is – leidt tot hoge recall: kosten voor menskracht en geïrriteerde klanten
- Te hoog is – leidt tot hoge precision: kosten van frauduleuze transacties en reputatieschade
Een PR-curve gebruiken
Naast het kiezen van de juiste cutoff die past bij de businessmetric, kun je de oppervlakte onder de precision-recall-curves van meerdere modellen of algoritmen gebruiken om hun prestaties te vergelijken. Het is met name nuttig om modellen via PR-curves te vergelijken in plaats van met losse precision, recall of zelfs een F1-score (de harmonische gemiddelde van precision en recall).

Afbeelding van Stackoverflow
Dit soort metrics zijn drempelafhankelijk: een verandering in drempel verandert de verdeling van TP, FP en FN. Twee verschillende modellen kunnen zich anders gedragen bij een gegeven drempel, wat de PR-curve tot een robuuste keuze voor modelvergelijking maakt. De bovenstaande grafiek toont twee PR-curves van twee verschillende algoritmen op een gegeven dataset – de AUC van algoritme twee is groter dan die van algoritme één, waardoor het de betere keuze is voor dit probleem.
Precision-recall-curve implementeren in Python
Nu we weten wat precision-recall-curves zijn en waar je ze voor gebruikt, gaan we er een maken in Python.
Stap 1: Benodigde Python-packages importeren
We bekijken de modeldataset voor borstkankerdetectie, waarbij “klasse 1” een kankerdiagnose voorstelt en “klasse 0” betekent dat er geen kanker is.
De eerste import laadt de dataset uit “sklearn.datasets”, die de onafhankelijke en doelvariabelen bevat. Omdat het een modeldataset is die door de meeste algoritmen eenvoudig is te leren, kiezen we het Naive Bayes-algoritme, geïmporteerd als “GaussianNB” uit sklearn.
De volgende import van “Precision_Recall_curve” levert verschillende drempels en hun bijbehorende precision- en recall-waarden op.
from sklearn.datasets import load_breast_cancer
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import precision_recall_curve
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
Stap 2: Train- en testdata voorbereiden
De onafhankelijke variabelen staan onder de sleutel “data” en de doelvariabele onder de sleutel “target” in de “data”-dictionary. De data wordt vervolgens opgesplitst in train- en testsets door het argument test_size met waarde 0,3 door te geven.
# Load model breast cancer data
data = load_breast_cancer()
X = data['data']
y = data['target']
Laten we kijken naar de verdeling van de positieve en negatieve klasse, dus borstkanker en geen borstkanker.
import numpy as np
unique, counts = np.unique(y, return_counts=True)
plt.pie(counts, labels=unique, autopct='%.0f%%');

Splits de data in een train- en testset met de functie train_test_split uit sklearn’s model_selection-module.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
Stap 3: Model trainen
De trainingsdata wordt als argument doorgegeven aan GaussianNB() om het model te trainen. Het gefitte modelobject wordt vervolgens gebruikt om voorspellingen in de vorm van kansen te krijgen op de train- en testdataset.
# Fit a Naive Bayes model
clf = GaussianNB().fit(X_train, y_train)
Stap 4: Voorspellingen genereren
Genereer voorspelde kansen met de train- en testdataset, die worden gebruikt om precision en recall bij verschillende drempelwaarden te verkrijgen.
# Predict probability
y_prob_train = clf.predict_proba(X_train)[:,1]
y_prob_test = clf.predict_proba(X_test)[:,1]
Stap 5: PR-curve plotten
De methode Precision_Recall_curve() neemt twee inputs – de kansen uit de traindataset, dus y_prob_train, en de daadwerkelijke grondwaarheidswaarden – en retourneert drie waarden: precision, recall en thresholds.
precision, recall, thresholds = precision_recall_curve(y_train, y_prob_train)
plt.fill_between(recall, precision)
plt.ylabel("Precision")
plt.xlabel("Recall")
plt.title("Train Precision-Recall curve");
De precision- en recall-vectoren worden gebruikt om de PR-curve bij verschillende drempels te plotten, zoals hieronder weergegeven:

PR-curve gegenereerd door de auteur
Is een precision-recall-curve beter dan een ROC-curve?
Een ROC-curve lijkt op de PR-curve, maar zet de True Positive Rate (TPR) uit tegen de False Positive Rate (FPR) voor verschillende drempels. We kennen TPR al; dat is gewoon een andere naam voor recall. Laten we ons dus richten op FPR, die het aantal misclassificaties uit de negatieve klasse aangeeft. In het fraudevoorbeeld representeert dit het percentage reguliere transacties dat als frauduleus wordt aangemerkt.

Afbeelding door Albert Um
We begrijpen nu dat recall, oftewel TPR, gemeenschappelijk is tussen de PR-curve en de ROC-curve; het belangrijkste verschil is dat het bij PR om precision gaat en bij ROC om FPR. Laten we zien waarom een PR-curve relatief informatiever is.
Dat komt doordat de P-R-curve betekenisvollere inzichten geeft over de klasse van interesse dan de ROC-curve. Neem de voorspelling van fraudetransacties. True Negatives (TN) zijn in ongebalanceerde datasets vaak zeer talrijk, waardoor FPR een heel kleine waarde wordt. Maar zegt dat iets over de modelprestatie bij het voorspellen van frauduleuze transacties?
Nee! Het gebruik van precision als een van de metrics beschrijft daarentegen de modelprestatie op de positieve klasse (fraudetransacties). Het laat zien of het model conservatief of ruimhartig is in het markeren van transacties als fraude.
Het tweede grote nadeel van de ROC-curve is de ongevoeligheid voor ongebalanceerde data. In de bovenstaande figuur zie je dat FPR een metric is die alleen de negatieve klasse betreft, wat betekent dat de verandering in FP naar verwachting evenredig is met de verandering in FP+TN (alle negatieve instanties). Als de verdeling van de onderliggende data dus verandert, verandert de ROC niet noemenswaardig. Deze ongevoeligheid voor klassenverdeling maakt de PR-curve een betere keuze dan de ROC-curve.
Tot slot
Precision en recall zijn belangrijke evaluatiemetrics om de prestaties van machinelearning-classificatiemodellen te meten. De trade-off tussen beide hangt echter af van de zakelijke prioriteit en wordt het best opgelost met behulp van de PR-curve. In dit artikel is uitgelegd hoe je de PR-curve interpreteert en de juiste drempel kiest om je zakelijke doel te behalen. Verder liet de post stap voor stap zien hoe je de curve in Python plot. Ook bespraken we waarom de PR-curve informatiever is dan de ROC-curve.
