Werkplaats / De werkplaats
In jouw eigen tempo
← Klassieke machine learning
MODULE 01 · LES 02

Kies wat een fout je kost

Bereken MAE, MSE, RMSE en R² en herken wanneer een score niet gedefinieerd is.

50 min3 checkpoints
DIT GA JE ONTDEKKEN
  • Je vergelijkt absolute en gekwadrateerde fouten.
  • Je interpreteert R² tegenover een constante baseline, inclusief negatieve scores.

Een bezorgvoorspelling kan één minuut of een uur miszitten. Beide zijn één verkeerde voorspelling, maar voor de ontvanger maken ze veel verschil. Een evaluatiemaatstaf (metric) legt vast hoe je zulke fouten samen beoordeelt.

Je kent residuen: doel min voorspelling. Gemiddeld nul is onvoldoende, want een te hoge en een te lage voorspelling kunnen elkaar wegstrepen. We maken iedere bijdrage eerst niet-negatief, en bekijken daarna welke fouten zwaarder meetellen.

1. Geef iedere gemiste eenheid hetzelfde gewicht

Neem drie gemeten tijden [1, 3, 5] en voorspellingen [2, 2, 8], allemaal in minuten. De residuen zijn −1, 1 en −3. Hun absolute waarden zijn 1, 1 en 3: samen 5 minuten fout, gemiddeld 5/3, ongeveer 1.667.

MAE=1n∑|yi−y^i|

Gemiddelde absolute fout (mean absolute error, MAE) telt de absolute afwijkingen en deelt door aantal n. i benoemt een meetpaar; y is het doel en y met dakje de voorspelling. De verticale strepen nemen de afstand tot nul, in Python abs.

ys = [1, 3, 5]
pred = [2, 2, 8]
totaal = 0
for i in range(len(ys)):
    totaal = totaal + abs(ys[i] - pred[i])
print(totaal / len(ys))  # 1.666...

Maak mae(ys,pred) voor niet-lege lijsten met gelijke lengte. Geef bij een ongeldige lengte ValueError voordat je deelt of indexeert. Een verdwenen meetpaar stilletjes overslaan zou ook de betekenis van je score veranderen.

01
CHECKPOINTTel absolute afwijkingen

2. Laat grote missers harder meetellen

Voor dezelfde residuen zijn de kwadraten 1, 1 en 9. De gemiddelde kwadratische fout (mean squared error, MSE) is daarom 11/3, ongeveer 3.667 vierkante minuten. De fout van drie minuten levert negen maal de bijdrage van een fout van één minuut.

MSE=1n∑(yi−y^i)2RMSE=MSE

Alle symbolen benoemen dezelfde meetparen als bij MAE. De wortel van de gemiddelde kwadratische fout (root mean squared error, RMSE) brengt de score terug naar minuten: ongeveer 1.915. Eerst middelen en dan de wortel nemen verschilt van absolute fouten middelen.

import math
kwadraten = 0
for i in range(len(ys)):
    fout = ys[i] - pred[i]
    kwadraten = kwadraten + fout ** 2
mse = kwadraten / len(ys)
rmse = math.sqrt(mse)
print(mse, rmse)  # ongeveer 3.667, 1.915

Maak kwadraatscores(ys,pred) als het paar (mse,rmse), met dezelfde lengtecontrole. Beide zijn nul bij perfecte voorspellingen. Kies vooraf welke foutkosten bij je toepassing passen; de kleinste ruwe score kiezen tussen verschillende eenheden heeft geen betekenis.

02
CHECKPOINTLaat grote afwijkingen zwaarder tellen

De visualisatie gebruikt vijf absolute fouten: viermaal 1 en één instelbare uitschieter. Zet die laatste op 10. Voorspel eerst: MAE wordt 14/5 = 2.8, MSE wordt 104/5 = 20.8 en RMSE ongeveer 4.561.

VIER KLEINE FOUTEN, ÉÉN GROTEWat kost een uitschieter?

De absolute fouten zijn 1, 1, 1, 1 en jouw gekozen waarde. MAE en RMSE hebben dezelfde eenheid; MSE heeft de gekwadrateerde eenheid.

MAE1.600RMSE2.000gelijke schaal · oorspronkelijke doeleenheid
MAE1.600MSE4.000RMSE2.000

3. Vergelijk met een duidelijk nulpunt

