Feature Scaling with MinMaxScaler
PolynomialFeatures(degree=2) expands 13 scaled features into 105 columns: a constant, the originals, the squares and the pairwise products.
Why the Order of Steps Matters
This article follows one realistic case from start to finish: a Ridge regression model built on 13 input features, with a polynomial expansion applied to those features. The aim is to watch the shape of the data change at each step, so that when a score or a shape looks wrong you know which line of code to inspect. The main lesson is that the cause of a failure is usually one step earlier than the line that complains.
The pipeline has three stages that depend on each other. First, every feature is rescaled to lie between 0 and 1 with MinMaxScaler. Second, PolynomialFeatures with degree=2 expands the scaled features into squares and pairwise products. Third, a Ridge model is fitted on the expanded matrix. The source states that scaling must come before the polynomial expansion, because the expansion multiplies features together. The scale of each input therefore directly affects the scale of every product built from it.
Tracing the Data Through the Pipeline
The first step loads the data, splits it into training and test sets, and rescales every feature with MinMaxScaler. The scaler is fitted on the training data, and the test data is transformed with that same scaler. After this step the training matrix still has 13 columns, but every value now lies between 0 and 1.
The second step fits a PolynomialFeatures object with degree=2 on the scaled training data. It then transforms both the training and the test sets with that same fitted object. Running the code prints two shape lines. The training matrix started with 13 columns, and the question to hold onto is what the second number in the printout means once the expansion has happened.
The third step fits a Ridge model on the expanded features. The source fits Ridge twice in the same code: once on the scaled original features and once on the polynomial features. The variable name ridge is reused, so the first model is overwritten by the second. Each model is scored on test data that was transformed the same way as its own training data. The scaled originals go with the scaled originals, and the polynomial matrix goes with the polynomial matrix.
Reading the 105 Columns
A count of 105 tells you very little on its own. The source describes the 105 columns as a constant, the 13 original features, the squares of each original feature, and all possible products of two different original features. The phrase degree=2 means that every output column is a product of at most two original features. It does not mean that the model is restricted to quadratic curves in a single variable, and it does not mean that only two features are used. Every original feature is still present, and each new column is built from them.
The breakdown can be checked by counting. There is one constant column, and the 13 originals are kept as they are. Each original is also squared, which gives 13 more columns. Every pair of two different features contributes one product, and the number of such pairs from 13 features is $\binom{13}{2} = 78$. Adding these together gives $1 + 13 + 13 + 78 = 105$, which matches the shape printout.
Matching Column Names to Their Originals
The shape alone does not say which column is which. The get_feature_names method solves this. It returns a list of strings in the same order as the columns of the transformed matrix, so the position in the list and the position in the matrix are the same thing. The list begins with the constant '1', followed by the 13 original features named x0 through x12, and then the squares and products.
The notation in the names is read as follows. The caret marks a square, so x02 means the first feature multiplied by itself. A space between two names means multiplication, so x0 x1 means the first feature times the second. The name therefore records exactly which original features were multiplied to create the column. The source lists the ordering rule: column 0 is the constant, columns 1 through 13 are the originals in their input order, and column 14 is the square of the first feature. The columns after it pair the first feature with each of the other features in turn. Once you know this rule, you can locate any column without scanning the whole list.
Checking the expansion on one row
A single row has two features, 2 and 3. Expand it with degree=2 and check that each generated name matches its value.
- 1Start with the constant
The first column is the constant 1, named '1'.
- 2Keep the originals
The two originals are kept in input order: x0 has value 2 and x1 has value 3.
- 3Square each original
x02 is 2 times 2, which is 4. x12 is 3 times 3, which is 9.
- 4Build the cross product
x0 x1 is the first original times the second, which is 2 times 3, giving 6.
- 5Compare with the names
Reading each name next to its value confirms that the expansion does what the names say.
The expanded row is 1, 2, 3, 4, 6, 9 for the names 1, x0, x1, x02, x0 x1, x12. The output pairs each name with its value, so the name is the fastest check on which originals were combined.
Predicting the Column Count
What do you think happens?
The training data has 13 scaled features. After PolynomialFeatures(degree=2), how many columns does the expanded matrix have?
Reveal answer
105 columns
The expansion keeps a constant column (1), the 13 originals, 13 squares, and 78 pairwise products. That is 1 + 13 + 13 + 78 = 105. The second shape number in the printout should therefore read 105.
Where the Ridge Score Goes Wrong
On the source's single split, Ridge regression improved from a score of 0.621 using only the scaled original features to 0.753 using the polynomial features. The improvement comes from the interaction and squared terms, but only when the test data is transformed with the same fitted objects as the training data. Ridge is a linear regression model with an L2 penalty. It minimizes the sum of squared errors plus a penalty on the size of the coefficients, which helps it cope with the strong relationships between columns that a polynomial expansion creates.
Common mistake Fitting a new MinMaxScaler on the test data
What it looks likeA test-time call such as scaler.fit_transform(X_test) computes the minimum and maximum from the test set.
Why it failsThe test values are then scaled on a different range from the training values, so the same raw number maps to different scaled values for training and testing.
Do this insteadCall fit only on the training data, then call transform on the test data with that same fitted scaler.
Common mistake Expanding the test data with a freshly fitted PolynomialFeatures object
What it looks likepoly.fit_transform(X_test_scaled) is called on the test set when the model was trained on poly.fit_transform(X_train_scaled).
Why it failsThe expansion produces columns in the order and count it learned from the data it was fitted on, so mixing fitted objects can give a different column layout from the one the Ridge model was trained on.
Do this insteadFit PolynomialFeatures once on the scaled training data, then call transform on the scaled test data.
Common mistake Assuming a shape error means the bug is in the model
What it looks likeThe Ridge fit raises a shape error, and the developer changes the regularization strength.
Why it failsA shape problem is usually caused by a transformation step that ran with the wrong object or on the wrong input, one step earlier than the line that complains.
Do this insteadCheck the printed shapes after each transform and confirm that the expanded test matrix has the same number of columns as the expanded training matrix.
Common mistake Scaling after the polynomial expansion
Why it failsThe source states that scaling must come before the expansion, because the expansion multiplies features together and their scale affects every product built from them.
Do this insteadApply MinMaxScaler first, then PolynomialFeatures, then Ridge.
Practice: Find the Failing Step
A colleague builds the pipeline as follows. They fit MinMaxScaler and PolynomialFeatures on the training data, train Ridge on the expanded training matrix, and then score on the test set. For the test set they call a new MinMaxScaler fitted on the test data, followed by a new PolynomialFeatures fitted on the test data, and they report a test score that is much lower than expected. Decide which step is the failure, and state which fitted object should have been reused.
Hints
- Ask which data each scaler or expansion was fitted on, and whether the test data was transformed with those same objects.
- Compare the number of columns the test matrix produces with the number the Ridge model was trained on.
- The fix is to reuse the objects fitted on the training data, not to refit them on the test data.
Key Takeaways
- Scaling with MinMaxScaler must come before PolynomialFeatures, and both must be fitted on the training data only.
PolynomialFeatures(degree=2)on 13 features gives 105 columns: 1 constant, 13 originals, 13 squares, and 78 pairwise products.- The
get_feature_nameslist is in the same order as the matrix columns, so names such as x02 and x0 x1 identify exactly which originals were combined. - On the source's split, Ridge improved from 0.621 without interaction terms to 0.753 with them, but only when the test data is transformed with the fitted training objects.
- When a shape error or low score appears, inspect the transform step that received the wrong fitted object, one step earlier than the failing line.