Werkplaats / De werkplaats
In jouw eigen tempo
← Data
MODULE 03 · LES 07

Verander de eenheid, behoud de betekenis

Standaardiseer vanuit training en onderzoek hoe eenheden een afstand veranderen.

45 min3 checkpoints
DIT GA JE ONTDEKKEN
  • Je past een scaler toe met uitsluitend trainingsstatistieken.
  • Je handelt constante features af en kunt een transformatie terugdraaien.

Een plant van twintig centimeter is tweehonderd millimeter hoog. Er is niets gegroeid, maar een berekening met die getallen kan de hoogte ineens veel zwaarder laten meetellen. Kenmerken schalen (feature scaling) maakt die invloed van eenheden zichtbaar en controleerbaar.

Je kent standaardiseren uit de les over verbanden en fit/transform uit de vorige module. Nu combineren we die ideeën: leer één centrum en één schaal op training en bewaar ze voor alle volgende metingen. Schalen herstelt geen meetfouten en maakt een verdeling niet vanzelf normaal.

1. Leer de meetlat op training

Neem twee trainingshoogtes: 2 en 6 centimeter. Het midden is 4; beide waarden liggen er 2 centimeter vandaan. De populatievariantie is daarom het gemiddelde van 4 en 4, dus 4, en de standaardafwijking is 2.

m=2+62=4s=4=2

m is het trainingsgemiddelde, s de trainingsschaal. We delen de som van gekwadrateerde afwijkingen door het aantal n; we gebruiken hier dus de populatieversie, niet de schatting met n−1. Het doel is een vaste voorbereiding van deze trainingsgegevens.

import math
train = [2, 6]
totaal = 0
for i in range(len(train)):
    totaal = totaal + train[i]
mean = totaal / len(train)
kwadraten = 0
for i in range(len(train)):
    verschil = train[i] - mean
    kwadraten = kwadraten + verschil ** 2
scale = math.sqrt(kwadraten / len(train))
if scale == 0:
    scale = 1.0
state = {"mean": mean, "scale": scale}
print(state)   # {'mean': 4.0, 'scale': 2.0}

math.sqrt berekent de vierkantswortel; ** 2 is het bekende kwadraat. Maak fit_schaal(train) voor kleine eindige oefenwaarden en geef de dictionary terug. Weiger lege training met ValueError voordat je deelt.

Bij constante training, bijvoorbeeld [5,5], is de werkelijke standaardafwijking nul. We kiezen dan expliciet de vervangschaal 1, zodat delen mogelijk blijft. Bewaar mean 5 en scale 1; deze afspraak verzint geen gemeten spreiding.

01
CHECKPOINTLeg centrum en schaal vast

2. Verander test niet in een nieuwe meetlat

Een nieuwe hoogte 8 ligt 4 centimeter boven ons gemiddelde. Met schaal 2 zijn dat twee trainingsstandaardafwijkingen. Dezelfde omzetting stuurt de trainingswaarden 2 en 6 naar −1 en 1.

z=x−ms=8−42=2

x is de oorspronkelijke meting, z de omgezette waarde. Gebruik in code steeds dezelfde state; de testwaarde bepaalt geen nieuw gemiddelde of nieuwe schaal.

xs = [2, 6, 8]
zs = []
for i in range(len(xs)):
    z = (xs[i] - state["mean"])
    z = z / state["scale"]
    zs.append(z)
print(zs)   # [-1.0, 1.0, 2.0]

Maak schaal(xs, state) met een nieuwe lijst; verander invoer en toestand niet. Voor een lege lijst is het resultaat [].

02
CHECKPOINTEén schaal voor bekende en onbekende rijen

Veelgemaakte fout: bij iedere verzameling opnieuw fit uitvoeren omdat de uitkomst dan mooi rond nul ligt. Daarmee krijgt test een andere meetlat en lekt informatie. Een testgemiddelde dat afwijkt van nul kan juist een echt verschil met training tonen.

De visualisatie vergelijkt twee planten met hoogteverschil en leeftijdsverschil. Zet het hoogteverschil op 20 centimeter; het leeftijdsverschil blijft 2 jaar. Ruw krijg je de wortel uit 20²+2², ongeveer 20.100; met trainingsschalen 20 cm en 5 jaar wordt het de wortel uit 1²+0.4², ongeveer 1.077.

