Based on the MLS-C01 exam guideReport an error
Once cleaning has made the data tidy, it is time to transform it into a form the model can learn from well. Feature engineering carries so much weight in the ML pipeline that it is commonly said to "determine 80% of model performance."
Many algorithms are sensitive to the scale (magnitude) of features. If you feed in age (0 to 100) and income (0 to 100 million) as they are, income overwhelms the distance and gradient calculations.
| Technique | Formula | Result range | Outlier impact | When to use |
|---|---|---|---|---|
| Min-Max normalization | (x − min) / (max − min) | [0, 1] | Very sensitive | When the range must be fitted exactly (image pixels, etc.) |
| Standardization (Z-score) | (x − μ) / σ | Mean 0, variance 1 | Sensitive | Default for linear models and neural networks |
| RobustScaler | (x − median) / IQR | Variable | Robust | When there are many outliers |
| MaxAbs | x / |max| | [−1, 1] | Sensitive | When zeros must be preserved in sparse matrices |
| Log transform | log(1+x) | Variable | Compresses the tail | Distributions with a long right tail |
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
# Standardization: default for neural networks/linear models
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test) # not fit!
# With many outliers, use RobustScaler
robust = RobustScaler()
X_train_robust = robust.fit_transform(X_train)[When scales differ wildly] [After standardization]
Loss function contours are Contours become nearly circular
elongated ellipses ↓
╱╲ ╭─╮
╱ ╲ zigzag descent │ ●│ converges along the shortest path
╲ ╱ ╰─╯
╲╱
The reason gradient descent is sensitive to scale is the shape of the loss function's contours. If feature scales differ wildly, the contours become elongated ellipses, and the gradient zigzags slowly toward the minimum. If standardization puts all features on the same scale, the contours become nearly circular and convergence is fast and stable. For distance-based models (KNN, K-means), it prevents Euclidean distance from being dominated by large-scale features.
⚠️ Trap: Just like an imputer, a scaler must be fit on the training set only. Using the test set's min/max/mean is leakage. Also, with Min-Max a single outlier pulls max up and compresses the remaining values toward 0, so when outliers are suspected, RobustScaler is the safe choice.
Most algorithms accept only numbers as input, so categorical variables must be converted into numbers.
| Encoding | Method | Suited for | Caution |
|---|---|---|---|
| Label Encoding | Category → integer (0, 1, 2…) | Ordinal, tree models | Imposes a false order if used on nominal data |
| One-Hot Encoding | Creates a 0/1 column per category | Nominal, low cardinality | Dimension explosion with high cardinality |
| Ordinal Encoding | Maps to integers in a meaningful order | Grades (low/mid/high) | Only when the order is real |
| Target Encoding | Replaces category with the target mean | High cardinality | Leakage and overfitting risk |
| Frequency Encoding | Replaces category with its frequency | High cardinality | Collisions when frequencies are equal |
| Feature Hashing | Maps to a fixed dimension with a hash | Unseen categories, streaming | Collisions occur |
| Embedding | A neural network learns low-dimensional dense vectors | Ultra-high cardinality, deep learning | Needs training data and a network |
Is there an order?
├─ Yes → Ordinal / Label Encoding (low < mid < high)
└─ No → How many unique values are there?
├─ Few (a few dozen or fewer) → One-Hot
└─ Many (thousands or more) → Target / Frequency / Hashing / Embedding
· Watch for leakage (Target)
· Accept collisions (Hashing)
· For deep learning, Embedding
The key distinction is whether there is an order. For grades (low < medium < high), Ordinal/Label is natural, and for something with no order like colors (red/blue/green), One-Hot is right. If you Label Encode colors for a linear model (red=0, blue=1, green=2), it creates the false order "green > blue > red."
from sklearn.preprocessing import OneHotEncoder, OrdinalEncoder
# Nominal: one-hot
ohe = OneHotEncoder(handle_unknown="ignore", sparse_output=False)
X_color = ohe.fit_transform(df[["color"]])
# Ordinal: ordinal with an explicit order
oe = OrdinalEncoder(categories=[["low", "mid", "high"]])
df["level_enc"] = oe.fit_transform(df[["level"]])Target encoding is powerful but dangerous.
# Target encoding (compute statistics from training-set folds only, to prevent leakage)
means = X_train.groupby("city")["target"].mean()
X_train["city_te"] = X_train["city"].map(means)
X_test["city_te"] = X_test["city"].map(means) # apply training-set statisticsWith high cardinality (for example, thousands of postal codes), target encoding avoids the dimension explosion of one-hot while compressing the relationship with the target into a single column. However, if you build a feature from the target of the same data, target leakage occurs, where the model peeks at the answer. To prevent this, use K-fold target encoding (computing each fold's statistics from the other folds) or smoothing (weighting the overall mean and the category mean by sample count). On the exam, the key is the trade-off: "high cardinality → one-hot explodes dimensions, and target encoding requires care about leakage."
⚠️ Trap: With One-Hot encoding, if the test set contains a new category not seen during training, it raises an error. You must set
handle_unknown="ignore"so that unknown categories are all treated as zero vectors, to be safe in production.
If you apply target encoding as-is to a category with extremely few samples (for example, only 3 records for that city), the value swings to extremes. You need to pull it toward the overall mean with smoothing.
Binning is a technique that splits a continuous variable into intervals (bins) and treats it like a categorical one.
| Method | Description | Example | Caution |
|---|---|---|---|
| Equal-width | Splits the value range into equal widths | 0–10, 10–20, 20–30 | With a skewed distribution, values pile into one bin |
| Equal-frequency | Same number of samples in each bin | Quartile-based | Boundaries depend on the data |
| Domain-based | Splits at meaningful boundaries | Age → minor/young adult/middle-aged/senior | Requires domain knowledge |
Effects of binning:
The downside is information loss. Fine differences within a bin disappear.
import pandas as pd
# Equal-width binning
df["age_bin"] = pd.cut(df["age"], bins=[0, 18, 35, 60, 120],
labels=["minor", "young", "middle", "senior"])
# Equal-frequency binning (quartiles)
df["income_q"] = pd.qcut(df["income"], q=4, labels=["Q1", "Q2", "Q3", "Q4"])Binning is a tool for adjusting the model's bias-variance trade-off. If you use continuous values as they are, a linear model can only express a monotonic straight-line relationship (high bias), but if you convert them to bin dummies, it learns an independent effect in each bin and captures nonlinearity (reduced bias). However, if you split bins too finely, each bin has few samples and estimates become unstable (increased variance). Equal-frequency binning mitigates this variance problem by equalizing the sample count in each bin.
Applying binning to tree or boosting models gains almost nothing, because trees already find split points on their own and express nonlinearity. In questions that ask "which preprocessing has little effect," the model type is the clue.
If scaling, encoding, and binning are tasks that "change the form," derived features are tasks that "create signal that wasn't there."
amount / average amount or debt / income is a stronger signal than the amount itself.age × income) expresses a combined effect such as "high-income middle-aged."x², x³ lets a linear model express curved relationships.Polynomials and interactions grow dimensionality quickly and lead to overfitting. Applying a degree-2 polynomial to 3 features gives 10, and to 10 features gives 66. Use them together with regularization (Ridge/Lasso), or, for tree models, they are often unnecessary in the first place.
Aggregate features become leakage if you pick the wrong aggregation point in time. "This user's average purchase amount over their entire history" can include data from after the prediction time. You must aggregate using only data from before the prediction time.
Once you've created features, you also have to cut them back. Unnecessary features increase overfitting, training time, and difficulty of interpretation all together.
| Approach | Method | Characteristics |
|---|---|---|
| Filter | Pre-screen with statistics such as correlation, variance, chi-square | Fast but independent of the model |
| Wrapper | Select by watching actual performance with forward selection and backward elimination | Accurate but expensive |
| Embedded | Automatic selection during model training (Lasso, tree importance) | Practical, specific to the model |
| Model | Scaling | One-hot | Binning | Missing-value imputation |
|---|---|---|---|---|
| Linear/logistic regression | Required | Required (nominal) | Helpful | Needed |
| SVM | Required | Required | Helpful | Needed |
| KNN / K-means | Required | Required | Moderate | Needed |
| Neural network | Required | Needed (or embedding) | Moderate | Needed |
| PCA | Required | Needed | Unsuitable | Needed |
| Decision Tree / RF | Unnecessary | Needed (numeric input) | Small effect | Needed |
| XGBoost / LightGBM | Unnecessary | Needed (numeric input) | Small effect | Needed (some handle it natively) |
In the next article, we look at feature engineering for special data such as dates and text, and at handling high-cardinality categorical data.
Click a choice to reveal the answer and explanation.
Question 1
Which of the following algorithms does not need input feature scaling?
Question 2
You want to feed a nominal variable with no order, such as "color (red/blue/green)," into linear regression. Which encoding is most appropriate?
Question 3
When encoding a high-cardinality categorical variable with thousands of unique values, such as postal codes, which technique avoids dimension explosion but requires care about data leakage?
Question 4
When using Min-Max normalization, one variable contains an extreme outlier. Which describes the resulting problem and the alternative correctly?
Question 5
Which feature engineering technique helps a linear model capture a nonlinear relationship in which "purchase rate changes sharply in a particular age range"?