- Je vindt hoofdcomponenten van gecentreerde data.
- Je projecteert en reconstrueert met dezelfde trainingsbasis en meet het informatieverlies.
Een plantenmeting heeft twintig features, maar je wilt de puntenwolk op een scherm bekijken. Welke twee getallen kun je per plant bewaren zonder alle verschillen weg te gooien? Principal component analysis (PCA) zoekt loodrechte richtingen die zoveel mogelijk variatie behouden.
Stel je een lichtbundel voor die punten op een as projecteert. Je bewaart de positie op die as; terugleggen geeft een benadering van het oorspronkelijke punt. Verschillen loodrecht op de as verdwijnen.
1. Zet het midden van de wolk op nul
Neem vier punten [0,0], [0,2], [4,0] en [4,2]. Hun kolomgemiddelde is μ = [2,1]. Na centreren zijn de afwijkingen [−2,−1], [−2,1], [2,−1] en [2,1].
De covariantiematrix meet spreiding en gezamenlijke beweging van de features. De eerste feature heeft gekwadrateerde afwijkingen die optellen tot 16, de tweede tot 4; de kruisproducten tellen op tot nul. Met steekproefdeler n−1 = 3 krijg je een diagonale matrix met 16/3 en 4/3.
X heeft n rijen en d features; μ bevat d gemiddelden en C heeft d bij d elementen. .T transponeert en @ vermenigvuldigt matrices. Trek met NumPy dezelfde gemiddeldevector van iedere rij af:
import numpy as np
X = np.array([[0, 0], [0, 2],
[4, 0], [4, 2]], dtype=float)
mu = X.mean(axis=0)
A = X - mu
C = A.T @ A / (len(X) - 1)
print(mu.tolist()) # [2.0, 1.0]
print(C)
# ongeveer [[5.333333, 0], [0, 1.333333]]
axis=0 middelt per kolom, over de rijen. Maak covariantiematrix(rows) als (mean,cov) met floatarrays. Vereis minstens twee rijen; we werken met een rechthoekige matrix van eindige getallen en minstens één feature.
Grote eenheden kunnen de uitkomst domineren. Vooraf standaardiseren is een inhoudelijke keuze: wil je oorspronkelijke spreiding behouden of iedere feature eerst vergelijkbaar wegen? Leer die voorbereiding uitsluitend op training.
012. Zoek de as met de meeste spreiding
Voor onze wolk is horizontaal duidelijk meer variatie dan verticaal. Vector [1,0] wijst horizontaal; vermenigvuldiging met C geeft [16/3,0]. De richting blijft gelijk en alleen de lengte verandert.
Zo'n richting heet een eigenvector; de vermenigvuldigingsfactor heet haar eigenwaarde. Voor een eenheidsvector is die eigenwaarde de steekproefvariantie langs de richting. PCA behoudt de richtingen met de grootste waarden.
De symmetrische covariantiematrix heeft loodrechte eigenrichtingen. np.linalg.eigh berekent ze en geeft eigenvectoren als kolommen, met eigenwaarden in oplopende volgorde. Je moet die volgorde dus omkeren voordat je de eerste k richtingen kiest.
values, vectors = np.linalg.eigh(C)
order = np.argsort(values)[::-1]
k = 1
V = vectors[:, order[:k]]
print(values[order])
# ongeveer [5.333,1.333]
print(V.shape) # (2, 1)
argsort geeft sorteerindices, [::-1] keert ze om en [:,...] selecteert kolommen. Maak fit_pca(rows,k) met mean, components als d-bij-k matrix en alle eigenvalues aflopend. Vereis een geheel aantal componenten met 1 ≤ k ≤ d.
Veelgemaakte fout: één voorgeschreven vectorteken eisen. v en −v beschrijven dezelfde as; beide zijn correct als projectie en reconstructie dezelfde basis gebruiken. Bij gelijke eigenwaarden kunnen ook verschillende loodrechte bases binnen die ruimte geldig zijn.
De punten zijn al gecentreerd. Groen is de gekozen richting; oranje lijnen tonen wat de één-dimensionale reconstructie verliest.
De knop berekent de hoofdrichting uit de covariantie en rondt op één graad af. 180° omkeren geeft dezelfde as.
Voorspel welke as de schuine wolk goed volgt. Draai de as en klik daarna op “Richt op PCA”: meer projectievariantie hoort hier bij minder reconstructiefout. Het diagram gebruikt in beide maten deler n; de richting blijft dezelfde als bij n−1.
023. Projecteer en leg terug met dezelfde basis
Met onze horizontale V = [1,0] bewaart ieder punt alleen zijn horizontale afwijking: scores [−2,−2,2,2]. Terugleggen en μ toevoegen geeft [0,1], [0,1], [4,1] en [4,1]. Iedere verticale afwijking van één is verloren, dus de gemiddelde gekwadrateerde reconstructieafstand is 1.
Z = (X - mu) @ V
herstel = Z @ V.T + mu
fout = ((X - herstel) ** 2).sum(axis=1)
print(Z.shape) # (4, 1)
print(fout.mean()) # 1.0
sum(axis=1) telt de featurefouten binnen iedere rij op; daarna middel je over de punten. Maak projecteer(rows,state) en reconstrueer(z,state). Gebruik de opgeslagen trainings-μ en V ook voor nieuwe voorbeelden.
nieuw = np.array([[3., 4.]])
score = (nieuw - mu) @ V
herstel = score @ V.T + mu
print(herstel.tolist()) # [[3.0, 1.0]]
print(mu.tolist()) # nog steeds [2.0, 1.0]
Opnieuw centreren op alleen het nieuwe punt zou zijn score nul maken en de trainingsbasis veranderen. Met alle d componenten kun je op afronding na exact herstellen; met minder componenten verdwijnen afwijkingen buiten de behouden ruimte.
Veel variatie is geen garantie voor voorspellende informatie. PCA gebruikt geen labels en kan een weinig variërende maar belangrijke eigenschap verwijderen.
03Wat neem je mee?
- Centreren maakt spreiding rond het trainingsgemiddelde zichtbaar.
- Eigenrichtingen ordenen die spreiding; kolommen van V vormen de behouden basis.
- Dezelfde μ en V koppelen projectie aan reconstructie, ook bij nieuwe punten.
Hierna combineer je een projectie met k-means in een notebook en beoordeel je de gevonden groepen kritisch.