Math for AI course · Lesson 24 of 180
Row-Echelon Form Reveals Redundant AI Features
Use pivots, free variables, and row-echelon form to diagnose redundant features and non-unique model parameters in a small design matrix.
When a model has three feature columns, it is tempting to assume it has three independent directions to learn from. But a feature can be present in the data while adding no new information. If one column is a combination of the others, the model may fit the same predictions with many different parameter vectors.
Row-echelon form makes that hidden structure visible. By the end of this lesson, you will be able to locate pivots, identify free variables, describe a general solution, and use a small NumPy implementation to diagnose redundant features without confusing a numerical warning with a mathematical conclusion.
Learning outcome: Find pivots, free variables, and a general solution.
Lesson 23: Gaussian elimination preserves the solution set introduced the legal row operations that keep a system’s solutions unchanged. Lesson 18: Matrices organize linear rules gave us the coefficient matrix. The official Mathematics for Machine Learning companion places this lesson in Section 2.3 of the current book PDF. The numbers, feature scenario, code, visual, and assessments here are original.
A staircase records what the equations can determine
Start with a matrix . A matrix is in row-echelon form when three structural rules hold:
- Every nonzero row appears above every all-zero row.
- The first nonzero entry of each nonzero row, called its pivot, appears farther right than the pivot in the row above it.
- Every entry below a pivot is zero.
The pivots form a left-to-right staircase. A pivot column is a direction that the rows constrain. A column without a pivot is a free direction: its value can vary while the equations determine the other variables around it.
Row-echelon form is not the same as reduced row-echelon form. Reduced form also requires each pivot to equal and to be the only nonzero entry in its column. Either form can reveal rank and free variables; reduced form is often more convenient for reading a parameterized answer.
The visual below keeps the intermediate states visible. The final matrix has two pivots, in columns and ; column has no pivot.
Static row-reduction record
The pivots form a staircase
Each state keeps the complete matrix visible. The final nonzero row has its pivot farther right than the row above it, and the zero row has moved to the bottom.
Original feature matrix Row f₁ f₂ f₃ R1 1 2 3 R2 2 4 6 R3 1 1 2 Clear the first column below the pivot Row f₁ f₂ f₃ R1 1 2 3 R2 0 0 0 R3 0 -1 -1 Move the nonzero row upward Row f₁ f₂ f₃ R1 1 2 3 R2 0 -1 -1 R3 0 0 0 Normalize the second pivot Row f₁ f₂ f₃ R1 1 2 3 R2 0 1 1 R3 0 0 0
The highlighted entries are pivots in the final structure. Column f₃ has no pivot, so it is the free direction that exposes the redundant feature.
Row operations expose two independent feature directions and one redundant column. The underlined entries mark the final pivot positions.
Worked example: a redundant feature column
Imagine a tiny design matrix whose columns summarize three signals extracted for three examples:
- : retrieval-match strength;
- : verification strength; and
- : a combined signal that was accidentally logged as a separate feature.
The matrix is
Before doing any reduction, notice that the third column is the sum of the first two: . That is a useful intuition, but row reduction gives us a procedure that still works when the relationship is not obvious by inspection.
First use the top-left entry as a pivot. Clear the entries beneath it:
which gives
The second row is temporarily zero, but the system has not lost information: the nonzero row below still needs to be moved upward. Swap the rows and then multiply the new second row by :
The pivots are in columns 1 and 2. Column 3 has no pivot, so it is the free column. The matrix has rank 2 rather than 3: the data contain three named features but only two independent directions.
Free variables describe a family, not a failure
To see what the missing pivot means, attach a right-hand side that is consistent with the same row relationships:
The same operations produce
The equations are now
Let the free variable be . Then
Every value of produces a parameter vector that gives the same right-hand side. For example, gives , while gives . Both satisfy the three original equations. The model’s predictions are fixed, but the individual weights are not identifiable from these observations alone.
A row of zeros is different from a contradiction
The last row in the example becomes
That row is redundant, so it contributes no new constraint. Do not confuse it with
which is impossible. In an augmented matrix, a row of zeros on the left with a nonzero right-hand side signals inconsistency and therefore no solution. The same left-hand matrix can support infinitely many solutions, one solution, or no solution depending on the transformed right-hand side.
This distinction matters in data pipelines. Repeated or dependent rows may reduce the amount of independent evidence without making the equations contradictory. A contradictory row instead says that the observations cannot be explained by the proposed linear model exactly.
Implement the pivot search in NumPy
The following compact implementation uses partial pivoting. At each column it chooses the largest-magnitude candidate below the current pivot row, swaps it into place, normalizes the pivot, and clears entries below it. The tolerance prevents a value that is only round-off noise from being treated as a real pivot.
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))
The meaningful output is approximately
[[1. 2. 3.]
[0. 1. 1.]
[0. 0. 0.]]
[0, 1]
2
The exact decimals depend on the dtype and tolerance, but the structural
conclusion is stable here: two pivot columns and one free column. NumPy’s
matrix_rank also uses a tolerance around singular values rather than asking
whether a floating-point value is literally equal to zero. That is why a rank
decision should be reported with its scale and tolerance, not as an eternal
truth about noisy measurements.
What this means for an AI model
Suppose a linear model computes
When , the prediction becomes
Only the sums and are observable in this design. Different parameter vectors can therefore produce identical predictions on every row of the matrix. A training run may still return one set of weights because an optimizer, initialization, regularizer, or numerical path selects one point from the family. That selected point is not proof that the data identified each feature’s independent contribution.
Use row-echelon form as a diagnostic, not as a replacement for validation. A rank calculation on a small sample can change when preprocessing, scaling, missing-value handling, or new data changes. For a larger or noisy matrix, inspect the singular-value scale and condition number as well. A full-rank matrix can still be nearly dependent, making its solution sensitive to small measurement changes.
condition = np.linalg.cond(features)
residual = np.linalg.norm(features[:, 2] - features[:, 0] - features[:, 1])
print(condition, residual)
Here the residual is exactly zero in the stored values and the condition number is extremely large in floating-point arithmetic (about in this run). An exactly rank-deficient matrix has an infinite mathematical condition number, but a floating-point SVD may report a very large finite value. That contrast is itself a warning. In production data, use a scale-aware tolerance: a tiny residual can mean a genuine near-dependency or just a measurement below the precision that matters for the application.
Check your understanding
Question
Show the step-by-step solution
Row-echelon form requires every nonzero row to be above all-zero rows, each successive pivot to move right, and entries below every pivot to be zero. A matrix can satisfy these rules even when pivot entries are not and entries above pivots are not zero. Those additional conditions belong to reduced row-echelon form.
Question
Show the step-by-step solution
Use the first row as a pivot and replace the second row with :
There is one pivot, so the rank is . The second row supplied no independent constraint; it repeated the first row at twice its scale.
Question
Show the step-by-step solution
The third variable is free because the final echelon matrix has pivots in columns 1 and 2 but not column 3. Setting lets the first two equations determine and in terms of .
Question
Show the step-by-step solution
That row represents or another impossible statement. No assignment of the unknowns can change the left side from zero, so the system is inconsistent. A row is different: it is redundant and leaves the existing solution set unchanged.
Question
Show the step-by-step solution
At , the vector is . The three rows produce , , and . These are exactly the chosen right-hand-side values, so the parameterized solution really describes valid solutions rather than only the reduced equations.
Question
Show the step-by-step solution
The data allow a family of equally predictive parameter vectors. Initialization, the optimizer’s path, regularization, or an implicit numerical preference can select one member of that family. The returned vector is a choice made by the full training procedure; it does not show that the observations uniquely identified each feature weight.
Question
Show the step-by-step solution
Inspect the singular-value scale, condition number, data units, measurement uncertainty, and the tolerance used for the rank decision. A tiny singular value can make solutions very sensitive to small changes even though the mathematical rank is full. Rescaling, collecting more independent observations, removing redundant features, or using a regularized formulation may be more appropriate than trusting many unstable digits.
The next lesson uses row structure to explain why numerical software usually solves a system directly instead of forming an explicit inverse. A pivot is not just a mark on paper: it tells you which directions the data constrain and which ones remain ambiguous.