Curso de Matemáticas para IA · Lección 24 de 180

La forma escalonada por filas revela características de IA redundantes

Usa pivotes, variables libres y la forma escalonada por filas para diagnosticar características redundantes y parámetros no únicos en una matriz de diseño pequeña.

Comparte este artículo

Cuando un modelo tiene tres columnas de características, es tentador suponer que dispone de tres direcciones independientes de las que aprender. Sin embargo, una característica puede estar presente en los datos sin aportar información nueva. Si una columna es una combinación de las demás, el modelo puede ajustar las mismas predicciones con muchos vectores de parámetros diferentes.

La forma escalonada por filas hace visible esa estructura oculta. Al terminar esta lección podrás localizar pivotes, identificar variables libres, describir una solución general y usar una pequeña implementación en NumPy para diagnosticar características redundantes sin confundir una advertencia numérica con una conclusión matemática.

Resultado de aprendizaje: Encontrar pivotes, variables libres y una solución general.

La lección 23: La eliminación de Gauss conserva el conjunto de soluciones introdujo las operaciones legales por filas que mantienen sin cambios las soluciones de un sistema. La lección 18: Las matrices organizan reglas lineales presentó la matriz de coeficientes. El sitio oficial complementario de Mathematics for Machine Learning sitúa esta lección en la sección 2.3 del PDF actual del libro. Los números, el escenario de características, el código, la visualización y las evaluaciones de esta lección son originales.

Una escalera registra lo que las ecuaciones pueden determinar

Comienza con una matriz AinmathbbRm×nAinmathbb{R}^{m\times n}. Una matriz está en forma escalonada por filas cuando cumple tres reglas estructurales:

  1. Cada fila no nula aparece por encima de todas las filas completamente nulas.
  2. La primera entrada no nula de cada fila no nula, llamada pivote, aparece más a la derecha que el pivote de la fila anterior.
  3. Todas las entradas situadas debajo de un pivote son cero.

Los pivotes forman una escalera de izquierda a derecha. Una columna pivote es una dirección que las filas restringen. Una columna sin pivote es una dirección libre: su valor puede variar mientras las ecuaciones determinan las demás variables a su alrededor.

La forma escalonada por filas no es lo mismo que la forma escalonada reducida por filas. La forma reducida también exige que cada pivote sea igual a 11 y sea la única entrada no nula de su columna. Cualquiera de las dos formas puede revelar el rango y las variables libres; la forma reducida suele ser más cómoda para leer una respuesta parametrizada.

La visualización siguiente mantiene visibles los estados intermedios. La matriz final tiene dos pivotes, en las columnas f1f_1 y f2f_2; la columna f3f_3 no tiene pivote.

Registro estático de reducción por filas

Los pivotes forman una escalera

Cada estado mantiene visible la matriz completa. El pivote de la última fila no nula está más a la derecha que el de la fila superior, y la fila de ceros ha bajado hasta el final.

  1. Paso 0Matriz de características originalInicio
    Matriz de características original
    Filaf₁f₂f₃
    R1123
    R2246
    R3112
  2. Paso 1Anular la primera columna debajo del pivoteR₂ ← R₂ − 2R₁; R₃ ← R₃ − R₁
    Anular la primera columna debajo del pivote
    Filaf₁f₂f₃
    R1123
    R2000
    R30-1-1
  3. Paso 2Subir la fila no nulaR₂ ↔ R₃
    Subir la fila no nula
    Filaf₁f₂f₃
    R1123
    R20-1-1
    R3000
  4. Paso 3Normalizar el segundo pivoteR₂ ← −R₂
    Normalizar el segundo pivote
    Filaf₁f₂f₃
    R1123
    R2011
    R3000

Las entradas resaltadas son los pivotes de la estructura final. La columna f₃ no tiene pivote, así que es la dirección libre que revela la característica redundante.

Las operaciones por filas exponen dos direcciones de características independientes y una columna redundante. Las entradas subrayadas marcan las posiciones de los pivotes finales.

Ejemplo resuelto: una columna de características redundante

