R Academy · Les

SVD-, QR- en Cholesky-ontbindingen

Pas svd(), qr() en chol() toe voor dimensiereductie en factorisatie.

Les 4 van 413 stappen

SVD-, QR- en Cholesky-ontbindingen is een gratis R Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject R Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus R Academy bevat in totaal 4 lessen.

Waarom matrixdecomposities?

Matrixdecomposities ontbinden A in producten van eenvoudigere matrices. Ze onthullen verborgen structuur (rang, conditie), maken efficiënte berekeningen mogelijk en vormen de basis van PCA, regressie en optimalisatie in de statistiek en machine learning.

# Three fundamental decompositions:
# 1. SVD: A = U D V'  (any matrix)
# 2. QR:  A = Q R    (any matrix)
# 3. Cholesky: A = L L'  (symmetric positive definite)

# Each serves a purpose:
# SVD -> PCA, pseudoinverse, rank, image compression
# QR  -> linear regression, Gram-Schmidt, eigenvalues
# Cholesky -> fast solve for SPD systems, simulation

A <- matrix(c(4, 3, 2,
              3, 6, 1,
              2, 1, 5), nrow = 3, byrow = TRUE)
cat('Matrix ready for decomposition')
print(A)

SVD: functie svd()

De singulierewaardedecompositie (SVD) factoriseert elke m×n-matrix als A = U D V', waarbij U en V orthogonaal zijn en D diagonaal is met niet-negatieve singuliere waarden in aflopende volgorde.

A <- matrix(c(1, 2, 3,
              4, 5, 6), nrow = 2, byrow = TRUE)

# Compute SVD
svd_result <- svd(A)

# Components:
svd_result$d  # singular values (decreasing)
svd_result$u  # left singular vectors  (2x2)
svd_result$v  # right singular vectors (3x2)

cat('Singular values:', svd_result$d, '\n')
cat('Rank of A:', sum(svd_result$d > 1e-10), '\n')

SVD-reconstructie

Reconstrueer A uit de SVD als A = U %*% diag(d) %*% t(V). Benaderingen met lage rang behouden alleen de eerste k singuliere waarden en vectoren; dit vormt de basis van beeldcompressie en ruisonderdrukking.

A <- matrix(c(1, 2, 3,
              4, 5, 6,
              7, 8, 9), nrow = 3, byrow = TRUE)

res <- svd(A)
U <- res$u; d <- res$d; V <- res$v

# Full reconstruction: A = U diag(d) V'
A_reconstructed <- U %*% diag(d) %*% t(V)
all.equal(A, A_reconstructed)  # TRUE

# Rank-1 approximation (best rank-1 approx by Eckart-Young)
A_rank1 <- d[1] * U[, 1] %*% t(V[, 1])
print(round(A_rank1, 2))

# Frobenius error of rank-1 approx
sqrt(sum((A - A_rank1)^2))

SVD: pseudoinverse en rang

De SVD geeft de pseudoinverse A⁺ = V D⁺ U', waarbij D⁺ elke niet-nulle singuliere waarde vervangt door haar reciproke. Hiermee los je Ax = b op in de kleinste-kwadratenzin, ook als A niet vierkant is of niet de volledige rang heeft.

A <- matrix(c(1, 2, 3,
              4, 5, 6), nrow = 2, byrow = TRUE)

# Pseudoinverse via SVD
svd_res <- svd(A)
tol <- 1e-10
# Invert nonzero singular values
d_inv <- ifelse(svd_res$d > tol, 1/svd_res$d, 0)
A_pinv <- svd_res$v %*% diag(d_inv) %*% t(svd_res$u)
print(A_pinv)  # 3x2 pseudoinverse

# Least-squares solution: x = A+ b
b <- c(7, 8)
x_ls <- A_pinv %*% b
print(x_ls)

# Compare with MASS::ginv
# MASS::ginv(A) should give the same result

QR-decompositie: qr()

