Pandas & NumPy Academy · Lección

Resolución de sistemas lineales

Resuelva Ax=b mediante np.linalg.solve y compárelo con el enfoque ingenuo de multiplicar por la inversa para evaluar la estabilidad numérica.

Lección 3 de 413 pasos

Resolución de sistemas lineales es una lección gratuita de Pandas & NumPy Academy en CoddyKit. Esta es la lección 3 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 Pandas & NumPy Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Pandas & NumPy Academy incluye 4 lecciones en total.

¿Qué es un sistema lineal?

Un sistema de ecuaciones lineales se puede escribir en forma matricial como Ax = b, donde A es la matriz de coeficientes, x es el vector de incógnitas y b es el vector del segundo miembro. Por ejemplo, dos ecuaciones con dos incógnitas se pueden expresar como una ecuación matricial 2×2. Resolver el sistema significa encontrar x tal que A multiplicada por x sea igual a b. np.linalg.solve(A, b) de NumPy lo gestiona de forma eficiente y precisa.

import numpy as np

# System: 2x + y = 5
#         x + 3y = 10
A = np.array([[2.0, 1.0],
              [1.0, 3.0]])
b = np.array([5.0, 10.0])

x = np.linalg.solve(A, b)
print('Solution x:', x)
print('Verify A @ x == b:', np.allclose(A @ x, b))

¿Por qué no usar la inversa?

Matemáticamente, la solución de Ax = b es x = A⁻¹b. Sin embargo, calcular np.linalg.inv(A) @ b es más lento y menos preciso que llamar directamente a np.linalg.solve(A, b). solve() utiliza internamente la descomposición LU, que requiere menos operaciones y acumula menos errores de coma flotante. Regla práctica: si está resolviendo x en Ax=b, use siempre solve, nunca inv.

import numpy as np

A = np.random.rand(100, 100)
b = np.random.rand(100)

# Avoid this pattern
x_inv = np.linalg.inv(A) @ b

# Prefer this
x_solve = np.linalg.solve(A, b)

print('Max difference:', np.max(np.abs(x_inv - x_solve)))
# solve is faster AND more accurate

Requisitos de solve()

np.linalg.solve(A, b) requiere que A sea cuadrada y no singular. Si A es singular (su determinante es cero), la función genera np.linalg.LinAlgError: Singular matrix. A es singular cuando sus filas son linealmente dependientes; por ejemplo, cuando una ecuación es simplemente un múltiplo de otra. Compruebe siempre que el sistema esté bien planteado antes de llamar a solve. Si A no es cuadrada, use np.linalg.lstsq().

import numpy as np

# Well-posed system
A = np.array([[1.0, 2.0], [3.0, 4.0]])
b = np.array([5.0, 6.0])
print('Solution:', np.linalg.solve(A, b))

# Singular system (row 2 = 3 * row 1)
A_singular = np.array([[1.0, 2.0], [3.0, 6.0]])
try:
    np.linalg.solve(A_singular, b)
except np.linalg.LinAlgError as e:
    print('Error:', e)

La descomposición LU internamente

np.linalg.solve aplica internamente la descomposición LU: factoriza A en una matriz triangular inferior L y una matriz triangular superior U, de modo que A = LU. Resolver el sistema se convierte entonces en resolver dos sistemas triangulares más sencillos (mediante sustitución hacia delante y hacia atrás), lo que es mucho más eficiente que repetir la eliminación gaussiana desde cero. Este es el mismo algoritmo que utilizan MATLAB, Fortran LAPACK y prácticamente todas las bibliotecas de cálculo científico.

import numpy as np
from scipy import linalg

A = np.array([[2.0, 1.0, -1.0],
              [-3.0, -1.0, 2.0],
              [-2.0, 1.0, 2.0]])
b = np.array([8.0, -11.0, -3.0])

# NumPy solve (uses LAPACK dgesv under the hood)
x = np.linalg.solve(A, b)
print('Solution:', x)
print('Check:', np.allclose(A @ x, b))

Resolver varios segundos miembros