Imagina una matriz de diseño pequeña cuyas columnas resumen tres señales extraídas para tres ejemplos:

  • f1f_1: intensidad de coincidencia en la recuperación;
  • f2f_2: intensidad de verificación; y
  • f3f_3: una señal combinada que se registró por accidente como una característica separada.

La matriz es

A=[123246112].A= \begin{bmatrix} 1&2&3\\ 2&4&6\\ 1&1&2 \end{bmatrix}.

Antes de reducirla, observa que la tercera columna es la suma de las dos primeras: f3=f1+f2f_3=f_1+f_2. Es una intuición útil, pero la reducción por filas nos proporciona un procedimiento que también funciona cuando la relación no resulta evidente a simple vista.

Primero usa la entrada superior izquierda como pivote. Elimina las entradas que están debajo:

R2←R2−2R1,R3←R3−R1,R_2\leftarrow R_2-2R_1, \qquad R_3\leftarrow R_3-R_1,

lo que produce

[1230000−1−1].\begin{bmatrix} 1&2&3\\ 0&0&0\\ 0&-1&-1 \end{bmatrix}.

La segunda fila se vuelve cero temporalmente, pero el sistema no ha perdido información: la fila no nula que está debajo aún debe subir. Intercambia las filas y después multiplica la nueva segunda fila por −1-1:

[1230−1−1000]⟶[123011000].\begin{bmatrix} 1&2&3\\ 0&-1&-1\\ 0&0&0 \end{bmatrix} \quad\longrightarrow\quad \boxed{ \begin{bmatrix} 1&2&3\\ 0&1&1\\ 0&0&0 \end{bmatrix}}.

Los pivotes están en las columnas 1 y 2. La columna 3 no tiene pivote, así que es la columna libre. La matriz tiene rango 2 en lugar de 3: los datos contienen tres características con nombre, pero solo dos direcciones independientes.

Las variables libres describen una familia, no un fracaso

Para ver qué significa la ausencia de un pivote, añade un lado derecho compatible con las mismas relaciones entre filas:

[123∣4246∣8112∣3].\begin{bmatrix} 1&2&3&\mid&4\\ 2&4&6&\mid&8\\ 1&1&2&\mid&3 \end{bmatrix}.

Las mismas operaciones producen

[101∣2011∣1000∣0].\begin{bmatrix} 1&0&1&\mid&2\\ 0&1&1&\mid&1\\ 0&0&0&\mid&0 \end{bmatrix}.

Ahora las ecuaciones son

θ1+θ3=2,θ2+θ3=1.\theta_1+\theta_3=2, \qquad \theta_2+\theta_3=1.

Sea θ3=t\theta_3=t la variable libre. Entonces

θ1=2−t,θ2=1−t,θ3=t.\theta_1=2-t, \qquad \theta_2=1-t, \qquad \theta_3=t.

Cada valor de tt produce un vector de parámetros que da el mismo lado derecho. Por ejemplo, t=0t=0 da (2,1,0)(2,1,0), mientras que t=1t=1 da (1,0,1)(1,0,1). Ambos satisfacen las tres ecuaciones originales. Las predicciones del modelo están fijadas, pero los pesos individuales no son identificables a partir de estas observaciones por sí solas.

Una fila de ceros es diferente de una contradicción

La última fila del ejemplo se convierte en

0θ1+0θ2+0θ3=0.0\theta_1+0\theta_2+0\theta_3=0.

Esa fila es redundante, por lo que no aporta una restricción nueva. No la confundas con

0θ1+0θ2+0θ3=5,0\theta_1+0\theta_2+0\theta_3=5,

que es imposible. En una matriz aumentada, una fila con ceros a la izquierda y un lado derecho distinto de cero indica incompatibilidad y, por tanto, ausencia de solución. La misma matriz del lado izquierdo puede admitir infinitas soluciones, una solución o ninguna, según el lado derecho transformado.