print(math.sqrt(20 ** 2 + 2 ** 2))
print(math.sqrt((20 / 20) ** 2 + 0.4 ** 2))
# ongeveer 20.100 en 1.077
WELKE FEATURE TELT HET ZWAARST?Eenheden veranderen de afstand

Twee planten verschillen 30 cm in hoogte en 2 jaar in leeftijd. Vaste trainingsschalen: 20 cm en 5 jaar.

Ruwe eenheden: bijdrage aan gekwadrateerde afstandGestandaardiseerd: bijdrage aan gekwadrateerde afstandgroen: hoogte · oranje: leeftijd
Ruwe afstand30.067Na standaardiseren1.552

Bij millimeters verandert ook de trainingsschaal van 20 cm naar 200 mm. De gestandaardiseerde afstand blijft daardoor gelijk.

Controleer eerst Centimeters, daarna Millimeters. Ruw stijgt de afstand naar ongeveer 200.010; gestandaardiseerd blijft hij 1.077 omdat de hoogteschaal ook van 20 cm naar 200 mm gaat. De gekleurde balken tonen het aandeel van beide kenmerken in de gekwadrateerde afstand, niet de afstand zelf.

3. Ga terug met dezelfde opgeslagen toestand

Om een z-waarde terug te brengen, vermenigvuldig je met de schaal en tel je het gemiddelde op. Voor z=2 geeft dat 2×2+4=8. Het volgordeverschil is belangrijk: eerst vermenigvuldigen, dan verschuiven.

x=z×s+m=8
hersteld = []
for i in range(len(zs)):
    x = zs[i] * state["scale"]
    hersteld.append(x + state["mean"])
print(hersteld)   # [2.0, 6.0, 8.0]

Maak herstel(zs, state). Een heen-en-terugcontrole, ook wel roundtrip, hoort de oorspronkelijke waarden op kleine afrondingsfouten na terug te geven.

03
CHECKPOINTBreng een waarde terug naar de oorspronkelijke eenheid

Bij constante training [5,5] krijgt testwaarde 7 de uitkomst 2, doordat we van 7 het centrum 5 aftrekken en delen door vervangschaal 1. Dat zijn geen twee werkelijk gemeten standaardafwijkingen, want die waren nul. De inverse brengt de waarde wel correct terug naar 7.

Wat neem je mee?

  • Fit leert centrum en schaal uitsluitend uit training; gebruik ze daarna onveranderd.
  • Schalen bepaalt de relatieve invloed van kenmerken, niet of je gegevens juist zijn.
  • Bewaar de toestand voor gebruik en herstel; een vervangschaal bij nulspreiding heeft een andere interpretatie.

Hierna maak je kenmerken van kleuren, waarbij getallen juist geen natuurlijke rangorde hebben.

Verder lezen & bronnen

Inhoud gecontroleerd op 2026-10-28.
DE VOLGENDE STAPEen kleur is geen rangnummer
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
Leg centrum en schaal vast

Schrijf fit_schaal(train) met een dictionary {mean,scale}.

Een hint

De schaal is de wortel uit de gemiddelde gekwadrateerde afwijking; vervang alleen een schaal nul door één.

02
Eén schaal voor bekende en onbekende rijen

Schrijf schaal(xs,state), zonder de invoer te wijzigen.

Een hint

Gebruik de opgeslagen toestand voor elke waarde.

03
Breng een waarde terug naar de oorspronkelijke eenheid

Schrijf herstel(zs,state) en draai de transformatie terug.

Een hint

De inverse van (x−mean)/scale is z*scale+mean.

Vastgelopen? Bekijk de voorbeeldoplossing
import math


def fit_schaal(train):
    if len(train) == 0:
        raise ValueError("Lege training")
    totaal = 0
    for i in range(len(train)):
        totaal = totaal + train[i]
    mean = totaal / len(train)
    kwadraten = 0
    for i in range(len(train)):
        verschil = train[i] - mean
        kwadraten = kwadraten + verschil ** 2
    scale = math.sqrt(kwadraten / len(train))
    if scale == 0:
        scale = 1.0
    return {"mean": mean, "scale": scale}


def schaal(xs, state):
    zs = []
    for i in range(len(xs)):
        z = xs[i] - state["mean"]
        zs.append(z / state["scale"])
    return zs


def herstel(zs, state):
    xs = []
    for i in range(len(zs)):
        x = zs[i] * state["scale"]
        xs.append(x + state["mean"])
    return xs

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