np.linalg.solve(A, B) puede gestionar una matriz B con varias columnas y resolver cada columna simultáneamente. Si B tiene dimensión (n, k), el resultado X tiene dimensión (n, k), donde cada columna de X es la solución correspondiente a la columna de B. Esto resulta útil en simulaciones físicas y aprendizaje automático, cuando necesita resolver la misma matriz de coeficientes con muchos segundos miembros diferentes.

import numpy as np

A = np.array([[3.0, 1.0],
              [1.0, 2.0]])

# Three right-hand side vectors at once
B = np.array([[9.0, 3.0, 6.0],
              [8.0, 4.0, 2.0]])

X = np.linalg.solve(A, B)
print('Solutions X shape:', X.shape)  # (2, 3)
print('Verify A @ X == B:', np.allclose(A @ X, B))

Mínimos cuadrados con np.linalg.lstsq()

Cuando el sistema está sobredeterminado (hay más ecuaciones que incógnitas), no existe una solución exacta. np.linalg.lstsq(A, b) encuentra el valor de x que minimiza la suma de los cuadrados de los residuos ||Ax - b||²; esto es exactamente lo que calcula la regresión lineal. Devuelve la solución x, los residuos, el rango y los valores singulares. El argumento rcond=None suprime una advertencia de obsolescencia y establece el umbral para tratar los valores singulares como cero.

import numpy as np

# Over-determined: 4 equations, 2 unknowns
A = np.array([[1.0, 1.0],
              [1.0, 2.0],
              [1.0, 3.0],
              [1.0, 4.0]])
b = np.array([2.0, 2.5, 3.5, 4.5])

x, residuals, rank, sv = np.linalg.lstsq(A, b, rcond=None)
print('Least-squares solution:', x)
print('Residuals:', residuals)
print('Rank:', rank)

Aplicar solve() en la regresión lineal

Las ecuaciones normales de los mínimos cuadrados ordinarios son A.T @ A @ x = A.T @ b, que constituyen un sistema cuadrado resoluble con np.linalg.solve. Esto produce el mismo resultado que lstsq cuando A.T @ A está bien condicionada. En la práctica, se prefiere lstsq porque utiliza SVD y es estable incluso cuando las columnas son casi colineales, pero las ecuaciones normales ayudan a comprender las matemáticas subyacentes de la regresión.

import numpy as np

np.random.seed(0)
X = np.column_stack([np.ones(50), np.random.rand(50) * 10])
y = 3.0 + 2.0 * X[:, 1] + np.random.randn(50)

# Solve normal equations
coeffs = np.linalg.solve(X.T @ X, X.T @ y)
print('Intercept:', round(coeffs[0], 3))
print('Slope:', round(coeffs[1], 3))

Comprobar el número de condición

Antes de resolver el sistema, es recomendable comprobar el número de condición con np.linalg.cond(A). Un número de condición cercano a 1 significa que el sistema está bien condicionado y que la solución es fiable. Un número de condición muy grande (por ejemplo, 1e12) significa que la matriz es casi singular: pequeños cambios en b producen grandes cambios en x y la solución puede no ser fiable numéricamente. En ese caso, considere la regularización (regresión ridge) o el uso de un solucionador más robusto.

import numpy as np

# Well-conditioned
A1 = np.array([[2.0, 1.0], [1.0, 3.0]])
print('Condition number (well):', np.linalg.cond(A1))

# Ill-conditioned (nearly linearly dependent rows)
A2 = np.array([[1.0, 1.0], [1.0, 1.0001]])
print('Condition number (ill):', np.linalg.cond(A2))

Sistemas dispersos: cuándo no usar linalg

En sistemas muy grandes donde A tiene principalmente entradas cero (una matriz dispersa), almacenar la matriz completa desperdicia memoria y usar np.linalg.solve denso es lento. SciPy proporciona scipy.sparse y scipy.sparse.linalg.spsolve, que aprovechan la dispersión para trabajar con sistemas enormes, como los de modelos de elementos finitos o problemas de redes. Comprender cuándo su matriz es dispersa es una consideración importante de rendimiento en el cálculo científico.

