Feature Engineering & Model Tuning
Module Completed: September 2021
🎯 Module Overview
Building a model is only part of the job — selecting the right features, handling high-dimensional data, tuning hyperparameters, and validating performance robustly are what separate a prototype from a production-ready model. This module covers the full toolkit: feature selection, regularisation, cross-validation, ROC/threshold tuning, Pipelines, and GridSearchCV.
📖 Topics Covered
Missing Value Treatment Strategies
Beyond simple mean/median imputation — a principled approach to large datasets with many missing columns:
- Calculate % null per column before deciding to drop or impute
- Drop columns with > X% null (X chosen based on data distribution of null counts)
- Median imputation for remaining columns (preferred over mean — robust to skewed distributions)
- Zero-variance columns: attributes where all values are (nearly) identical add no predictive signal — identify and drop using variance threshold
Feature Selection
Reducing the feature space to remove noise, speed up training, and improve generalisation:
- Variance Threshold — drop near-constant features (variance ≈ 0)
- Correlation Filter — drop one column from any pair with |r| > 0.8 to remove redundancy
- Recursive Feature Elimination (RFE) — iteratively removes weakest features using model coefficients or feature importances
- Forward / Backward Feature Selection — greedy search adding/removing one feature at a time
- Feature Importance from Random Forest / XGBoost — rank features by mean decrease in impurity
Regularisation
Penalising large model coefficients to reduce overfitting in linear/logistic models:
- Ridge (L2) — adds sum of squared coefficients to loss; shrinks all coefficients but keeps all features;
alphacontrols strength; closed-form solution - Lasso (L1) — adds sum of absolute coefficients to loss; drives some coefficients exactly to zero (built-in feature selection);
alphacontrols sparsity - ElasticNet — combines L1 + L2;
l1_ratiocontrols the mix - Choosing
alphavia cross-validated grid search (RidgeCV,LassoCV,GridSearchCV)
Cross-Validation
Reliable model evaluation beyond a single train-test split:
- K-Fold CV — splits data into K folds; trains on K-1, validates on 1; repeats K times; average score is the final estimate
- Stratified K-Fold — preserves class proportions in each fold; critical for imbalanced targets
- Leave-One-Out CV (LOOCV) — K = n; maximum use of data; computationally expensive; best for very small datasets
- Bootstrapping — random sampling with replacement; each bootstrap sample trains a model; distribution of scores gives confidence intervals around performance estimates
- Rule: fit scaler/imputer on training fold only, transform test fold — never leak test statistics
ROC Curve & Threshold Management
Beyond default 0.5 threshold — tuning the decision boundary for business requirements:
- ROC Curve — plots True Positive Rate (Recall) vs False Positive Rate at all thresholds
- AUC-ROC — area under the ROC curve; model's discrimination ability; 0.5 = random, 1.0 = perfect
- Threshold Tuning — use
predict_probato get probability scores, then apply custom threshold; raising threshold → higher precision, lower recall; lowering → higher recall, lower precision - When to lower threshold: when missing a positive (e.g., missing a fail/fraud) is more costly than a false alarm
Hyperparameter Tuning
Systematic search for optimal model configuration:
- GridSearchCV — exhaustive search over all combinations in a parameter grid; evaluates each via cross-validation; best for small grids
- RandomizedSearchCV — samples a fixed number of random combinations; better for large grids; often finds near-optimal faster
refit=True— automatically retrains the best model on the full training set after searchcv_results_— detailed scores for every parameter combination evaluated
Scikit-learn Pipelines
Chaining preprocessing steps + model into a single reusable object:
- Prevents data leakage — scaler/imputer fitted only on training data within each CV fold
- Enables clean
fit()/predict()API for the entire workflow - Compatible with
GridSearchCV— hyperparameters addressable viastep__paramsyntax - Common pattern:
Pipeline([('scaler', StandardScaler()), ('clf', RandomForestClassifier())]) - Pickle the entire pipeline for deployment — guarantees identical preprocessing at inference time
Dimensionality Reduction for High-Dimensional Data
When features >> samples:
- PCA to reduce 500+ features to the top K components explaining 90–95% variance
- Apply PCA after scaling, before model training
- Trade-off: slight accuracy loss vs significant speed gain; critical at gigabyte/terabyte scale
Sampling Strategies (Up/Down-sampling)
- Under-sampling — remove majority class records; only viable with very large datasets
- Over-sampling (SMOTE / ADASYN) — generate synthetic minority samples; apply only on training fold, never on test
- ADASYN preferred for complex decision boundaries
🏆 Project — Feature Engineering, Model Selection & Tuning
Submitted: 12 September 2021 Domain: Semiconductor manufacturing process
Problem Statement
Predict the Pass/Fail yield of a semiconductor manufacturing entity from sensor signal data. Determine whether all 591 features are necessary or whether a reduced feature set can achieve comparable performance.
Dataset
- Shape: 1,567 records × 592 columns (591 features + 1 target)
- Target:
Pass/Fail— original encoding: -1 = Pass, 1 = Fail → re-encoded to 1 = Pass, 0 = Fail - Data:
signal-data.csv— continuous float sensor readings; heavy with missing values
Data Cleaning Pipeline
| Step | Action | Result |
|---|---|---|
| Null % analysis | Computed % null per column | 538 of 592 columns had NaNs |
| Drop high-null columns | Dropped columns with > 5% null | Down to 540 columns |
| Median imputation | Imputed median for remaining nulls | No NaNs remaining |
| Zero-variance drop | Dropped near-constant columns | Down to 217 columns |
| Correlation filter | Dropped one from each pair with | r |
| Final dataset | Ready for modelling | 1,567 rows × 116 features |
EDA
- Wide range of feature scales (0.01–0.1 up to 2,700–3,300) → StandardScaler mandatory
- Target imbalance: significantly more Pass than Fail records
- PCA for visualisation: 90% variance explained by a subset of components (applied for EDA only, not initial modelling)
Preprocessing
- Train-Test Split: 70:30 stratified → 1,096 train / 471 test
- ADASYN oversampling applied to training data only to fix class imbalance
- StandardScaler fitted on training data, applied to test data (no leakage)
Models Trained
Model 1 — Random Forest (Default Parameters)
- High overall accuracy
- Poor recall for
Class=Fail(model missed 33 of 34 actual failures) - ROC threshold tuning: raised threshold to 0.67 → slight improvement in Fail recall
Model 2 — Random Forest (Hyperparameter Tuned)
- GridSearchCV used for tuning
n_estimators,max_depth,min_samples_split,max_features - Marginal improvement in Fail class recall (+4 correct vs Model 1 with default threshold)
- ROC threshold reapplied → additional uplift
Model 3 — Random Forest + PCA (Dimensionality Reduction)
- PCA applied: retained 87 components explaining target variance
- Comparable accuracy to Models 1 & 2 with reduced feature space
- Slightly better Fail class prediction than baseline; threshold tuning applied
Bootstrap Validation
- Multiple random samples drawn from the dataset; model trained on each
- Score distribution showed
RandomForestClassifieris stable across different sample populations — low variance in train score, slightly more variance in test score
Model Comparison
| Model | Overall Accuracy | Fail Class Recall | Notes |
|---|---|---|---|
| Default RF | High | Very low | Missed most failures |
| Tuned RF | High | Slightly better | +4 correct fails vs default |
| PCA + RF | High | Comparable | 1/3 fewer features |
Final Model: RandomForestClassifier with tuned hyperparameters
Pipeline & Deployment
Pipelinebuilt:ADASYN → StandardScaler → RandomForestClassifier- Pickled artefacts saved:
final_model.pkl— trained RandomForeststandard_scaler.pkl— fitted scalerfinal_pca.pkl— PCA transformerfinal_attributes.pkl— list of selected feature names
- Future data (
Future_predictions.xlsx) loaded, cleaned, scaled, and passed through the pipeline for inference
🔑 Key Learnings
- High feature count demands a cleaning pipeline — blindly using 591 raw features is inefficient; variance threshold + null filter + correlation filter reduced to 116 useful features
- Scale first, always — features with vastly different ranges (0.01 vs 3000) will break distance-based models and skew linear model coefficients
- Apply oversampling only to training data — sampling before splitting leaks minority patterns into the test set and gives artificially inflated recall scores
- High accuracy ≠ good model for imbalanced targets — a model predicting all-Pass for a 90/10 split gets 90% accuracy while failing completely on the minority class
- ROC threshold tuning is a business decision — choose the threshold based on the cost of false negatives vs false positives; for semiconductor failures, missing a failure (FN) is far worse than a false alarm (FP)
- Pipelines prevent data leakage — fitting scaler inside a Pipeline ensures it sees only the training fold at each CV step; fitting outside leaks test distribution into the scaler
- PCA on high-dimensional data is practical — 117 features → 87 PCA components, comparable accuracy, dramatically faster at scale
- Bootstrap gives confidence intervals — a single train/test split gives one performance number; bootstrapping reveals the distribution of performance across different data samples
🛠️ Tools & Libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pickle
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import Ridge, Lasso, LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline
from sklearn.model_selection import (train_test_split, GridSearchCV,
RandomizedSearchCV, KFold,
StratifiedKFold, LeaveOneOut,
cross_val_score)
from sklearn.metrics import (classification_report, confusion_matrix,
roc_curve, roc_auc_score)
from sklearn.feature_selection import VarianceThreshold, RFE
from imblearn.over_sampling import ADASYN, SMOTE