Werkplaats / Notebook
In jouw eigen tempo
← Alle bouwprojecten
Klassieke machine learning · PYTHON NOTEBOOK

Je eigen regressie naast scikit-learn

Train twee echte modellen, vergelijk ze op onbekende voorbeelden en teken hun voorspellingen.

110 min4 cellen
De opdracht, leerdoelen en voorkennis
  • Je vergelijkt een eigen kleinste-kwadratenmodel met een echte scikit-learn-pipeline.
  • Je meet prestaties op vaste testdata tegenover een trainingsgemiddelde-baseline.
  • Je maakt een grafiek van berekende voorspellingen.

Lees eerst: Bouw een herbruikbare data-pipeline · Laat de lijn stap voor stap leren.

Als jouw regressie en een bibliotheek dezelfde voorspellingen geven, heb je een sterke controle op je implementatie. In dit project bouw je beide en vergelijk je ze met een eenvoudige referentie. Alle data zijn verzonnen: een mooie score bewijst hier de berekening, geen bruikbaarheid op echte plantmetingen.

Je werkt in vier cellen: data, eigen model, bibliotheekmodel en vergelijking. Zoals in het datanotebook blijven variabelen bestaan. Voer na een wijziging ook de afhankelijke cellen opnieuw uit, of gebruik Alles uitvoeren.

1. Geef een bibliotheek de juiste tabel

NumPy bewaart getallen in arrays waarop je tegelijk kunt rekenen. import numpy as np geeft de bibliotheek de korte naam np; np.array maakt een array van een lijst. dtype=float kiest opslag met kommagetallen. Dat is relevant wanneer je een fractionele uitkomst in een array bewaart; het berekenen van een gemiddelde kan ook bij integerinvoer een kommagetal opleveren.

Scikit-learn verwacht features als een tabel: vorm (n,1) betekent n rijen en één kolom. Doelen hebben vorm (n,), één getal per rij. In dit kleine voorbeeld staan twee trainingsparen: (0,1) en (2,5).

import numpy as np
a = np.array([0, 2], dtype=float)
x = a.reshape(-1, 1)
y = np.array([1, 5], dtype=float)
xt = np.array([[1.], [3.]])
yt = np.array([3., 7.])
print(x.shape, y.shape)  # (2, 1) (2,)
print(x[:, 0])          # [0. 2.]

reshape(-1,1) maakt één kolom en laat NumPy het aantal rijen afleiden. x[:,0] selecteert alle rijen, met de dubbele punt, uit kolom 0. Gebruik deze kleine arrays om de uitleg te volgen; de projectcel vraagt de grotere vaste dataset hieronder.

Maak regressiedata() met x van −3 tot en met 3 en y gelijk aan tweemaal x plus 1, met ruis [−0.2, 0.1, 0, 0.2, −0.1, 0.1, −0.1]. Test gebruikt x = [−2.5, −0.5, 1.5, 2.5] en doelen tweemaal x plus 1, zonder ruis. Geef vier verse arrays terug en bewaar ze als x,y,xt,yt.

01
CHECKPOINTMaak de vergelijking reproduceerbaar

2. Dezelfde sommen, een kortere schrijfwijze

Voor ons kleine voorbeeld zijn de gemiddelden 1 en 3. De gecentreerde x-waarden zijn [−1,1], de y-waarden [−2,2]. De productsom is 4 en de x-kwadratensom 2: helling 2 en intercept 1.

Bij arrays werkt aftrekken van een getal elementgewijs; vermenigvuldigen van even lange arrays vermenigvuldigt overeenkomstige waarden. .mean() berekent het gemiddelde en .sum() de som. Daardoor kun je de al bekende formule zo schrijven:

def eigen_fit(x, y):
    a = x[:, 0]
    dx = a - a.mean()
    dy = y - y.mean()
    teller = (dx * dy).sum()
    noemer = (dx ** 2).sum()
    w = teller / noemer
    b = y.mean() - w * a.mean()
    return float(w), float(b)

w, b = eigen_fit(x, y)
eigen = w * xt[:, 0] + b
print(w, b, eigen)  # 2.0 1.0 [3. 7.]

float geeft een gewoon Python-kommagetal terug. De invoerafspraak voor dit lab is één numerieke featurekolom, evenveel doelen, minstens twee verschillende trainings-x-waarden en niet-lege testdata. Maak eigen_fit en bewaar voor de projectarrays w,b,eigen_voorspelling.

