Concepts / Data Splitting for Model Evaluation

Data Splitting for Model Evaluation

Split the data into training and test sets before preprocessing, because the test set is needed to evaluate the supervised model afterward.

  • Programming

A Surprising Result from Scaling

A very common first reaction to MinMaxScaler is to assume that scaling puts every feature into the same tidy box. You fit the scaler, you transform the data, and you expect every number in the result to sit between 0 and 1. For the training data, that expectation is correct. For the test data, it is often wrong. The mismatch is a useful place to learn how scaling actually works, and this article follows one workflow from start to finish: load a dataset, split it, scale it, and check the results.

What do you think happens?

You have fitted a MinMaxScaler on a training set and then used it to transform a separate test set. What do you expect the minimum and maximum of each test feature to be after scaling?

  • Always exactly 0 and 1, just like the training set

  • Not necessarily 0 and 1; the test set can fall below 0 or above 1

  • Always between 0 and 1, but the minimum is never exactly 0

Reveal answer
Answer:

Not necessarily 0 and 1. The test set can have values below 0 or above 1 after scaling.

The scaler subtracts the training minimum and divides by the training range. The test set has its own minimum and range, which need not match the training values, so its scaled values can land outside the training box. The source treats this as expected behavior, not a bug.

Why the Split Comes First

Preprocessing methods such as scalers are usually applied before a supervised algorithm is applied. The model, however, must still be evaluated on data it has not seen. That is why the dataset is split into a training set and a test set before any scaling happens. The test set is needed to evaluate the supervised model afterward, so it has to remain a separate collection of rows that the model and the preprocessing steps are not allowed to treat as already known.

The running example uses the cancer dataset from an earlier chapter. The scenario is to train a kernel SVM, which is a supervised model, and to preprocess its inputs with MinMaxScaler. The dataset has 569 data points, and each one is described by 30 measurements. The split sends 426 samples to the training set and 143 samples to the test set. The shapes printed by the code confirm that the feature count is still 30 in both sets; only the number of rows is divided.

Load dataset569 rows, 30 featuresSplit426 train, 143 testFit scalertraining features onlyTransform trainingsetlands in 0 to 1Transform test setsame stored min and rangeCheck test rangemay fall outside 0 to 1firsttrain rowsthensame scalerinspect
At which step does the train/test split occur relative to scaling and model training, and where could a result first diverge from expectation?

Fit Learns, Transform Applies

Once the split is done, scaling follows a fixed sequence. The preprocessing class is imported and then instantiated, just as the supervised models from earlier were created. The instance is then fitted, transformed on the training data, and transformed on the test data. Each step has a specific job, and the order matters.

Fitting is the step that learns from data. For MinMaxScaler, the fit method computes the minimum and maximum value of each feature on the training set. Unlike the classifiers and regressors used earlier, the scaler is given only the training features when fit is called. The target values y_train are not passed in and are not used. The scaler receives only the features, not the labels.

Fitting only records the numbers. Applying the change is the job of the transform method. In scikit-learn, transform is the method used whenever a preprocessing object returns a new representation of the data. Calling it on the training set produces the scaled training data. The shape stays the same, because the features are shifted and scaled rather than removed.

Rule

In words, transform subtracts the training set minimum and divides by the training set range. The minimum and the range are learned once, during fit, from the training data. The same two numbers are then reused for every later call to transform, including the call on the test set.

python
Notes on the code
  • The split happens before any scaling, so the test rows are held out.
  • fit receives only the training features; y_train is not passed to the scaler.
  • transform is called on X_test, not fit, so the test data does not change the stored minimum and range.

Following One Feature Through the Scaler

The cancer dataset is too large to inspect by hand, so this example uses one feature with a handful of values. Trace the state of the scaler at each step. The arithmetic is simple enough to check on paper before running any code.

Worked example

One feature, training values 2, 4, 6 and test values 1, 8