Esta distinción importa en las canalizaciones de datos. Las filas repetidas o dependientes pueden reducir la cantidad de evidencia independiente sin hacer contradictorias las ecuaciones. Una fila contradictoria, en cambio, indica que las observaciones no pueden explicarse exactamente mediante el modelo lineal propuesto.

Implementa la búsqueda de pivotes en NumPy

La implementación compacta siguiente utiliza pivoteo parcial. En cada columna elige el candidato de mayor magnitud por debajo de la fila pivote actual, lo intercambia para colocarlo en su sitio, normaliza el pivote y elimina las entradas que están debajo. La tolerancia evita tratar como pivote real un valor que solo sea ruido de redondeo.

import numpy as np

def row_echelon(matrix, tolerance=1e-12):
    a = np.array(matrix, dtype=float, copy=True)
    rows, columns = a.shape
    pivot_row = 0
    pivot_columns = []

    for column in range(columns):
        if pivot_row == rows:
            break

        candidate = pivot_row + np.argmax(np.abs(a[pivot_row:, column]))
        if abs(a[candidate, column]) <= tolerance:
            continue

        a[[pivot_row, candidate]] = a[[candidate, pivot_row]]
        a[pivot_row] /= a[pivot_row, column]

        for row in range(pivot_row + 1, rows):
            a[row] -= a[row, column] * a[pivot_row]

        a[np.abs(a) <= tolerance] = 0
        pivot_columns.append(column)
        pivot_row += 1

    return a, pivot_columns


features = np.array([
    [1, 2, 3],
    [2, 4, 6],
    [1, 1, 2],
])

echelon, pivots = row_echelon(features)
print(echelon)
print(pivots)
print(np.linalg.matrix_rank(features))

La salida significativa es aproximadamente

[[1. 2. 3.]
 [0. 1. 1.]
 [0. 0. 0.]]
[0, 1]
2

Los decimales exactos dependen del tipo de datos y de la tolerancia, pero la conclusión estructural es estable aquí: dos columnas pivote y una columna libre. matrix_rank de NumPy también usa una tolerancia alrededor de los valores singulares, en lugar de preguntar si un valor de coma flotante es literalmente igual a cero. Por eso, una decisión sobre el rango debe informarse junto con su escala y tolerancia, no como una verdad eterna sobre mediciones ruidosas.

Qué significa esto para un modelo de IA

Supón que un modelo lineal calcula

y^=θ1f1+θ2f2+θ3f3.\hat{y}=\theta_1f_1+\theta_2f_2+\theta_3f_3.

Cuando f3=f1+f2f_3=f_1+f_2, la predicción se convierte en

y^=(θ1+θ3)f1+(θ2+θ3)f2.\hat{y}=(\theta_1+\theta_3)f_1+(\theta_2+\theta_3)f_2.

En este diseño solo son observables las sumas θ1+θ3\theta_1+\theta_3 y θ2+θ3\theta_2+\theta_3. Por tanto, distintos vectores de parámetros pueden producir predicciones idénticas en todas las filas de la matriz. Un entrenamiento aún puede devolver un conjunto de pesos porque el optimizador, la inicialización, el regularizador o la trayectoria numérica selecciona un punto de la familia. Ese punto seleccionado no demuestra que los datos hayan identificado la contribución independiente de cada característica.

Usa la forma escalonada por filas como diagnóstico, no como sustituto de la validación. Un cálculo del rango sobre una muestra pequeña puede cambiar cuando cambian el preprocesamiento, el escalado, el tratamiento de valores ausentes o los datos nuevos. Para una matriz más grande o ruidosa, inspecciona también la escala de los valores singulares y el número de condición. Una matriz de rango completo aún puede estar casi en dependencia, lo que hace que su solución sea sensible a pequeños cambios en las mediciones.

condition = np.linalg.cond(features)
residual = np.linalg.norm(features[:, 2] - features[:, 0] - features[:, 1])
print(condition, residual)