QR-decompositie ontbindt A als A = QR, waarbij Q orthogonaal is (Q'Q = I) en R bovendriehoekig. Deze wordt gebruikt bij lineaire regressie, het berekenen van eigenwaarden (QR-algoritme) en Gram-Schmidt-orthogonalisatie.

A <- matrix(c(1, 2,
              3, 4,
              5, 6), nrow = 3, byrow = TRUE)

# Compute QR decomposition
qr_res <- qr(A)

# Extract Q and R
Q <- qr.Q(qr_res)  # 3x2 orthogonal
R <- qr.R(qr_res)  # 2x2 upper triangular

cat('Q is orthogonal: Q\'Q = I\n')
print(round(t(Q) %*% Q, 10))  # Identity

cat('R is upper triangular:\n')
print(round(R, 6))

# Reconstruct A = Q %*% R
all.equal(A, Q %*% R)  # TRUE

QR voor regressie

De normale vergelijkingen van lineaire regressie oplossen via QR is numeriek beter. Omdat Q'Q = I, worden de normale vergelijkingen A'Ax = A'b gelijk aan R'Q'QRx = R'Q'b, wat vereenvoudigt tot Rx = Q'b; dit los je op met achterwaartse substitutie.

# Generate regression data
set.seed(7)
n <- 20
x1 <- rnorm(n); x2 <- rnorm(n)
y <- 1 + 2*x1 - 0.5*x2 + rnorm(n, sd = 0.5)

# Design matrix
X <- cbind(intercept = 1, x1 = x1, x2 = x2)

# QR solve: numerically stable
beta_qr <- qr.solve(X, y)
print(beta_qr)  # ~c(1, 2, -0.5)

# Compare with lm()
beta_lm <- coef(lm(y ~ x1 + x2))
all.equal(beta_qr, beta_lm, check.names = FALSE)  # TRUE

# The qr.solve internals use backsolve on R
cat('QR regression is lm()\'s default method')

Cholesky-decompositie: chol()

Cholesky factoriseert een symmetrisch positief definiete matrix als A = L L', waarbij L onderdriehoekig is. R's chol() geeft de bovendriehoekige factor U terug, zodat A = t(U) %*% U.

# Symmetric positive definite matrix
A <- matrix(c(4, 2,
              2, 3), nrow = 2, byrow = TRUE)

# Cholesky decomposition: A = t(U) %*% U
U <- chol(A)
print(U)
# Note: chol() returns UPPER triangular in R

# Reconstruct
all.equal(A, t(U) %*% U)  # TRUE

# Attempting Cholesky on non-PD matrix throws error
# Catch it:
result <- tryCatch(
  chol(matrix(c(1, 3, 3, 2), nrow = 2)),
  error = function(e) cat('Error:', e$message)
)

Oplossen met Cholesky

Voor symmetrisch positief definiete stelsels, zoals covariantiematrices, is oplossen op basis van Cholesky twee keer zo snel als met LU. Gebruik chol2inv() om de inverse te berekenen, of gebruik backsolve/forwardsolve met de Cholesky-factor.

# SPD system: typical in statistics (covariance matrices)
set.seed(1)
X <- matrix(rnorm(30), nrow = 10, ncol = 3)
A <- crossprod(X)  # X'X is always SPD
b <- c(1, 2, 3)

# Cholesky factor
U <- chol(A)  # Upper triangular

# Solve A x = b using two triangular solves
# A = t(U) %*% U -> solve t(U) y = b, then U x = y
y <- forwardsolve(t(U), b)
x <- backsolve(U, y)
print(x)

# Verify
all.equal(as.vector(A %*% x), b)

# Or: inverse via chol2inv
A_inv <- chol2inv(U)
all.equal(x, as.vector(A_inv %*% b))

SVD in PCA

PCA via SVD: centreer de gegevensmatrix X en bereken vervolgens de SVD van de gecentreerde X. De rechter singuliere vectoren V zijn de richtingen van de hoofdcomponenten; de singuliere waarden d houden verband met de verklaarde variantie (d²/(n-1)).

set.seed(42)
n <- 50; p <- 3
X <- matrix(rnorm(n * p), nrow = n)
# Add correlation
X[, 2] <- 0.8 * X[, 1] + 0.6 * X[, 2]

# Center
X_c <- scale(X, center = TRUE, scale = FALSE)

# SVD of centered data
svd_res <- svd(X_c)

# Variance explained by each PC
var_explained <- svd_res$d^2 / (n - 1)
prop_var <- var_explained / sum(var_explained)
cat('Proportion of variance explained:\n')
print(round(prop_var, 3))

# Compare with prcomp
pc <- prcomp(X)
all.equal(prop_var, pc$sdev^2 / sum(pc$sdev^2))

Matrixrang via SVD

De rang van een matrix is gelijk aan het aantal niet-verwaarloosbare singuliere waarden. SVD biedt de numeriek betrouwbaarste manier om de rang te bepalen: tel eenvoudig de d-waarden boven een drempel, doorgaans max(d) * tol.

# Full-rank matrix (rank 3)
A <- matrix(c(1, 0, 0,
              0, 2, 0,
              0, 0, 3), nrow = 3)
svd(A)$d  # c(3, 2, 1) - all nonzero -> rank 3

# Rank-deficient matrix (rank 2)
B <- matrix(c(1, 2, 3,
              2, 4, 6,   # row 2 = 2 * row 1
              0, 1, 1), nrow = 3, byrow = TRUE)
svd(B)$d  # Third value is ~0

# Rank function using SVD
matrix_rank <- function(M, tol = 1e-10) {
  d <- svd(M)$d
  sum(d > tol * d[1])  # relative tolerance
}
matrix_rank(B)  # 2

Cholesky voor steekproeven uit een multivariate normale verdeling

Om een steekproef te trekken uit een multivariate normale verdeling N(μ, Σ), bereken je de Cholesky-factor U van Σ en transformeer je vervolgens standaardnormale waarden: X = μ + Z %*% U. Zo werkt MASS::mvrnorm() intern.

set.seed(99)
# Covariance matrix
Sigma <- matrix(c(4, 2,
                  2, 3), nrow = 2)
mu <- c(1, 5)
n_samples <- 500

# Cholesky factor
U <- chol(Sigma)

# Sample standard normals
Z <- matrix(rnorm(n_samples * 2), nrow = n_samples)

# Transform: X ~ N(mu, Sigma)
X <- sweep(Z %*% U, 2, mu, FUN = '+')

# Check empirical covariance
print(round(cov(X), 2))  # Should be close to Sigma
print(round(colMeans(X), 2))  # Should be close to mu

Korte controle

Test je begrip van SVD-, QR- en Cholesky-decomposities in R.

Samenvatting: SVD, QR en Cholesky

Belangrijkste punten: SVD (svd()) geeft d, u en v terug en wordt gebruikt voor PCA, rang, pseudoinverse en benaderingen met lage rang. QR (qr()) geeft een orthogonale Q en bovendriehoekige R terug en wordt gebruikt voor regressie en stabiliteit. Cholesky (chol()) geeft de bovendriehoekige U terug waarvoor A = t(U)%*%U; deze is het snelst voor SPD-stelsels. Alle decomposities reconstrueren A exact en dienen verschillende rekenkundige doelen.

A <- matrix(c(4, 2, 2, 3), nrow = 2)

# SVD
res <- svd(A)
all.equal(A, res$u %*% diag(res$d) %*% t(res$v))  # TRUE

# QR (on a design matrix)
X <- cbind(1, c(1,2,3,4,5))
qr_res <- qr(X)
all.equal(X, qr.Q(qr_res) %*% qr.R(qr_res))  # TRUE

# Cholesky
U <- chol(A)
all.equal(A, t(U) %*% U)  # TRUE

# Use cases:
# svd() -> PCA, rank, pseudoinverse
# qr()  -> regression, stability
# chol()-> SPD solve, MVN sampling
Gratis beginnen

Leer R met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
43
Lessen
159

Veelgestelde vragen

Is de les “SVD-, QR- en Cholesky-ontbindingen” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad R Academy, waaronder “SVD-, QR- en Cholesky-ontbindingen”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus R Academy bevat in totaal 4 lessen.

Wat leer ik in “SVD-, QR- en Cholesky-ontbindingen”?

Pas svd(), qr() en chol() toe voor dimensiereductie en factorisatie. Je oefent met R Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met R Academy te beginnen?

Ervaring vooraf is niet nodig. R Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “SVD-, QR- en Cholesky-ontbindingen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over R Academy?

Ja. Elke les over R Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Matrixvermenigvuldiging en determinanten
  2. Lineaire stelsels oplossen met solve()
  3. Eigenwaarden en eigenvectoren
  4. SVD-, QR- en Cholesky-ontbindingen
← Terug naar R Academy