Een foutscore hangt ook af van hoe sterk de doelen uiteenlopen. R-kwadraat (R²) vergelijkt je gekwadrateerde fout met altijd het gemiddelde van de evaluatiedoelen voorspellen. Dit is een rekenreferentie voor de score, geen model dat je op testdata mag trainen.

Bij onze doelen [1, 3, 5] is dat gemiddelde 3. De afwijkingen ervan zijn −2, 0 en 2, met kwadratensom 8. Ons model heeft kwadratensom 11: slechter dan die constante referentie.

R2=1−SSESST1−118=−0.375

SSE is de som van gekwadrateerde modelresiduen. SST is de som van gekwadrateerde doelafwijkingen rond hun gemiddelde. De afkortingen houden de formule kort; voor de berekening gebruik je weer eenvoudige lussen.

gemiddelde = sum(ys) / len(ys)
sst = 0
for i in range(len(ys)):
    sst = sst + (ys[i] - gemiddelde) ** 2
sse = kwadraten
print(1 - sse / sst)  # -0.375

Bij perfecte voorspellingen is R² gelijk aan 1; bij dezelfde kwadratensom als de referentie is het 0. Veelgemaakte fout: R² behandelen als percentage correcte antwoorden, of negatieve waarden op nul afkappen. Hier vertelt juist het minteken iets nuttigs.

Maak r2(ys,pred) met dezelfde lengtecontrole. Zijn alle doelen gelijk, dan is SST nul; geef volgens ons oefencontract None, ook bij een perfecte voorspelling. Bibliotheken kunnen voor dat geval een andere conventie kiezen.

03
CHECKPOINTVergelijk met een constante voorspelling

Wat neem je mee?

  • MAE telt iedere gemiste eenheid gelijk; MSE benadrukt grote missers en RMSE herstelt de doeleenheid.
  • R² vergelijkt met een vaste rekenreferentie en kan negatief zijn.
  • Meet generalisatie op apart gehouden data en vermeld grootheid, eenheid en referentie.

Hierna gebruik je MSE als verliesfunctie om de lijn zelf te laten leren.

Verder lezen & bronnen

Inhoud gecontroleerd op 2026-10-28.
DE VOLGENDE STAPLaat de lijn stap voor stap leren
JOUW EXPERIMENT

Probeer het zelf

Python
main.py

Python start zodra jij code uitvoert.

UITVOER

Je uitvoer verschijnt hier.
Alles rekent in je eigen browser.

Jouw checkpoints0 / 3
01
Tel absolute afwijkingen

Schrijf mae(ys,pred), met ValueError voor lege of ongelijke lijsten.

Een hint

Som de absolute verschillen en deel door het aantal waarnemingen.

02
Laat grote afwijkingen zwaarder tellen

Schrijf kwadraatscores(ys,pred) als (MSE,RMSE), met dezelfde invoercontrole als MAE.

Een hint

Bereken eerst MSE; RMSE is de positieve vierkantswortel.

03
Vergelijk met een constante voorspelling

Schrijf r2(ys,pred), met None voor constante doelen en ValueError voor lege of ongelijke invoer.

Een hint

Bereken het doelgemiddelde en test SST voordat je deelt.

Vastgelopen? Bekijk de voorbeeldoplossing
def mae(ys, pred):
    if not ys or len(ys) != len(pred):
        raise ValueError("Evenveel niet-lege paren vereist")
    totaal = 0
    for i in range(len(ys)):
        totaal = totaal + abs(ys[i] - pred[i])
    return totaal / len(ys)


def kwadraatscores(ys, pred):
    if not ys or len(ys) != len(pred):
        raise ValueError("Evenveel niet-lege paren vereist")
    totaal = 0
    for i in range(len(ys)):
        fout = ys[i] - pred[i]
        totaal = totaal + fout ** 2
    mse = totaal / len(ys)
    return mse, mse ** 0.5


def r2(ys, pred):
    if not ys or len(ys) != len(pred):
        raise ValueError("Evenveel niet-lege paren vereist")
    gemiddelde = sum(ys) / len(ys)
    sst = 0
    sse = 0
    for i in range(len(ys)):
        sst = sst + (ys[i] - gemiddelde) ** 2
        sse = sse + (ys[i] - pred[i]) ** 2
    if sst == 0:
        return None
    return 1 - sse / sst

Voer de code uit en verklaar voor jezelf waarom elke stap werkt.