0Pricing
R Academy · Lección

Descomposiciones SVD, QR y de Cholesky

Aplique svd(), qr() y chol() para reducir la dimensionalidad y factorizar matrices.

Descomposiciones SVD, QR y de Cholesky es una lección gratuita de R Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de R Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de R Academy incluye 4 lecciones en total.

¿Por qué se descomponen las matrices?

Las descomposiciones de matrices factorizan A como productos de matrices más sencillas. Revelan estructuras ocultas (rango, condicionamiento), permiten realizar cálculos eficientes y son fundamentales para el PCA, la regresión y la optimización en estadística y aprendizaje automático.

# 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: función svd()

La descomposición en valores singulares (SVD) factoriza cualquier matriz m×n A = U D V', donde U y V son ortogonales y D es diagonal, con valores singulares no negativos ordenados de forma decreciente.

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')

Reconstrucción mediante SVD

Reconstruya A a partir de la SVD como A = U %*% diag(d) %*% t(V). Las aproximaciones de rango bajo conservan solo los k valores o vectores singulares principales; esta es la base de la compresión de imágenes y la reducción del ruido.

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: pseudoinversa y rango

La SVD proporciona la pseudoinversa A⁺ = V D⁺ U', donde D⁺ sustituye cada valor singular distinto de cero por su recíproco. Resuelve Ax = b en el sentido de mínimos cuadrados incluso cuando A no es cuadrada o no tiene rango completo.

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

Descomposición QR: qr()

La descomposición QR factoriza A = QR, donde Q es ortogonal (Q'Q = I) y R es triangular superior. Se utiliza en regresión lineal, en el cálculo de valores propios (algoritmo QR) y en la ortogonalización de Gram-Schmidt.

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 para regresión

Resolver las ecuaciones normales de la regresión lineal mediante QR es numéricamente superior. Como Q'Q = I, las ecuaciones normales A'Ax = A'b se convierten en R'Q'QRx = R'Q'b y se simplifican a Rx = Q'b, que se resuelve mediante sustitución hacia atrás.

# 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')

Descomposición de Cholesky: chol()

La descomposición de Cholesky factoriza una matriz simétrica definida positiva como A = L L', donde L es triangular inferior. El chol() de R devuelve el factor triangular superior U (por lo que 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)
)

Resolución mediante Cholesky

Para sistemas simétricos definidos positivos (como las matrices de covarianzas), la resolución basada en Cholesky es dos veces más rápida que LU. Use chol2inv() para calcular la inversa, o use backsolve/forwardsolve con el factor de Cholesky.

# 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 en PCA

PCA mediante SVD: centre la matriz de datos X y, después, calcule la SVD de la matriz centrada. Los vectores singulares derechos V son las direcciones de los componentes principales; los valores singulares d se relacionan con la varianza explicada (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))

Rango de una matriz mediante SVD

El rango de una matriz es igual al número de valores singulares no despreciables. La SVD proporciona la forma numéricamente más fiable de determinar el rango: basta con contar los valores d que superen un umbral (normalmente 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 para muestrear una normal multivariante

Para muestrear de una normal multivariante N(μ, Σ), calcule el factor de Cholesky U de Σ y transforme las normales estándar: X = μ + Z %*% U. Así funciona internamente MASS::mvrnorm().

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

Comprobación rápida

Compruebe su comprensión de las descomposiciones SVD, QR y de Cholesky en R.

Resumen: SVD, QR y Cholesky

Ideas clave: SVD (svd()) devuelve d, u y v; se utiliza para PCA, rango, pseudoinversa y aproximaciones de rango bajo. QR (qr()) devuelve una Q ortogonal y una R triangular superior; se utiliza para regresión y estabilidad. Cholesky (chol()) devuelve una U triangular superior tal que A = t(U)%*%U; es la opción más rápida para sistemas SPD. Todas permiten reconstruir A exactamente y tienen distintos usos computacionales.

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

Preguntas frecuentes

¿La lección «Descomposiciones SVD, QR y de Cholesky» es gratis?

Sí — el texto completo de «Descomposiciones SVD, QR y de Cholesky» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de R Academy, actualiza a CoddyKit PRO. El curso de R Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Descomposiciones SVD, QR y de Cholesky»?

Aplique svd(), qr() y chol() para reducir la dimensionalidad y factorizar matrices. Practicas R Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar R Academy?

No se requiere experiencia previa. R Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Descomposiciones SVD, QR y de Cholesky»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de R Academy?

Sí. Cada lección de R Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Multiplicación de matrices y determinantes
  2. Resolución de sistemas lineales con solve()
  3. Valores propios y vectores propios
  4. Descomposiciones SVD, QR y de Cholesky
← Volver a R Academy