Concepts / Feature Scaling with MinMaxScaler

Feature Scaling with MinMaxScaler

PolynomialFeatures(degree=2) expands 13 scaled features into 105 columns: a constant, the originals, the squares and the pairwise products.

  • Programming

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.

Training data13 featuresFitted MinMaxScalermin and max from trainingFittedPolynomialFeaturesdegree=2Fitted Ridge modeltrained on 105 columnsTest data13 featuresScaled test datatransformed by trainingscalerExpanded test datatransformed by trainingexpansionTest score0.753 in the source splitfitscaled training datafit on expanded matrixtransform with fitted scalertransform with fitted expansionpredict and scoreused for prediction
Which fitted transformer parameters flow from the training data into the test transform, and where does the pipeline break if the test data is transformed with different fitted objects?

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.

Expanded matrix105 columnsConstant1 columnOriginal features13 columnsSquares13 columnsPairwise products78 columns
What does the 105-column expanded matrix contain, and how do the constant, original, squared, and cross-product columns nest within it?

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.

1constant, value 1x0first original, value 2x1second original, value 3x0^2 first times first, value 4x0 x1first times second, value 6x1^2 second times second, value9
Given a generated column name like x0 x1 or x02, which original feature or features produced it, and where does it sit in the output array?
Worked example

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.

  1. 1
    Start with the constant

    The first column is the constant 1, named '1'.

  2. 2
    Keep the originals

    The two originals are kept in input order: x0 has value 2 and x1 has value 3.

  3. 3
    Square each original

    x02 is 2 times 2, which is 4. x12 is 3 times 3, which is 9.

  4. 4
    Build the cross product

    x0 x1 is the first original times the second, which is 2 times 3, giving 6.

  5. 5
    Compare with the names

    Reading each name next to its value confirms that the expansion does what the names say.

Result

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
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 like

    A test-time call such as scaler.fit_transform(X_test) computes the minimum and maximum from the test set.

    Why it fails

    The 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 instead

    Call 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 like

    poly.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 fails

    The 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 instead

    Fit 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 like

    The Ridge fit raises a shape error, and the developer changes the regularization strength.

    Why it fails

    A 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 instead

    Check 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 fails

    The 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 instead

    Apply MinMaxScaler first, then PolynomialFeatures, then Ridge.

Practice: Find the Failing Step

MEDIUM

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_names list 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.

Related concepts

More concepts starting with F