02
CHECKPOINTBouw de eerste deelnemer zelf

3. Een keten die haar voorbereiding bewaart

Scikit-learn levert StandardScaler voor de standaardisering en LinearRegression voor kleinste kwadraten. make_pipeline verbindt ze in die volgorde. fit(x,y) leert beide op training; predict(xt) gebruikt daarna dezelfde opgeslagen schaal.

from sklearn.pipeline import (
    make_pipeline)
from sklearn.preprocessing import (
    StandardScaler)
from sklearn.linear_model import (
    LinearRegression)

def bibliotheek_fit(x, y):
    model = make_pipeline(
        StandardScaler(),
        LinearRegression())
    model.fit(x, y)
    return model

model = bibliotheek_fit(x, y)
ander = model.predict(xt)
print(ander)  # ongeveer [3. 7.]

Maak deze functie en bewaar model en sklearn_voorspelling. Veelgemaakte fout: interne coëfficiënten rechtstreeks vergelijken. In ons kleine voorbeeld wordt x eerst naar [−1,1] getransformeerd; het bibliotheekintercept is dan 3, terwijl ons eigen intercept 1 is.

De voorspellingen bij dezelfde ruwe invoer blijven gelijk. Met één niet-constante feature verandert standaardiseren de mogelijke rechte lijnen niet. Hier oefen je vooral een correcte fit/transform-keten die later ook bij gevoeligere modellen nodig is.

03
CHECKPOINTLaat de bibliotheek dezelfde vraag beantwoorden

4. Scores én de werkelijk voorspelde lijn

De inzetbare baseline voorspelt overal het trainingsgemiddelde van y. Dat is 3 voor ons kleine voorbeeld. Op testdoelen [3,7] geeft de baseline fouten [0,−4], dus MSE = 8; beide geleerde lijnen hebben MSE = 0.

MSEbaseline=802+(−4)22=8
fout = eigen - yt
eigen_mse = float((fout ** 2).mean())
fout = ander - yt
ander_mse = float((fout ** 2).mean())
fout = y.mean() - yt
basis_mse = float((fout ** 2).mean())
afwijkingen = np.abs(eigen - ander)
verschil = float(np.max(afwijkingen))
print(eigen_mse, ander_mse, basis_mse)
# ongeveer 0.0 0.0 8.0
print(verschil)  # ongeveer 0.0

np.abs neemt iedere absolute afwijking; np.max kiest de grootste. Gebruik het testgemiddelde niet als geleerde baseline: testdoelen zijn alleen voor beoordeling. Kleine afrondingsverschillen tussen de twee modellen zijn normaal.

Teken vervolgens training en test met de bekende scatter. plot verbindt voorspelde punten met een lijn; np.argsort geeft indices waarmee je eerst op x sorteert. Anders kan een lijn tussen ongeordende testpunten teruglopen.

import matplotlib.pyplot as plt
volgorde = np.argsort(xt[:, 0])
plt.figure(figsize=(6, 3))
plt.scatter(
    x[:, 0], y, label="training")
plt.scatter(
    xt[:, 0], yt, label="test")
plt.plot(
    xt[volgorde, 0], ander[volgorde])
plt.xlabel("Synthetische feature x")
plt.ylabel("Synthetisch doel y")
plt.legend()
plt.tight_layout()

Maak vergelijk(x,y,xt,yt): train beide modellen, bereken de scores en maak een nieuwe figuur met beide datasets en de voorspelde lijn. Geef een dictionary met eigen_mse, sklearn_mse, baseline_mse en verschil terug; bewaar die als rapport. Verander de invoerarrays niet.

04
CHECKPOINTRapporteer de held-out fout en teken de lijn

Bekijk de grotere projectgrafiek: waarom liggen de ruisvrije testpunten dichter bij de lijn dan sommige trainingspunten? De bijna perfecte testscore past bij hoe we deze data maakten. Probeer een andere testdoelreeks alleen in aparte proefvariabelen, zodat de projectgegevens intact blijven.