A scaler is fitted on the training values 2, 4, and 6 for one feature. It is then used to transform the test values 1 and 8. What are the scaled training values, and what are the minimum and maximum of the scaled test values?

  1. 1
    Fit on training values

    The training minimum is 2 and the training maximum is 6, so the training range is 6 minus 2, which equals 4. These two numbers are stored by the scaler.

  2. 2
    Transform the training values

    Each training value becomes (value minus 2) divided by 4. The value 2 becomes 0, the value 4 becomes 0.5, and the value 6 becomes 1. The training set lands exactly in 0 to 1.

  3. 3
    Transform the test values with the same stored numbers

    The value 1 becomes (1 minus 2) divided by 4, which equals negative 0.25. The value 8 becomes (8 minus 2) divided by 4, which equals 1.5. The scaler does not refit, so it still uses 2 and 4.

  4. 4
    Read the test minimum and maximum

    The scaled test values are negative 0.25 and 1.5. The test minimum is below 0 and the test maximum is above 1.

Result

Scaled training values are 0, 0.5, and 1. Scaled test values are negative 0.25 and 1.5, so the test range does not match the 0 to 1 box.

Training featuresvalues 2, 4, 6fitcomputes min and maxStored min 2, range 4reused for every transformScaled training0, 0.5, 1Test featuresvalues 1, 8Scaled testnegative 0.25, 1.5fit receiveslearnstransformtransform, no refittransform only
Which data flows into the scaler to compute the minimum and range, and which data is only transformed using those stored values?

Why Test Values Escape the 0 to 1 Box

The printed minimum and maximum for the test set are not 0 and 1 in the cancer workflow, and some scaled features fall outside the 0 to 1 range. The source explains this directly: MinMaxScaler, like the other scalers, applies exactly the same transformation to the training and test sets. The transform subtracts the training minimum and divides by the training range. The test set's own minimum and range might be different, so its scaled values can land outside the training box.

Test value 1scaled to negative 0.25Test value 8scaled to 1.5Training value 2scaled to 0Training value 4scaled to 0.5Training value 6scaled to 1
Why does a test value of 1 become negative 0.25 after scaling, when the scaler's minimum and range were learned only from the training data?

Mistakes That Break the Split

  • Common mistake

    Refitting the scaler on the test set

    What it looks like
    scaler.fit(X_test) followed by scaler.transform(X_test)
    Why it fails

    The test set now computes its own minimum and range, so the test data is scaled differently from the training data and the stored training statistics are overwritten.

    Do this instead

    Call fit only on X_train, then call transform on both X_train and X_test.

  • Common mistake

    Expecting the test set to fall inside 0 to 1

    What it looks like

    Assuming a scaled test maximum of 1.5 means the code has a bug

    Why it fails

    The test set has its own range, and the scaler reuses training numbers, so out-of-range values are expected.

    Do this instead

    Check that the training set is in 0 to 1, and accept that test values can fall outside it.

  • Common mistake

    Scaling before splitting

    What it looks like

    Calling fit on the full dataset and then splitting

    Why it fails

    The test set must remain data the model has not seen. Scaling before the split lets the test rows shape the preprocessing.

    Do this instead

    Split first, then fit the scaler on the training features only.

  • Common mistake

    Passing labels to the scaler

    What it looks like
    scaler.fit(X_train, y_train)
    Why it fails

    The scaler receives only the features. The target values are not used in computing the minimum and maximum.

    Do this instead

    Pass only the training features to fit.

Locating the Divergent Step

MEDIUM

A colleague says the test set looks wrong because its scaled maximum is 1.3 instead of 1. Using the workflow order from earlier, identify which step first produces a range different from the 0 to 1 expectation, and explain why the earlier steps are not the source of the difference.

Hints
  • Walk the workflow in order: load, split, fit, transform training, transform test, check.
  • Ask whether the training set was transformed into 0 to 1. If it was, the scaler's stored numbers are probably correct.
  • The only step where a test-specific range can first appear is the one that transforms the test set with stored training values.

Key Takeaways

  • Split the data into training and test sets before preprocessing, because the test set is needed to evaluate the supervised model afterward.
  • MinMaxScaler's fit learns each feature's minimum and maximum from the training features only; transform applies those stored numbers to any data.
  • Transforming the training set lands it in 0 to 1, but the test set uses training statistics, so its scaled values can fall below 0 or above 1, which is expected behavior.
  • When a scaled result looks wrong, trace the workflow in order and find the first step where the result departs from what the stored statistics predict.

Related concepts

More concepts starting with D