import numpy as np

# Dense solve is fine for small-to-medium systems
A = np.random.rand(200, 200)
b = np.random.rand(200)
x = np.linalg.solve(A, b)
print('Dense solve OK, solution shape:', x.shape)

# For large sparse systems, use scipy.sparse.linalg.spsolve instead
# from scipy.sparse.linalg import spsolve
# x = spsolve(A_sparse, b)

Interpretar el vector solución

Una vez que tenga el vector solución x de np.linalg.solve(A, b), verifíquelo siempre calculando A @ x y comparándolo con b mediante np.allclose(A @ x, b). En la aritmética de punto flotante, rara vez se obtiene una igualdad exacta; allclose comprueba que la diferencia esté dentro de una pequeña tolerancia. El residuo ||Ax - b|| debería estar cerca del épsilon de máquina multiplicado por la escala del problema en un sistema bien condicionado.

import numpy as np

A = np.array([[4.0, 3.0, 2.0],
              [1.0, 5.0, 3.0],
              [2.0, 1.0, 6.0]])
b = np.array([10.0, 20.0, 15.0])

x = np.linalg.solve(A, b)
print('Solution:', np.round(x, 4))

# Residual check
residual = np.linalg.norm(A @ x - b)
print('Residual ||Ax - b||:', residual)
print('Valid:', np.allclose(A @ x, b))

Resolución en canalizaciones de aprendizaje automático

Los solucionadores lineales aparecen en todo el aprendizaje automático: la regresión lineal resuelve las ecuaciones normales, los procesos gaussianos resuelven sistemas de matrices de kernel y los filtros de Kalman resuelven ecuaciones de actualización de estados. Al comprender np.linalg.solve y lstsq, podrá implementar estos algoritmos desde cero y depurarlos cuando los resultados no sean los esperados. El módulo linalg de NumPy le proporciona las mismas herramientas numéricas que se utilizan en bibliotecas científicas de producción.

import numpy as np

# Ridge regression: (X.T @ X + lambda * I) @ w = X.T @ y
np.random.seed(42)
X = np.random.rand(100, 5)
y = np.random.rand(100)
lambda_reg = 0.1
n_features = X.shape[1]

A = X.T @ X + lambda_reg * np.eye(n_features)
bvec = X.T @ y
w = np.linalg.solve(A, bvec)
print('Ridge regression weights:', np.round(w, 4))

Comprobación rápida

Compruebe su comprensión de los conceptos de análisis de datos de esta lección.

Resumen de la lección

En esta lección ha aprendido que np.linalg.solve(A, b) resuelve eficazmente sistemas lineales cuadrados mediante la descomposición LU, np.linalg.lstsq() encuentra la solución de mínimos cuadrados para sistemas sobredeterminados y el número de condición mide la estabilidad numérica; los valores grandes advierten de matrices casi singulares. A continuación, exploraremos los valores propios y la SVD, fundamentales para PCA y muchos algoritmos de aprendizaje automático.

Gratis para empezar

Aprende Python con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
30
Lecciones
120

Preguntas frecuentes

¿La lección «Resolución de sistemas lineales» es gratis?

Sí — el texto completo de «Resolución de sistemas lineales» 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 Pandas & NumPy Academy, actualiza a CoddyKit PRO. El curso de Pandas & NumPy Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Resolución de sistemas lineales»?

Resuelva Ax=b mediante np.linalg.solve y compárelo con el enfoque ingenuo de multiplicar por la inversa para evaluar la estabilidad numérica. Practicas Pandas & NumPy 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 Pandas & NumPy Academy?

No se requiere experiencia previa. Pandas & NumPy 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 3 de 4.

¿Cuánto tiempo toma la lección «Resolución de sistemas lineales»?

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 Pandas & NumPy Academy?

Sí. Cada lección de Pandas & NumPy 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 con np.matmul y @
  2. Determinantes, inversas y transpuestas
  3. Resolución de sistemas lineales
  4. Introducción a valores propios y SVD
← Volver a Pandas & NumPy Academy