Wat neem je mee?

  • Arrayvormen maken onderscheid tussen voorbeelden en featurekolommen.
  • Vergelijk voorspellingen op dezelfde invoer, met voorbereiding geleerd op training.
  • Een trainingsbaseline en echte grafiek helpen scores interpreteren; synthetisch succes is geen praktijkbewijs.

Hierna voorspel je categorieën in plaats van getallen.

Bronnen: scikit-learn — linear models ↗ scikit-learn — Pipeline ↗ NumPy — de eerste stappen met arrays ↗ Matplotlib — punten verbinden met plot ↗ · Gecontroleerd 2026-10-28.

Python start zodra jij code uitvoert.
[1]

Maak de vergelijking reproduceerbaar

Maak vier verse NumPy-arrays volgens de projectdata. x en xt hebben één kolom; y en yt zijn eendimensionaal. Bewaar x,y,xt,yt. Het kleine voorbeeld in de uitleg is oefenmateriaal.

Bekijk voorbeeld
import numpy as np


def regressiedata():
    waarden = [-3, -2, -1, 0, 1, 2, 3]
    x = np.array(waarden, dtype=float).reshape(-1, 1)
    ruis = np.array([-.2, .1, 0, .2, -.1, .1, -.1])
    y = 2 * x[:, 0] + 1 + ruis
    xt = np.array([[-2.5], [-.5], [1.5], [2.5]])
    yt = 2 * xt[:, 0] + 1
    return x, y, xt, yt


x, y, xt, yt = regressiedata()
print("Training:", x.shape, "Test:", xt.shape)
[2]

Bouw de eerste deelnemer zelf

Pas de gecentreerde sommen toe op x[:,0] en y. Geef twee floats terug; bewaar w,b en eigen_voorspelling voor de projecttestdata. Gebruik de arraybewerkingen uit de uitleg.

Bekijk voorbeeld
def eigen_fit(x, y):
    a = x[:, 0]
    dx = a - a.mean()
    dy = y - y.mean()
    w = (dx * dy).sum() / (dx ** 2).sum()
    b = y.mean() - w * a.mean()
    return float(w), float(b)


w, b = eigen_fit(x, y)
eigen_voorspelling = w * xt[:, 0] + b
print("Eigen parameters:", w, b)
[3]

Laat de bibliotheek dezelfde vraag beantwoorden

Verbind StandardScaler en LinearRegression met make_pipeline. Fit alleen op x,y, geef de pipeline terug en bewaar model en sklearn_voorspelling=model.predict(xt).

Bekijk voorbeeld
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression


def bibliotheek_fit(x, y):
    model = make_pipeline(StandardScaler(), LinearRegression())
    model.fit(x, y)
    return model


model = bibliotheek_fit(x, y)
sklearn_voorspelling = model.predict(xt)
print("Bibliotheekvoorspellingen:", sklearn_voorspelling)
[4]

Rapporteer de held-out fout en teken de lijn

Train beide modellen op training, bereken de drie test-MSEs en het grootste voorspelverschil. De baseline gebruikt het trainingsgemiddelde. Bewaar rapport; teken in een nieuwe figuur training, test en de berekende lijn op gesorteerde test-x. Verander de arrays niet.

Bekijk voorbeeld
import matplotlib.pyplot as plt


def vergelijk(x, y, xt, yt):
    w, b = eigen_fit(x, y)
    model = bibliotheek_fit(x, y)
    own = w * xt[:, 0] + b
    other = model.predict(xt)
    eigen_mse = float(((own - yt) ** 2).mean())
    sklearn_mse = float(((other - yt) ** 2).mean())
    baseline_mse = float(((y.mean() - yt) ** 2).mean())
    verschil = float(np.max(np.abs(own - other)))
    order = np.argsort(xt[:, 0])
    plt.figure(figsize=(6, 3))
    plt.scatter(x[:, 0], y, label="training")
    plt.scatter(xt[:, 0], yt, marker="x", label="test")
    plt.plot(xt[order, 0], other[order], label="geleerde lijn", color="#287653")
    plt.xlabel("Synthetische feature x")
    plt.ylabel("Synthetisch doel y")
    plt.legend()
    plt.tight_layout()
    return {"eigen_mse": eigen_mse, "sklearn_mse": sklearn_mse,
            "baseline_mse": baseline_mse, "verschil": verschil}


rapport = vergelijk(x, y, xt, yt)
print("Onbekende voorbeelden:", rapport)