Aquí el residuo es exactamente cero en los valores almacenados y el número de condición es extremadamente grande en aritmética de coma flotante (aproximadamente 3.8×10163.8\times10^{16} en esta ejecución). Una matriz exactamente deficiente en rango tiene un número de condición matemático infinito, pero una SVD de coma flotante puede informar de un valor finito muy grande. Ese contraste es una advertencia en sí mismo. En datos de producción, usa una tolerancia consciente de la escala: un residuo diminuto puede indicar una dependencia casi exacta genuina o simplemente una medición por debajo de la precisión relevante para la aplicación.

Comprueba lo que has entendido

Pregunta

Mostrar la solución paso a paso

La forma escalonada por filas exige que cada fila no nula esté por encima de todas las filas nulas, que cada pivote sucesivo se desplace a la derecha y que las entradas situadas debajo de cada pivote sean cero. Una matriz puede cumplir estas reglas aunque las entradas pivote no sean 11 y las entradas situadas por encima de los pivotes no sean cero. Esas condiciones adicionales pertenecen a la forma escalonada reducida por filas.

Pregunta

Mostrar la solución paso a paso

Usa la primera fila como pivote y sustituye la segunda fila por R2−2R1R_2-2R_1:

[1224]⟶[1200].\begin{bmatrix}1&2\\2&4\end{bmatrix} \longrightarrow \begin{bmatrix}1&2\\0&0\end{bmatrix}.

Hay un pivote, así que el rango es 11. La segunda fila no aportaba una restricción independiente; repetía la primera fila con el doble de su escala.

Pregunta

Mostrar la solución paso a paso

La tercera variable es libre porque la matriz escalonada final tiene pivotes en las columnas 1 y 2, pero no en la columna 3. Fijar θ3=t\theta_3=t permite que las dos primeras ecuaciones determinen θ1\theta_1 y θ2\theta_2 en función de tt.

Pregunta

Mostrar la solución paso a paso

Esa fila representa 0=50=5 u otra afirmación imposible. Ninguna asignación de las incógnitas puede cambiar el lado izquierdo de cero, por lo que el sistema es incompatible. Una fila 0=00=0 es diferente: es redundante y deja sin cambios el conjunto de soluciones existente.

Pregunta

Mostrar la solución paso a paso

Cuando t=1t=1, el vector es (1,0,1)(1,0,1). Las tres filas producen 1+2(0)+3(1)=41+2(0)+3(1)=4, 2(1)+4(0)+6(1)=82(1)+4(0)+6(1)=8 y 1+0+2(1)=31+0+2(1)=3. Son exactamente los valores elegidos para el lado derecho, así que la solución parametrizada describe soluciones válidas y no solo las ecuaciones reducidas.

Pregunta

Mostrar la solución paso a paso

Los datos permiten una familia de vectores de parámetros con predicciones igualmente buenas. La inicialización, la trayectoria del optimizador, la regularización o una preferencia numérica implícita pueden seleccionar un miembro de esa familia. El vector devuelto es una elección del procedimiento de entrenamiento completo; no demuestra que las observaciones hayan identificado de forma única el peso de cada característica.

Pregunta

Mostrar la solución paso a paso

Inspecciona la escala de los valores singulares, el número de condición, las unidades de los datos, la incertidumbre de las mediciones y la tolerancia utilizada para decidir el rango. Un valor singular diminuto puede hacer que las soluciones sean muy sensibles a pequeños cambios aunque el rango matemático sea completo. Puede ser más apropiado reescalar, recopilar más observaciones independientes, eliminar características redundantes o usar una formulación regularizada que confiar en muchos dígitos inestables.

La próxima lección usará la estructura de las filas para explicar por qué el software numérico suele resolver un sistema directamente en lugar de formar una inversa explícita. Un pivote no es solo una marca sobre el papel: indica qué direcciones están restringidas por los datos y cuáles siguen siendo ambiguas.

Fuentes

  1. Mathematics for Machine Learning companion website
  2. Mathematics for Machine Learning book PDF
  3. NumPy documentation: numpy.linalg.matrix_rank
  4. NumPy documentation: numpy.linalg.solve
  5. NumPy documentation: numpy.linalg.cond
  6. NumPy documentation: numpy.linalg.norm