# Data normalization before or after train-test split?

Which one is the right approach to make data normalization - before or after train-test split?

Normalization before split

normalized_X_features = pd.DataFrame(StandardScaler().fit_transform(X_features), columns = X_features.columns)
x_train, x_test, y_train, y_test = train_test_split(normalized_X_features, Y_feature, test_size=0.20, random_state=4)
LR = LogisticRegression(C=0.01, solver='liblinear').fit(x_train, y_train)
y_test_pred = LR.predict(x_test)


Normalization after split

x_train, x_test, y_train, y_test = train_test_split(X_features, Y_feature, test_size=0.20, random_state=4)
normalized_x_train = pd.DataFrame(StandardScaler().fit_transform(x_train), columns = x_train.columns)
LR = LogisticRegression(C=0.01, solver='liblinear').fit(normalized_x_train, y_train)

normalized_x_test = pd.DataFrame(StandardScaler().fit_transform(x_test), columns = x_test.columns)
y_test_pred = LR.predict(normalized_x_test)


So far I have seen both approaches.

• The 2nd approach is definitely wrong. You should not be calling a sklearn "fit" method on test data. 'fit' and 'fit_transform' are for training, 'predict' and 'transform' for testing. – David Waterworth Jul 3 '19 at 3:49

Normalization across instances should be done after splitting the data between training and test set, using only the data from the training set.

This is because the test set plays the role of fresh unseen data, so it's not supposed to be accessible at the training stage. Using any information coming from the test set before or during training is a potential bias in the evaluation of the performance.

• And the test set must also be normalized (before prediction)? – Tauno Jul 2 '19 at 13:22
• @TaunoTanilas you must treat the test set the same way you treat the training set. – Michael Hoffman Jul 2 '19 at 13:30
• Yes, test set needs to be normalized before feeding the model. – Adhira Deogade Jul 2 '19 at 13:43

As @Erwan said, you should normalize the training set and then use the same normalization steps on the test set. So your code should look like:

x_train, x_test, y_train, y_test = train_test_split(X_features, Y_feature, test_size=0.20, random_state=4)

scaler = StandardScaler()

normalized_x_train = pd.DataFrame(scaler.fit_transform(x_train), columns = x_train.columns)
LR = LogisticRegression(C=0.01, solver='liblinear').fit(normalized_x_train, y_train)

normalized_x_test = pd.DataFrame(scaler.transform(x_test), columns = x_test.columns)
y_test_pred = LR.predict(normalized_x_test)


Answer to your question: Do Normalization after splitting into train and test/validation. The reason is to avoid any data leakage.

Data Leakage:

Data leakage is when information from outside the training dataset is used to create the model. This additional information can allow the model to learn or know something that it otherwise would not know and in turn invalidate the estimated performance of the mode being constructed.