Module 7

Machine Learning

Classical machine learning end to end — algorithms, evaluation, ensembling, and shipping a trained model.

35 lessonsAI & MLHarinIT Academy
Module 7 · Lesson 7.1

Introduction to ML

7.1.1 What is Machine Learning?

Machine Learning (ML) is a branch of Artificial Intelligence (AI) that enables computers to learn patterns from data and make predictions or decisions without being explicitly programmed for every possible situation.

In traditional programming, we provide:

Rules + Data → Output

In machine learning, we provide:

Data + Expected Output → Learning Algorithm → Model

The trained model can then be used to make predictions on new, unseen data.

Simple Example

Suppose we want to predict whether an email is spam or not spam.

A traditional program might contain thousands of manually written rules:

IF email contains "free money"

THEN spam

IF email contains "winner"

THEN spam

...

A machine learning system can instead learn from historical emails:

Training Data

↓
Emails + Labels
↓
ML Algorithm
↓
Trained Model
↓
New Email
↓
Spam / Not Spam

The important idea is that the model learns relationships and patterns from examples.

7.1.2 Why Do We Need Machine Learning?

  • Traditional programming works well when rules can be clearly defined.
  • For example:
  • IF age >= 18

THEN eligible = True

ELSE

eligible = False

However, many real-world problems are difficult to solve using fixed rules.

Examples include:

  • Detecting fraudulent transactions

  • Recognizing faces

  • Predicting customer churn

  • Recommending movies

  • Predicting house prices

  • Detecting spam

  • Predicting equipment failures

  • Understanding natural language

  • Identifying diseases from medical images

  • Forecasting sales

For these problems, manually writing rules for every possible scenario is impractical.

Machine learning allows the computer to discover useful patterns from historical data.

7.1.3 Traditional Programming vs Machine Learning

Traditional Programming Machine Learning
Rules are explicitly written Rules/patterns are learned from data
Programmer defines logic Algorithm learns relationships
Data + Rules → Output Data + Output → Model
Usually deterministic Often probabilistic
Changes require modifying rules Model can be retrained with new data
Suitable for well-defined rules Suitable for complex patterns

Example: House Price Prediction

Traditional programming would require rules such as:

IF area > 2000 AND location = A

  • price = ...
  • This becomes complicated because house prices depend on many factors.
  • Machine learning can learn the relationship:
  • Area
  • Bedrooms
  • Location
  • Age
  • Parking
  • Distance from city
↓
Machine Learning Model
↓
Predicted Price

7.1.4 Artificial Intelligence vs Machine Learning vs Deep Learning

These three terms are closely related but are not identical.

Artificial Intelligence (AI)

│
├── Machine Learning (ML)
│ │
│ ├── Traditional ML
│ │ ├── Linear Regression
│ │ ├── Decision Trees
│ │ ├── SVM
│ │ └── K-Means
│ │
│ └── Deep Learning
│ ├── Neural Networks
│ ├── CNN
│ ├── RNN
│ └── Transformers
Artificial Intelligence

AI is the broader field concerned with building systems capable of performing tasks that normally require human intelligence.

Examples:

  • Reasoning

  • Planning

  • Perception

  • Language understanding

  • Decision-making

Machine Learning

ML is a subset of AI where systems learn from data.

Deep Learning

Deep Learning is a subset of ML based primarily on multi-layer neural networks.

7.1.5 How Machine Learning Works

A typical ML system follows these steps:

Data

↓
Data Preprocessing
↓
Feature Engineering
↓
Training Dataset
↓
ML Algorithm
↓
Trained Model
↓
Model Evaluation
↓
Model Deployment
↓
Predictions on New Data

For example, suppose a company wants to predict whether a customer will leave.

The dataset might contain:

Customer Age Tenure Monthly Charges Support Calls Churn
C001 25 2 850 5 Yes
C002 42 8 450 1 No
C003 31 3 700 4 Yes
C004 51 10 400 0 No
  • The algorithm learns patterns between customer characteristics and churn.
  • For a new customer:
  • Age = 29
  • Tenure = 2
  • Monthly Charges = 800
  • Support Calls = 5
  • the model may predict:
  • Churn Probability = 87%

7.1.6 Important Terminology

Understanding ML terminology is essential.

Dataset

A collection of data used for machine learning.

Example:

customer_data.csv
Feature
An input variable used by the model.
  • For customer churn:
  • Age
  • Tenure
  • Monthly Charges
  • Support Calls
  • are features.

Target

The variable that the model attempts to predict.

Example:

Churn

Observation / Sample

  • One individual record in the dataset.
  • C001 | 25 | 2 | 850 | 5 | Yes
  • is one sample.

Model

A mathematical representation learned from data.

Examples:

  • Linear Regression model

  • Decision Tree model

  • Random Forest model

  • Logistic Regression model

Training

The process of allowing an algorithm to learn patterns from historical data.

Prediction

The output generated by a trained model for new data.

7.1.7 Features and Target

Consider a dataset for predicting employee salary:

Experience Education Location Age Salary
2 Bachelor's Hyderabad 25 600000
5 Master's Bengaluru 30 1000000
8 Master's Hyderabad 35 1500000
  • Here:
  • Features:
  • Experience
  • Education
  • Location
  • Age
  • Target:
  • Salary
  • The model learns:

\[X \rightarrow Y\]

where:

  • (X) = input features

  • (Y) = target/output

7.1.8 Types of Machine Learning

Machine learning is commonly divided into three major categories:

1. Supervised Learning

The training data contains the correct answers.

Input Data + Known Output

↓
Algorithm
↓
Model

Examples:

  • House price prediction

  • Spam detection

  • Customer churn prediction

  • Disease classification

Two major supervised learning tasks are:

Regression

Predict a continuous numerical value.

Example:

  • House Price = ₹85,00,000
  • Classification
  • Predict a category.

Example:

Spam = Yes

2. Unsupervised Learning

  • The training data does not contain predefined answers.
  • The algorithm attempts to discover hidden patterns or structures.
  • Input Data
↓
ML Algorithm
↓
Patterns / Groups

Examples:

  • Customer segmentation

  • Document clustering

  • Anomaly detection

  • Dimensionality reduction

Common algorithms include:

  • K-Means

  • Hierarchical Clustering

  • PCA

3. Reinforcement Learning

  • An agent learns by interacting with an environment.
  • The agent receives rewards or penalties based on its actions.
  • Environment
↑
│
Action
│
Agent
│
Reward
↓

Examples:

  • Game-playing AI

  • Robotics

  • Autonomous systems

  • Resource optimization

7.1.9 Training, Validation and Test Data

A dataset is commonly divided into multiple parts.

Training Set

Used to train the model.

Typical proportion:

70–80%

Validation Set

  • Used to tune the model and compare alternatives.
  • Typical proportion:
  • 10–15%

Test Set

  • Used for the final unbiased evaluation.
  • Typical proportion:
  • 10–20%
  • A common workflow is:
  • Complete Dataset
│
┌─────────┴─────────┐
↓ ↓
Training Test
│
↓
Validation

The exact split depends on the problem and dataset size.

7.1.10 What Does a Machine Learning Model Learn?

A model generally learns parameters that describe relationships between input variables and the target.

For example, linear regression may learn:

\[y = b_0 + b_1x\]

where:

  • (x) = input

  • (y) = prediction

  • (b_0) = intercept

  • (b_1) = learned coefficient

Suppose:

\[Salary = 500000 + 150000 \times Experience\]

For 5 years of experience:

\[Salary = 500000 + (150000 \times 5)\]

\[Salary = 1,250,000\]

The coefficients were learned from training data.

7.1.11 Machine Learning Example Using Python

A simple example using Scikit-learn:

from sklearn.linear_model import LinearRegression
X = [[1], [2], [3], [4], [5]]
y = [30000, 40000, 50000, 60000, 70000]
model = LinearRegression()
model.fit(X, y)
prediction = model.predict([[6]])
print(prediction)

The important operation is:

model.fit(X, y)

fit() trains the model using the supplied examples.

Then:

model.predict([[6]])

asks the trained model to make a prediction for a new input.

7.1.12 Applications of Machine Learning

Machine learning is used across almost every industry.

Finance

  • Fraud detection

  • Credit scoring

  • Risk analysis

  • Algorithmic trading

Healthcare

  • Disease prediction

  • Medical image analysis

  • Drug discovery

  • Patient risk prediction

Retail

  • Recommendation systems

  • Customer segmentation

  • Demand forecasting

  • Dynamic pricing

Manufacturing

  • Predictive maintenance

  • Quality inspection

  • Production optimization

Banking

  • Loan approval

  • Fraud detection

  • Customer churn prediction

Transportation

  • Route optimization

  • Traffic prediction

  • Autonomous driving

Technology

  • Search engines

  • Voice assistants

  • Recommendation systems

  • Generative AI

7.1.13 Advantages of Machine Learning

1. Automation

ML can automate complex decision-making tasks.

2. Pattern Detection

It can identify patterns that may be difficult for humans to detect.

3. Scalability

Models can process very large datasets.

4. Adaptability

Models can be retrained as new data becomes available.

5. Prediction

ML can predict future outcomes based on historical patterns.

7.1.14 Limitations of Machine Learning

Machine learning is not automatically intelligent or correct.

1. Requires Quality Data

Poor data can produce poor models.

This is often summarized as:

Garbage In → Garbage Out

2. Bias

If training data contains bias, the model can learn that bias.

3. Overfitting

A model can memorize training data instead of learning general patterns.

4. Computational Cost

Some ML algorithms require significant computing resources.

5. Interpretability

Some complex models can be difficult to explain.

6. Data Dependency

A model's performance can degrade when real-world data changes significantly from its training data.

7.1.15 Machine Learning Lifecycle

A real-world ML project usually follows this lifecycle:

1. Define Business Problem
2. Collect Data
3. Explore Data
4. Clean Data
5. Feature Engineering
6. Split Data
7. Select Algorithm
8. Train Model
9. Evaluate Model
10. Tune Model
11. Deploy Model
12. Monitor Model

13. Retrain When Required

This lifecycle is important because building the model is only one part of an ML project.

7.1.16 Key Takeaways

  • Machine Learning is a subset of Artificial Intelligence.

  • ML systems learn patterns from data.

  • Features are inputs used by a model.

  • Target is the value the model attempts to predict.

  • Supervised learning uses labeled data.

  • Unsupervised learning discovers patterns without labeled outputs.

  • Reinforcement learning learns through rewards and penalties.

  • Regression predicts numerical values.

  • Classification predicts categories.

  • Training data is used to learn the model.

  • Validation data helps tune the model.

  • Test data is used for final evaluation.

  • Good-quality data is critical to successful ML.

  • ML does not eliminate the need for domain knowledge.

  • A production ML system requires deployment and monitoring in addition to model training.

Quick Revision

AI → Broad field of intelligent systems
ML → Systems learn from data
Deep Learning → ML using deep neural networks
Feature → Input variable
Target → Output to predict
Training → Learning from data
Prediction → Applying learned model to new data
Regression → Predict a number
Classification → Predict a category
Clustering → Discover groups
Model Evaluation → Measure model performance
Module 7 · Lesson 7.2

ML Workflow

7.2.1 Introduction

The Machine Learning Workflow is the systematic sequence of steps followed to build, evaluate, deploy, and maintain a machine learning solution.

  • Building an ML model is not simply a matter of loading a dataset and calling fit().
  • A typical workflow is:
  • Business Problem
↓
Data Collection
↓
Data Understanding
↓
Data Cleaning
↓
Exploratory Data Analysis
↓
Feature Engineering
↓
Train / Validation / Test Split
↓
Model Selection
↓
Model Training
↓
Model Evaluation
↓
Hyperparameter Tuning
↓
Final Model
↓
Deployment
↓
Monitoring
↓
Retraining

The workflow is generally iterative, not strictly linear. Evaluation may reveal problems that require us to return to data preparation, feature engineering, or model selection.

7.2.2 Step 1 — Define the Business Problem

The first step is to clearly understand what problem needs to be solved.

Before selecting an algorithm, answer:

  • What business problem are we solving?

  • What exactly should the model predict?

  • Who will use the prediction?

  • What data is available?

  • How will success be measured?

  • What are the business constraints?

Example

A telecom company wants to reduce customer churn.

The business problem can be defined as:

Predict whether an existing customer is likely to leave the company in the next 30 days.

Now we can define:

Input → Customer information
Output → Churn / No Churn

This is a classification problem.

7.2.3 Step 2 — Collect Data

Machine learning requires relevant data.

Data can come from many sources:

  • Relational databases

  • Data warehouses

  • APIs

  • CSV files

  • Excel files

  • Application logs

  • IoT devices

  • Cloud storage

  • Web applications

  • Surveys

For example:

Customer Database

↓
Transaction Data
↓
Support Tickets
↓
Usage Data
↓
Customer Churn Dataset

The quality and relevance of the data strongly influence model performance.

7.2.4 Step 3 — Understand the Data

After collecting data, we need to understand its structure and characteristics.

Important questions include:

  • How many records are present?

  • How many columns are present?

  • What are the data types?

  • Which column is the target?

  • Are there missing values?

  • Are there duplicate records?

  • Are there outliers?

  • Are classes balanced?

  • Are there suspicious values?

In Python:

import pandas as pd
df = pd.read_csv("customers.csv")
print(df.shape)
print(df.head())
print(df.info())
print(df.describe())
  • For example:
  • Rows : 100,000
  • Columns : 25
  • Target : Churn

7.2.5 Step 4 — Data Cleaning

Real-world data is rarely perfect.

Common problems include:

  • Missing values

  • Duplicate records

  • Incorrect data types

  • Invalid values

  • Inconsistent formats

  • Outliers

  • Incorrect labels

Missing Values

Example:

Customer Age Income Churn
C001 25 50000 No
C002 NULL 60000 Yes
C003 31 NULL No

Possible solutions:

  • Remove rows

  • Replace with mean

  • Replace with median

  • Replace with mode

  • Use model-based imputation

Example:

df["Age"] = df["Age"].fillna(df["Age"].median())

The correct method depends on the dataset and business context.

7.2.6 Step 5 — Exploratory Data Analysis

Exploratory Data Analysis (EDA) is the process of investigating the dataset to understand patterns, relationships, distributions, and anomalies.

Typical EDA activities include:

  • Distribution analysis

  • Correlation analysis

  • Outlier detection

  • Group comparisons

  • Target distribution analysis

  • Visualization

Example:

import matplotlib.pyplot as plt
df["Age"].hist()
plt.xlabel("Age")
plt.ylabel("Number of Customers")
plt.show()

For classification:

print(df["Churn"].value_counts())

This helps determine whether the target classes are balanced.

7.2.7 Step 6 — Feature Engineering

Feature engineering means creating, transforming, or selecting variables that help the model learn useful patterns.

Suppose we have:

Date_of_Birth

Instead of directly using the date, we might derive:

  • Age
  • Similarly:
  • Login_Date
  • could produce:
Day_of_Week
Month
Is_Weekend
Example
df["TotalCharges"] = (
df["MonthlyCharges"] * df["TenureMonths"]
)

Feature engineering can significantly improve model performance.

7.2.8 Step 7 — Select Features and Target

  • Suppose our dataset contains:
  • Age
  • Tenure
  • MonthlyCharges
  • SupportCalls
  • ContractType
  • Churn
  • Then:
X = df[
    [
        "Age",
        "Tenure",
        "MonthlyCharges",
        "SupportCalls",
        "ContractType"
    ]
]
y = df["Churn"]

Here:

  • X = features

  • y = target

Conceptually:

\[X \rightarrow Model \rightarrow y\]

7.2.9 Step 8 — Split the Dataset

  • We should not train and evaluate the model using exactly the same data.
  • A common approach is:
  • Dataset
│
┌───────┴───────┐
↓ ↓
Training Test
│
↓
Validation

For example:

Training → 70%
Validation → 15%
Test → 15%

Another common approach is to use:

Training → 80%
Test → 20%

and use cross-validation on the training set for model selection.

Using Scikit-learn:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)

7.2.10 Step 9 — Select an ML Algorithm

The algorithm should be selected based on the problem.

Problem Possible Algorithms
House price prediction Linear Regression, Random Forest, XGBoost
Spam detection Logistic Regression, Naive Bayes, SVM
Customer churn Logistic Regression, Random Forest, XGBoost
Customer segmentation K-Means, Hierarchical Clustering
Image classification CNN / Deep Learning
Recommendation Collaborative Filtering, ML models
Time-series forecasting Specialized forecasting models

There is no single algorithm that is best for every problem.

7.2.11 Step 10 — Train the Model

Training means allowing the algorithm to learn patterns from the training dataset.

Example:

from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train)

The important operation is:

model.fit(X_train, y_train)

During training, the algorithm estimates model parameters based on the training data.

7.2.12 Step 11 — Make Predictions

After training, we can use the model to predict unseen data.

y_pred = model.predict(X_test)

For probabilities:

y_probability = model.predict_proba(X_test)
  • For example:
  • Customer Actual Prediction
  • C101 Yes Yes
  • C102 No No
  • C103 Yes No
  • C104 No Yes

The incorrect predictions will be important during model evaluation.

7.2.13 Step 12 — Evaluate the Model

  • Model evaluation determines whether the model performs sufficiently well.
  • The evaluation metric depends on the problem.
  • Classification
  • Common metrics:
  • Accuracy

  • Precision

  • Recall

  • F1 Score

  • ROC-AUC

  • Confusion Matrix

Regression

Common metrics:

  • MAE

  • MSE

  • RMSE

  • (R^2)

Example:

from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

If:

Accuracy = 0.91

the model correctly classified approximately 91% of the test observations.

However, accuracy alone may be misleading, particularly for imbalanced datasets.

7.2.14 Step 13 — Hyperparameter Tuning

Most ML algorithms have parameters that are not learned directly from the training data.

These are called hyperparameters.

  • For a Random Forest, examples include:
  • n_estimators
  • max_depth
  • min_samples_split
  • min_samples_leaf

We can search for better values using:

  • Grid Search

  • Randomized Search

  • Bayesian optimization

Example:

from sklearn.model_selection import GridSearchCV
params = {
"C": [0.1, 1, 10]
}
grid = GridSearchCV(
LogisticRegression(),
params,
cv=5
)
grid.fit(X_train, y_train)
print(grid.best_params_)

7.2.15 Step 14 — Check for Overfitting and Underfitting

A good model should generalize to unseen data.

Overfitting

The model performs very well on training data but poorly on unseen data.

Training Accuracy → 99%
Test Accuracy → 72%

This indicates possible overfitting.

Underfitting

The model performs poorly on both training and test data.

Training Accuracy → 65%
Test Accuracy → 63%

The model may be too simple or the features may be inadequate.

The goal is to find an appropriate balance.

7.2.16 Step 15 — Select the Final Model

After comparing multiple algorithms, choose the model based on:

  • Evaluation metrics

  • Business requirements

  • Interpretability

  • Training time

  • Prediction speed

  • Resource requirements

  • Model size

  • Maintenance requirements

For example:

Model F1 Training Time Interpretability
Logistic Regression 0.78 Low High
Random Forest 0.84 Medium Medium
XGBoost 0.86 Medium Medium

If interpretability is critical, Logistic Regression might still be preferable even though XGBoost has higher F1.

The best model is not necessarily the model with the highest metric.

7.2.17 Step 16 — Deploy the Model

  • Once the model has been validated, it can be deployed so that applications can use it.
  • A typical architecture is:
  • User/Application
↓
API
↓
ML Model
↓
Prediction
↓
Application

For example:

Customer Information

↓
REST API
↓
Churn Model
↓
87% Churn Probability
↓
Customer Retention System

Popular deployment approaches include:

  • REST API

  • Batch prediction

  • Cloud ML services

  • Containerized applications

  • Embedded models

7.2.18 Step 17 — Monitor the Model

  • Deployment is not the end of the ML workflow.
  • A production model must be monitored.
  • Important monitoring areas include:
  • Model Performance
  • Is prediction quality decreasing?
  • Data Drift
  • Has the input data distribution changed?
  • Concept Drift
  • Has the relationship between inputs and target changed?
  • System Performance
  • Is prediction latency acceptable?
  • Data Quality
  • Are missing or invalid values increasing?

Example:

Model Accuracy

↓
0.91
↓
0.89
↓
0.84
↓
0.76

A significant degradation may indicate that the model needs investigation or retraining.

7.2.19 Step 18 — Retrain the Model

  • When new data becomes available, the model may need to be retrained.
  • A production workflow might look like:
  • New Production Data
↓
Data Validation
↓
Retraining
↓
Model Evaluation
↓
Approval
↓
Deployment
↓
Monitoring

This creates a continuous ML lifecycle.

7.2.20 Complete ML Workflow Example

Consider an employee attrition prediction system.

Business Problem

  • Predict whether an employee is likely to leave.
  • Data
  • Age
  • Experience
  • Salary
  • JobLevel
  • Overtime
  • JobSatisfaction
  • YearsAtCompany
  • Attrition
  • Workflow
1. Define Problem
2. Collect Employee Data
3. Clean Data
4. Perform EDA
5. Engineer Features
6. Split Dataset
7. Train Models
┌───────────────┐
│ Logistic Reg. │
│ Random Forest │
│ XGBoost │
└───────────────┘
8. Evaluate
9. Tune Best Model
10. Test Final Model
11. Deploy
12. Monitor

13. Retrain

  • The final system might produce:
  • Employee ID: E1024
  • Probability of Attrition: 82%
  • Risk Level: HIGH

The HR team could then take appropriate retention actions.

7.2.21 ML Workflow Using Scikit-learn

A simplified implementation looks like this:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score
# 1. Load data
df = pd.read_csv("employees.csv")
# 2. Select features and target
X = df[[
    "Age",
    "MonthlyIncome",
    "JobSatisfaction",
    "YearsAtCompany"
]]
y = df["Attrition"]
# 3. Split data
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)
# 4. Build pipeline
pipeline = Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression())
])
# 5. Train
pipeline.fit(X_train, y_train)
# 6. Predict
y_pred = pipeline.predict(X_test)
# 7. Evaluate
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

This example demonstrates an important principle: preprocessing and modeling should be treated as part of one reproducible pipeline.

7.2.22 Why an ML Pipeline Is Important

  • Without a proper pipeline, preprocessing can accidentally be applied incorrectly.
  • For example:
  • Raw Data
↓
Scaling
↓
Feature Selection
↓
Model
  • These steps should be consistently applied during both training and prediction.
  • Scikit-learn's Pipeline helps ensure that the same transformations are applied in the correct order.
  • This becomes especially important when the model moves into production.

7.2.23 Common ML Workflow Mistakes

  • Mistake 1 — Starting with the Algorithm
  • Bad approach:
  • "I want to use Random Forest."
  • Better approach:
  • Business Problem
↓
Data
↓
Problem Type
↓
Candidate Algorithms
  • Mistake 2 — Training on All Data
  • If the same data is used for training and evaluation, the reported performance may be misleading.
  • Always maintain an appropriate validation/test strategy.
  • Mistake 3 — Data Leakage

Data leakage occurs when information that should not be available during prediction is accidentally used during model training.

This can produce unrealistically high performance.

Example:

Future information

↓
Training Dataset
↓
Model
  • The model appears excellent during testing but fails in production.
  • Mistake 4 — Ignoring Class Imbalance
  • Suppose:
99% → No Fraud
1% → Fraud

A model that predicts No Fraud for everyone achieves 99% accuracy but is useless for fraud detection.

Therefore, metrics such as:

  • Precision

  • Recall

  • F1

  • ROC-AUC

may be more informative.

Mistake 5 — Ignoring Business Requirements

A technically excellent model may not be useful if:

  • It is too slow.

  • It is too expensive.

  • It cannot be explained.

  • It does not integrate with existing systems.

  • Its predictions do not lead to useful business actions.

7.2.24 ML Workflow vs ML Lifecycle

  • These terms are sometimes used interchangeably, but there is a useful distinction.
  • ML Workflow
  • Focuses primarily on building a model:
  • Data
↓
Preprocessing
↓
Training
↓
Evaluation
↓
Model
ML Lifecycle

Covers the complete production process:

Problem

↓
Data
↓
Training
↓
Evaluation
↓
Deployment
↓
Monitoring
↓
Retraining
↓
Redeployment

The ML lifecycle is broader than model development alone.

7.2.25 Key Takeaways

  • ML workflow provides a structured process for solving machine learning problems.

  • Start with the business problem, not the algorithm.

  • Data collection and data quality are critical.

  • EDA helps understand the data before modeling.

  • Feature engineering can significantly improve model performance.

  • Separate training and evaluation data to measure generalization.

  • Choose algorithms based on the problem and constraints.

  • Evaluate models using appropriate metrics.

  • Hyperparameter tuning can improve model performance.

  • Watch for overfitting, underfitting, and data leakage.

  • Deployment makes the model available to applications.

  • Monitoring is essential after deployment.

  • Models may need periodic or event-driven retraining.

  • A production ML system is an iterative lifecycle, not a one-time model-building exercise.

Module 7 · Lesson 7.3

Supervised Learning

7.3.1 Introduction

Supervised Learning is a type of machine learning in which an algorithm learns from labeled training data.

In supervised learning, every training example contains:

  • Input features (X) — information given to the model

  • Target/label (y) — the correct answer

The model learns the relationship between the inputs and the known outputs and then uses that relationship to predict outputs for new, unseen data.

The basic idea is:

Labeled Training Data

↓
ML Algorithm
↓
Trained Model
↓
New / Unseen Data
↓
Prediction

Mathematically, the objective is to learn a function:

\[f(X) \approx y\]

where:

  • (X) = input features

  • (y) = target

  • (f) = learned model/function

7.3.2 Simple Example

Suppose we want to predict house prices.

Our historical dataset contains:

Area (sq.ft) Bedrooms Age Price
1000 2 10 ₹40 L
1500 3 8 ₹60 L
2000 3 5 ₹85 L
2500 4 3 ₹110 L
  • Here:
  • Features:
  • Area
  • Bedrooms
  • Age
  • Target:
  • Price
  • The model learns from the historical examples.
  • For a new house:
  • Area = 1800 sq.ft
  • Bedrooms = 3
  • Age = 6 years
  • the model may predict:
  • Predicted Price = ₹75 L

The important point is that the model already knows the correct prices for historical examples during training.

7.3.3 Why Is It Called "Supervised"?

The term supervised comes from the idea that the model learns with a known answer.

Consider a teacher giving students questions along with correct answers.

Question → Correct Answer
↓
Student learns relationship
↓
New Question → Student predicts answer

Similarly:

Input → Known Target
↓
ML Algorithm
↓
Learned Model
↓
New Input → Predicted Target

The historical target values effectively act as the "teacher."

7.3.4 Structure of Supervised Learning

A supervised learning dataset can be represented as:

\[D = {(x_1,y_1),(x_2,y_2),...,(x_n,y_n)}\]

where:

  • (x_i) = input features for observation (i)

  • (y_i) = known target for observation (i)

  • (n) = number of training observations

The algorithm attempts to learn a function:

\[f:X\rightarrow Y\]

so that:

\[f(x_i) \approx y_i\]

for both training examples and, more importantly, new unseen examples.

7.3.5 Main Types of Supervised Learning

Supervised learning is primarily divided into two major categories:

Supervised Learning

│
┌─────────┴─────────┐
↓ ↓
Regression Classification
│ │
Predict a number Predict a class

1. Regression

Predicts a continuous numerical value.

Examples:

  • House price

  • Salary

  • Temperature

  • Sales revenue

  • Electricity consumption

  • Stock-related numerical forecasts

Example:

Input → House characteristics
Output → ₹85,00,000

2. Classification

Predicts a category/class.

Examples:

  • Spam / Not Spam

  • Fraud / Not Fraud

  • Customer Churn / No Churn

  • Disease / No Disease

  • Approved / Rejected

Example:

Input → Customer information
Output → Churn

7.3.6 Regression vs Classification

Feature Regression Classification
Output Numerical value Category
Example House price Spam detection
Output type Continuous Discrete
Example output ₹75,00,000 Spam
Common metrics MAE, RMSE, (R^2) Accuracy, Precision, Recall, F1
Algorithms Linear Regression Logistic Regression

Easy way to remember

Regression → "How much?"
Classification → "Which class?"

7.3.7 Common Supervised Learning Algorithms

Regression Algorithms

  • Linear Regression

  • Polynomial Regression

  • Decision Tree Regression

  • Random Forest Regression

  • Support Vector Regression

  • Gradient Boosting

  • XGBoost

  • LightGBM

  • CatBoost

Classification Algorithms

  • Logistic Regression

  • Decision Trees

  • Random Forest

  • Support Vector Machines

  • K-Nearest Neighbors

  • Naive Bayes

  • Gradient Boosting

  • XGBoost

  • LightGBM

  • CatBoost

Some algorithms, such as Decision Trees and Random Forests, can be used for both regression and classification.

7.3.8 Supervised Learning Workflow

A typical workflow is:

1. Collect Labeled Data
2. Clean Data
3. Explore Data
4. Select Features
5. Select Target
6. Split Dataset
7. Choose Algorithm
8. Train Model
9. Make Predictions
10. Evaluate Model
11. Tune Model
12. Deploy

For example:

Customer Data

↓
Customer Churn Labels
↓
Train Model
↓
Evaluate
↓
Deploy
↓
Predict Future Churn

7.3.9 Training Data

Training data is the data used by the algorithm to learn.

Suppose we have:

Age Salary Experience Churn
25 50000 2 Yes
35 80000 7 No
29 55000 3 Yes
45 100000 15 No
  • The model observes relationships between:
  • Age
  • Salary
  • Experience
↓
Churn

During training, the algorithm tries to find patterns that help predict Churn.

7.3.10 Training vs Prediction

These are two different stages.

Training
model.fit(X_train, y_train)

The model learns from labeled examples.

Prediction
model.predict(X_test)

The trained model predicts the target for new data.

Therefore:

Training:

X + Known y → Learn Model

Prediction:

X → Model → Predicted y

7.3.11 Example Using Scikit-learn

Let's build a simple classification model.
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
X = [
[25, 30000],
[30, 45000],
[35, 60000],
[40, 75000],
[45, 90000],
[50, 100000]
]
y = [
1,
1,
1,
0,
0,
0
]
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

The process is:

X + y

↓
Train/Test Split
↓
Logistic Regression
↓
fit()
↓
Trained Model
↓
predict()
↓
Predictions
↓
Evaluation

7.3.12 Classification Example — Spam Detection

  • Suppose we have thousands of emails.
  • Each email has a label:
  • Spam
  • Not Spam
  • The features could include:
  • Number of links
  • Number of suspicious words
  • Email length
  • Sender information
  • Number of attachments
  • Training data:
Links Suspicious Words Length Label
10 5 500 Spam
0 0 150 Not Spam
8 4 700 Spam
1 0 200 Not Spam
  • The model learns the relationship.
  • For a new email:
  • Links = 7
  • Suspicious Words = 3
  • Length = 600
  • The model may predict:
  • Spam

7.3.13 Regression Example — Sales Prediction

  • Suppose a company wants to predict monthly sales.
  • Features:
  • Advertising Spend
  • Number of Customers
  • Discount
  • Season
  • Previous Month Sales
  • Target:
  • Current Month Sales
  • Training data:
Advertising Customers Discount Sales
10,000 500 5% 80,000
20,000 800 10% 125,000
30,000 1000 10% 160,000

The model learns:

\[Sales = f(Advertising, Customers, Discount, ...)\]

For new input data, it produces a numerical prediction.

7.3.14 Loss Function

During training, a supervised learning algorithm needs a way to measure how wrong its predictions are.

This is done using a loss function or cost function.

Conceptually:

\[Loss = Actual - Predicted\]

  • The exact mathematical form depends on the problem.
  • Regression
  • Mean Squared Error is commonly used:

\[MSE = \frac{1}{n}\sum_{i=1}^{n}(y_i-\hat{y}_i)^2\]

where:

  • (y_i) = actual value

  • (\hat{y}_i) = predicted value

  • (n) = number of observations

The model attempts to minimize the loss.

7.3.15 Classification Loss

For classification, algorithms commonly use losses such as log loss / cross-entropy.

For binary classification:

\[L = -[y\log(p)+(1-y)\log(1-p)]\]

where:

  • (y) = actual class

  • (p) = predicted probability

A model that assigns high probability to the correct class generally receives a lower loss.

7.3.16 Model Generalization

  • The real goal of supervised learning is generalization.
  • A model should not simply memorize training examples.
  • It should learn patterns that work on new data.
  • Training Data
↓
Learn General Patterns
↓
New Unseen Data
↓
Good Predictions

This is why we evaluate the model on data that was not used to train it.

7.3.17 Overfitting

Overfitting occurs when a model learns the training data too closely, including noise and accidental patterns.

Example:

  • Training Accuracy = 99%
  • Test Accuracy = 72%
  • This indicates poor generalization.
  • Possible solutions:
  • Use more training data

  • Reduce model complexity

  • Regularization

  • Feature selection

  • Cross-validation

  • Early stopping

  • Pruning

  • Hyperparameter tuning

7.3.18 Underfitting

Underfitting occurs when a model is too simple to capture the underlying patterns.

Example:

  • Training Accuracy = 65%
  • Test Accuracy = 63%
  • Possible solutions:
  • Use a more powerful model

  • Add useful features

  • Reduce excessive regularization

  • Improve feature engineering

  • Train for longer where applicable

7.3.19 Advantages of Supervised Learning

1. Clear Objective

The target variable provides a defined learning objective.

2. Easy to Evaluate

Predictions can be compared with known answers.

3. Wide Range of Applications

Used in:

  • Finance

  • Healthcare

  • Retail

  • Manufacturing

  • Banking

  • Marketing

  • Cybersecurity

4. Powerful Predictive Capability

With sufficient quality data, supervised models can produce highly useful predictions.

7.3.20 Limitations of Supervised Learning

1. Requires Labeled Data

Creating labels can be expensive and time-consuming.

For example, manually labeling millions of images requires substantial effort.

2. Label Quality Matters

Incorrect labels can cause the model to learn incorrect patterns.

3. Bias in Training Data

If historical data contains bias, the model may reproduce it.

4. Data Distribution Changes

A model trained on historical data may perform poorly when real-world conditions change.

5. Overfitting

Complex models can memorize training data instead of learning general patterns.

7.3.21 Real-World Applications

Banking

  • Problem: Predict whether a loan applicant will default.
  • Income
  • Credit Score
  • Loan Amount
  • Employment
  • Existing Debt
↓
ML Model
↓
Default / No Default
E-Commerce
  • Problem: Predict whether a customer will make a purchase.
  • Browsing History
  • Previous Purchases
  • Time on Website
  • Cart Items
↓
Model
↓
Purchase / No Purchase
Healthcare
  • Problem: Predict disease risk.
  • Age
  • Blood Pressure
  • Cholesterol
  • Other Clinical Features
↓
Model
↓
Risk / No Risk
Manufacturing
  • Problem: Predict machine failure.
  • Temperature
  • Vibration
  • Pressure
  • Operating Hours
↓
Model
↓
Failure / No Failure

7.3.22 Supervised vs Unsupervised Learning

Supervised Learning Unsupervised Learning
Uses labeled data Uses unlabeled data
Target variable exists Usually no target variable
Predicts known output type Discovers hidden structure
Regression/classification Clustering/dimensionality reduction
Easy to measure against labels Evaluation can be more difficult
Example: churn prediction Example: customer segmentation

Example

Supervised:

Customer Data + Churn Label

↓
Predict Future Churn

Unsupervised:

Customer Data

↓
Discover Customer Groups

7.3.23 Key Takeaways

  • Supervised learning learns from labeled data.

  • Each training example contains features and a known target.

  • The model learns a relationship between inputs and outputs.

  • The two major supervised learning tasks are regression and classification.

  • Regression predicts continuous numerical values.

  • Classification predicts discrete categories.

  • Training uses fit().

  • Prediction uses predict().

  • Model performance must be evaluated on unseen data.

  • Loss functions measure prediction errors during training.

  • The ultimate objective is generalization, not memorization.

  • Overfitting occurs when the model performs well on training data but poorly on unseen data.

  • High-quality labeled data is one of the most important requirements for supervised learning.

  • Common supervised algorithms include Linear Regression, Logistic Regression, Decision Trees, Random Forest, SVM, KNN, Naive Bayes, XGBoost, LightGBM, and CatBoost.

Module 7 · Lesson 7.4

Unsupervised Learning

7.4.1 Introduction

Unsupervised Learning is a type of machine learning in which an algorithm learns patterns, structures, or relationships from data without predefined target labels.

In supervised learning, we have:

Features + Known Target

↓
ML Algorithm
↓
Model

In unsupervised learning, we typically have:

Features Only

↓
ML Algorithm
↓
Hidden Patterns / Groups / Structure

The primary objective is to discover useful information that is not explicitly provided in the dataset.

7.4.2 Simple Example

Suppose an online store has customer information:

Customer Age Annual Income Purchases
C001 22 30000 15
C002 25 35000 18
C003 24 32000 16
C004 45 90000 4
C005 48 95000 5
C006 46 88000 4

There is no column called:

Group 1 → Young customers with lower income and frequent purchases
Group 2 → Older customers with higher income and fewer purchases

The algorithm discovers these groups from the data rather than being given the group labels.

7.4.3 Why Is It Called "Unsupervised"?

Input → Correct Answer
↓
Algorithm learns

versus:

Unsupervised Learning

Input

↓
Algorithm searches for patterns
↓
Discovered structure

The model is not told:

"These customers belong to Group A."

Instead, it determines which observations appear similar according to the selected algorithm and distance/similarity criteria.

7.4.4 Main Goals of Unsupervised Learning

Unsupervised learning is commonly used for:

  1. Clustering

  2. Dimensionality Reduction

  3. Anomaly Detection

  4. Association / Pattern Discovery

  5. Data Exploration

7.4.5 Major Types of Unsupervised Learning

Unsupervised Learning

│
┌─────────────┼──────────────┐
↓ ↓ ↓
Clustering Dimensionality Anomaly
Reduction Detection
│ │ │
K-Means PCA Isolation
Hierarchical Forest
DBSCAN

7.4.6 Clustering

Clustering groups similar observations together.

Suppose customer data is represented as points:

• • •

• • •

• •

• • •

A clustering algorithm might identify:

Cluster A

• • •

• • •

Cluster B

• •

• • •

The objective is generally to make:

Common clustering algorithms

7.4.7 K-Means Clustering

\[K = 3\]

↓
Choose K
↓
Initialize Centroids
↓
Assign Points to Nearest Centroid
↓
Recalculate Centroids
↓
Repeat
↓
Final Clusters

K-Means is covered in more detail in Section 7.13.

7.4.8 Hierarchical Clustering

\ /

\ /

...

7.4.9 Dimensionality Reduction

↓
500 Features
↓
Hard to visualize
↓
High computational cost

Dimensionality reduction attempts to represent the important information using fewer dimensions.

Example:

100 Features

↓
PCA
↓
10 Components

A common technique is Principal Component Analysis (PCA).

PCA is covered in detail in Section 7.15.

7.4.10 Why Reduce Dimensions?

Dimensionality reduction can help with:

Visualization

Reduce high-dimensional data to 2D or 3D.

100-dimensional data

↓
PCA
↓
2D data
↓
Visualization
Computational Efficiency

Fewer features can reduce processing requirements.

Noise Reduction

Some dimensions may contain little useful information.

Feature Compression

Many correlated features can sometimes be represented using fewer components.

7.4.11 Anomaly Detection

The unusual transaction may be an anomaly.

Applications include:

Algorithms include:

7.4.12 Association Rule Learning

Another unsupervised technique is association rule learning.

It attempts to discover relationships between items.

For example, an e-commerce system may discover:

Customers who buy:

Laptop
often also buy:
↓
Frequently purchased together

7.4.13 Feature Representation

Each customer can be represented as a vector:

\[X_i = [Age_i, Income_i, SpendingScore_i]\]

For example:

\[X_1 = [25, 40000, 80]\]

An algorithm can compare these vectors to identify similarities.

The definition of similarity or distance is very important in many unsupervised algorithms.

7.4.14 Distance Measures

\[A=(x_1,y_1)\]

and

\[B=(x_2,y_2)\]

Euclidean distance is:

\[d(A,B)=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}\]

For example:

\[A=(2,3)\]

\[B=(5,7)\]

Then:

\[d=\sqrt{(5-2)^2+(7-3)^2}\]

\[=\sqrt{9+16}\]

\[=5\]

Distance measures are particularly important for K-Means and KNN-like approaches.

7.4.15 Feature Scaling

Feature scaling is often very important for unsupervised algorithms based on distances.

Consider:

Age → 20–70
Annual Income → 20,000–2,000,000

\[z=\frac{x-\mu}{\sigma}\]

where:

Min-Max Scaling

\[x'=\frac{x-x_{min}}{x_{max}-x_{min}}\]

7.4.16 Example Using K-Means

Here is a simple Python example:

from sklearn.cluster import KMeans
X = [
[25, 30000],
[28, 35000],
[24, 32000],
[45, 90000],
[48, 95000],
[46, 88000]
]
model = KMeans(
n_clusters=2,
random_state=42,
n_init=10
)
model.fit(X)
labels = model.labels_
print(labels)

The output could be something like:

\[1 1 1 0 0 0\]

7.4.17 How to Interpret Clusters

We can interpret them as:

Cluster 0 → High-income, low-frequency customers
Cluster 1 → Younger, lower-income, high-frequency customers

This interpretation requires domain knowledge.

The algorithm itself does not automatically know what "high-value customer" means.

7.4.18 Evaluating Unsupervised Learning

Evaluation is more challenging than supervised learning because there may be no known correct labels.

For clustering, common metrics include:

Silhouette Score

The silhouette score measures how well observations fit within their assigned clusters compared with other clusters.

The score generally ranges from:

\[-1 \text{ to } 1\]

A higher value generally indicates better-defined clusters.

Example:

from sklearn.metrics import silhouette_score
score = silhouette_score(X, labels)
print("Silhouette Score:", score)

Other approaches

7.4.19 Supervised vs Unsupervised Learning

Characteristic Supervised Unsupervised
Labels Required Not required
Target variable Yes Usually no
Main objective Prediction Pattern discovery
Tasks Regression, classification Clustering, dimensionality reduction
Evaluation Usually straightforward Often more difficult
Example Predict churn Segment customers
Example algorithm Random Forest K-Means

Example

Supervised:

Customer Data + Churn Label

↓
Churn Prediction

Unsupervised:

Customer Data

↓
Customer Segmentation

7.4.20 Advantages of Unsupervised Learning

1. No Labeling Required

Large amounts of unlabeled data can be analyzed.

2. Pattern Discovery

It can reveal previously unknown structures.

3. Customer Segmentation

Useful for marketing and personalization.

4. Data Exploration

Helps understand complex datasets before building predictive models.

5. Dimensionality Reduction

Can simplify high-dimensional datasets.

7.4.21 Limitations of Unsupervised Learning

1. Difficult Evaluation

There may be no known "correct" answer.

2. Interpretation Can Be Difficult

A cluster does not automatically have a business meaning.

3. Sensitive to Algorithm Choices

Different algorithms or parameters may produce different structures.

4. Feature Scaling Can Matter

Distance-based algorithms can be strongly affected by feature scales.

5. Number of Clusters May Be Unknown

For algorithms such as K-Means, selecting the appropriate value of (K) can be challenging.

6. Noise Can Affect Results

Outliers and irrelevant features can distort discovered patterns.

7.4.22 Real-World Applications

Customer Segmentation

A retail company can group customers based on:

Fraud and Anomaly Detection

An organization can identify transactions that differ significantly from normal behavior.

Normal Transactions

↓
Learn Normal Pattern
↓
Compare New Transactions
↓
Identify Unusual Transactions
Recommendation Systems

Unsupervised techniques can identify similarities between:

These similarities can support recommendation systems.

Document Clustering

Thousands of documents can be grouped based on their content:

Documents

↓
Text Representation
↓
Clustering
↓
Technology
Finance
Healthcare
Sports
News

7.4.23 Unsupervised Learning in a Data Engineering Environment

↓
Customer Transactions
↓
Feature Extraction
↓
ML Dataset
↓
Clustering
↓
Customer Segments
↓
BI / Power BI Dashboard

This demonstrates how ML can complement traditional data engineering and analytics systems.

7.4.24 Important Algorithms in This Module

The upcoming sections cover several important unsupervised techniques:

7.4.25 Key Takeaways

Quick Revision

Supervised Learning

Labeled Data → Learn → Predict
Unsupervised Learning
Unlabeled Data → Discover → Patterns
Clustering
Data → Similarity → Groups
Dimensionality Reduction
Many Features → Fewer Representations
Anomaly Detection
Normal Patterns → Identify Unusual Observations
Module 7 · Lesson 7.5

Reinforcement Learning

7.5.1 Introduction

Reinforcement Learning (RL) is a type of machine learning in which an agent learns how to make decisions by interacting with an environment.

Instead of learning from labeled examples, the agent learns through trial and error.

The agent performs an action, receives feedback in the form of a reward or penalty, and gradually learns which actions lead to better outcomes.

The basic idea is:

Environment

↗ ↘
Action Reward
↑ ↓
└──── Agent ─────┘

A more complete representation is:

State

↓
Agent
↓
Action
↓
Environment
↓
┌───────┴────────┐
↓ ↓
Reward New State
│ │
└──────→ Agent ←─┘

7.5.2 Simple Example

Reach destination → +100 reward
Hit obstacle → -10 reward
Move unnecessarily → -1 reward

Initially, the robot does not know the best path.

It tries different actions:

Trial 1 → Poor path → Low reward
Trial 2 → Better path → Higher reward
Trial 3 → Good path → Higher reward

...

Over many trials, the robot learns a strategy that maximizes its expected reward.

7.5.3 Why Is It Called Reinforcement Learning?

The term reinforcement comes from the idea that desirable behavior is reinforced through rewards.

For example:

Good Action

↓
Positive Reward
↓
Action becomes more likely

Similarly:

Poor Action

↓
Negative Reward
↓
Agent learns to avoid it

The agent does not receive a correct answer for every decision.

Instead, it receives feedback about the quality of its actions.

7.5.4 Reinforcement Learning vs Supervised Learning

These two approaches are fundamentally different.

Supervised Learning Reinforcement Learning
Uses labeled training data Learns through interaction
Correct answer is provided No direct correct answer
Learns from examples Learns through trial and error
Feedback usually immediate for each example Rewards can be delayed
Dataset is typically fixed Agent interacts with environment
Example: Spam classification Example: Game-playing agent

Supervised Learning

Input → Correct Label
↓
Model
Reinforcement Learning
State → Action → Reward → New State

7.5.5 Main Components of Reinforcement Learning

There are several important concepts:

  1. Agent

  2. Environment

  3. State

  4. Action

  5. Reward

  6. Policy

  7. Value Function

  8. Q-Function

  9. Episode

These components form the foundation of reinforcement learning.

7.5.6 Agent

The agent is the entity that makes decisions.

Examples:

The agent observes the current state and chooses an action.

State

↓
Agent
↓
Action

7.5.7 Environment

The environment receives the agent's action and responds with a new state and reward.

7.5.8 State

A state represents the current situation of the environment from the agent's perspective.

For a chess-playing agent, the state could contain:

Mathematically, a state can be represented as:

\[s_t\]

where (t) represents the current time step.

7.5.9 Action

The available actions form the action space.

For example:

\[A = {Left, Right, Up, Down}\]

7.5.10 Reward

A reward is feedback received by the agent after taking an action.

It tells the agent how desirable the outcome was.

Example:

Action Outcome Reward
Move toward goal Good +5
Move away Poor -2
Reach goal Excellent +100
Hit obstacle Bad -20

The agent's objective is generally to maximize the long-term cumulative reward, rather than simply maximizing the immediate reward.

7.5.11 Reward Function

The reward can be represented as:

\[R(s,a)\]

where:

The environment may produce:

\[r_{t+1}\]

after the agent takes action (a_t) in state (s_t).

The interaction can therefore be represented as:

\[(s_t,a_t,r_{t+1},s_{t+1})\]

This sequence is fundamental to reinforcement learning.

7.5.12 Policy

A policy defines how the agent chooses actions.

It can be represented as:

\[\pi(a|s)\]

State A → Move Right
State B → Move Up
State C → Move Left

A stochastic policy may assign probabilities:

Move Right → 70%
Move Up → 20%
Move Left → 10%

The goal of learning is often to discover a good or optimal policy.

7.5.13 Value Function

A value function estimates how good a state is in terms of future rewards.

It can be represented as:

\[V^\pi(s)\]

7.5.14 Q-Function

The Q-function estimates the value of taking a particular action in a particular state.

It is represented as:

\[Q^\pi(s,a)\]

where:

---------------------

Right → Q-value = 8

because it has the highest estimated long-term value.

7.5.15 Episode

An episode is one complete sequence of interactions from a starting point until a terminal condition is reached.

For a game:

Start Game

↓
Move
↓
Move
↓
Move
↓
Game Over

This is one episode.

For a robot navigation task:

Start

↓
Move
↓
Move
↓
Reach Destination

This can also represent one episode.

7.5.16 The Reinforcement Learning Loop

The basic RL loop is:

┌─────────────────────┐
│ Environment │
└──────────┬──────────┘
│
State
↓
┌─────────────────────┐
│ Agent │
└──────────┬──────────┘
│
Action
↓
┌─────────────────────┐
│ Environment │
└──────────┬──────────┘
│
Reward + State
↓
Agent

Repeated many times:

\[S_t \rightarrow A_t \rightarrow R_{t+1}, S_{t+1}\]

7.5.17 Cumulative Reward

The agent is usually interested in total future reward, not just the next reward.

Suppose an agent receives:

Step 1 → +1
Step 2 → +1
Step 3 → +10

Total reward:

\[1+1+10=12\]

However, reinforcement learning often uses a discount factor.

7.5.18 Discount Factor

The discount factor is represented by:

\[\gamma\]

where:

\[0 \leq \gamma < 1\]

The discounted return is:

\[G_t = R_{t+1} + \gamma R_{t+2}\]

For example, if:

\[\gamma=0.9\]

then future rewards are discounted.

7.5.19 Exploration vs Exploitation

One of the most important challenges in reinforcement learning is deciding between:

Exploration

Try actions that the agent does not know much about.

"Maybe this action will produce a better reward."

Exploitation

Exploration ←→ Exploitation

7.5.20 Epsilon-Greedy Strategy

A common approach is epsilon-greedy.

Let:

\[\epsilon = 0.1\]

Then approximately:

10% → Explore
90% → Exploit

This simple strategy is widely used in reinforcement learning.

7.5.21 Markov Decision Process

Many reinforcement learning problems are modeled using a Markov Decision Process (MDP).

An MDP can be represented by:

\[(S,A,P,R,\gamma)\]

where:

The Markov property means that the future depends primarily on the current state and action, rather than the entire history.

Conceptually:

Current State

+

Action

↓
Transition
↓
Next State + Reward

7.5.22 Q-Learning

Q-Learning is one of the classic reinforcement learning algorithms.

It learns the optimal action-value function:

\[Q^*(s,a)\]

The standard Q-learning update rule is:

\[Q(s,a) \leftarrow Q(s,a) +\alpha \left[ r+\gamma\max_{a'}Q(s',a') -Q(s,a) \right]\]

where:

The term:

\[r+\gamma\max_{a'}Q(s',a')\]

represents the updated estimate of future value.

7.5.23 Learning Rate

The learning rate is represented by:

\[\alpha\]

where:

\[0 < \alpha \leq 1\]

It determines how strongly new information affects existing knowledge.

High learning rate

The agent adapts quickly to new information.

Low learning rate

The agent changes its knowledge more gradually.

7.5.24 Q-Table

For small environments, Q-learning can maintain a table.

Example:

State Left Right Up Down
S1 2.1 8.4 3.2 1.0
S2 5.2 2.4 7.8 3.1
S3 1.2 4.7 2.2 9.1

For state S1, the best action is:

Right

because:

\[Q(S1,Right)=8.4\]

However, Q-tables become impractical when the state or action space becomes extremely large.

7.5.25 Deep Reinforcement Learning

State → Q-Table

we have:

State

↓
Neural Network
↓
Q-values / Policy

One famous algorithm is:

Deep Q-Network (DQN)

DQN became well known for learning to play video games directly from visual input.

7.5.26 Policy-Based Methods

Instead of learning only a value function, some algorithms directly learn a policy.

The model attempts to learn:

\[\pi(a|s)\]

Examples include:

These methods are useful when the action space or policy representation makes direct policy optimization attractive.

7.5.27 Actor-Critic Methods

Critic

Evaluates how good those actions are.

State

↓
┌──────┴──────┐
↓ ↓
Actor Critic
↓ ↓
Action Evaluation
│ │
└──────┬──────┘
↓
Learn

Popular modern algorithms include:

7.5.28 Reinforcement Learning Example — Game

S1 → Start
S2 → Near obstacle
S3 → Near goal
S4 → Goal
Actions
Left
Right
Jump
Rewards
Reach goal → +100
Hit obstacle → -50
Normal movement → -1

The agent can choose actions that maximize expected cumulative reward.

7.5.29 Real-World Applications

Robotics

RL can be used for:

Games

RL has been successfully applied to:

Safety constraints are especially important in real-world deployment.

Recommendation Systems

↓
Recommendation
↓
User Response
↓
Reward
↓
Update Policy
Resource Optimization

RL can potentially optimize:

7.5.30 Advantages of Reinforcement Learning

1. Learns Through Interaction

The agent can learn without a labeled dataset containing the correct action for every state.

2. Handles Sequential Decisions

RL is particularly useful when one decision affects future decisions.

3. Long-Term Optimization

The objective can focus on cumulative rewards rather than immediate outcomes.

4. Adaptive Behavior

An agent can potentially adapt its policy as the environment changes.

5. Suitable for Complex Decision Problems

RL is useful when finding explicit rules manually is difficult.

7.5.31 Limitations of Reinforcement Learning

1. Large Amount of Training

Many RL problems require numerous interactions or simulations.

2. Reward Design

↓
Wrong Objective
↓
Unexpected Behavior

3. Exploration Can Be Expensive

Trying poor actions can be costly or dangerous in real-world environments.

4. Training Instability

Some deep RL algorithms can be difficult to train reliably.

5. Sample Inefficiency

The agent may require many experiences to learn effectively.

6. Real-World Safety

Exploration is relatively easy in a simulation but can be dangerous with physical systems.

7.5.32 Supervised, Unsupervised and Reinforcement Learning

Feature Supervised Unsupervised Reinforcement
Training signal Labels No labels Rewards
Target Known Usually unknown Reward objective
Learning method Examples Pattern discovery Trial and error
Environment interaction Usually no Usually no Yes
Main tasks Regression, classification Clustering, PCA Sequential decision-making
Example House price prediction Customer segmentation Game playing

A simple memory trick:

Supervised

↓
Learn from Answers
Unsupervised
↓
Learn from Patterns
Reinforcement
↓
Learn from Rewards

7.5.33 Complete Reinforcement Learning Architecture

┌─────────────────┐
│ Environment │
└───────┬─────────┘
│
State + Reward
│
↓
┌─────────────────┐
│ Agent │
│ │
│ Policy / Value │
│ Function │
└───────┬─────────┘
│
Action
│
↓
┌─────────────────┐
│ Environment │
└─────────────────┘

The cycle continues:

\[S_t \rightarrow A_t \rightarrow R_{t+1},S_{t+1}\]

until the agent learns an effective policy.

7.5.34 Key Takeaways

Module 7 · Lesson 7.6

Linear Regression

7.6.1 Introduction

Linear Regression is a supervised machine learning algorithm used primarily to predict a continuous numerical value.

It assumes that the target variable has a linear relationship with one or more input features.

Examples:

The basic idea is:

Input Features

↓
Linear Regression Model
↓
Continuous Numerical Prediction

For example:

House Area → Linear Regression → Predicted House Price

7.6.2 Simple Linear Regression

When there is one independent variable, we use Simple Linear Regression.

The equation is:

\[\hat{y}=b_0+b_1x\]

where:

For example:

\[Salary = 300000 + 100000 \times Experience\]

If experience is 5 years:

\[Salary = 300000 + (100000\times5)\]

\[Salary = 800000\]

So the predicted salary is ₹8,00,000.

7.6.3 Visualizing Linear Regression

The regression model attempts to find the line that best represents the relationship between (x) and (y).

The line is called the regression line or line of best fit.

7.6.4 Independent and Dependent Variables

In:

\[\hat{y}=b_0+b_1x\]

Independent Variable

The input variable (x).

Example:

Example:

Salary

Therefore:

Experience → Salary

We are trying to understand how changes in experience are associated with changes in salary.

7.6.5 Example Dataset

Consider:

Experience Salary
1 350000
2 450000
3 550000
4 650000
5 750000

The relationship appears approximately linear.

A model might learn:

\[Salary = 250000 + 100000(Experience)\]

For 6 years:

\[Salary=250000+(100000\times6)\]

\[Salary=850000\]

Therefore:

Predicted Salary = ₹8,50,000

7.6.6 What Does the Slope Mean?

The coefficient (b_1) represents the expected change in (y) for a one-unit increase in (x).

Suppose:

\[Salary=250000+100000(Experience)\]

Here:

\[b_1=100000\]

This means that, according to the fitted model, one additional year of experience is associated with an increase of approximately ₹1,00,000 in predicted salary.

7.6.7 What Does the Intercept Mean?

The intercept (b_0) represents the model's predicted value of (y) when (x=0).

For:

\[Salary=250000+100000(Experience)\]

the intercept is:

\[b_0=250000\]

Mathematically, this means the predicted salary at zero years of experience is ₹2,50,000.

However, the intercept is not always meaningful in the real-world context, especially when (x=0) is outside the observed data range.

7.6.8 Multiple Linear Regression

When there are multiple independent variables, we use Multiple Linear Regression.

The equation becomes:

\[\hat{y}=b_0+b_1x_1+b_2x_2+\cdots+b_nx_n\]

For example:

\[Price = b_0+ b_1(Area)+ b_2(Bedrooms)+ b_3(Age)+ b_4(Parking)\]

Here the model uses several features to predict house price.

Example:

Area Bedrooms Age Parking Price
1000 2 10 1 40 L
1500 3 8 1 60 L
2000 3 5 2 85 L
2500 4 3 2 110 L

7.6.9 Regression Line and Residuals

For each observation, the model produces a predicted value.

The difference between the actual and predicted value is called the residual or error.

\[e_i=y_i-\hat{y}_i\]

where:

Example:

A good regression model attempts to keep these errors small.

7.6.10 Ordinary Least Squares

The most common method for fitting a linear regression model is Ordinary Least Squares (OLS).

The idea is to choose coefficients that minimize the sum of squared residuals.

\[SSE=\sum_{i=1}^{n}(y_i-\hat{y}_i)^2\]

The model attempts to minimize:

\[\boxed{\sum_{i=1}^{n}(y_i-\hat{y}_i)^2}\]

Why square the errors?

Because:

  1. Positive and negative errors should not cancel each other.

  2. Large errors receive greater penalty.

  3. The resulting optimization problem has useful mathematical properties.

7.6.11 Mean Squared Error

Another important metric is Mean Squared Error (MSE).

\[MSE= \frac{1}{n} \sum_{i=1}^{n}(y_i-\hat{y}_i)^2\]

A lower MSE generally indicates better predictive performance on the evaluated data.

Example:

-2, 2, 1

Squared errors:

4, 4, 1

Therefore:

\[MSE=\frac{4+4+1}{3}=3\]

7.6.12 Root Mean Squared Error

RMSE is the square root of MSE:

\[RMSE=\sqrt{MSE}\]

The advantage is that RMSE is expressed in the same units as the target variable.

For example, if the target is house price in rupees, RMSE is also expressed in rupees.

7.6.13 Mean Absolute Error

MAE is:

\[MAE= \frac{1}{n} \sum_{i=1}^{n}|y_i-\hat{y}_i|\]

Unlike MSE, MAE does not square the errors.

Example:

Therefore:

\[MAE=\frac{10+10+20}{3}=13.33\]

MAE is often easy to interpret because it represents average absolute prediction error in the target's units.

7.6.14 R² — Coefficient of Determination

measures how much of the variation in the target is explained by the regression model relative to a baseline that predicts the mean.

It is commonly written as:

\[R^2=1-\frac{SS_{res}}{SS_{tot}}\]

where:

For example:

R² = 0.80

can be interpreted as the model explaining about 80% of the variance in the target relative to the mean baseline, on the data being evaluated.

Important: a high (R^2) does not automatically mean the model is good for every purpose.

7.6.15 Adjusted R²

For multiple linear regression, adding more variables can increase ordinary (R^2), even when some variables contribute little useful information.

Adjusted R² accounts for the number of predictors and can therefore be more informative when comparing models with different numbers of features.

It is especially useful in statistical modeling when deciding whether additional predictors improve the model sufficiently.

7.6.16 Assumptions of Linear Regression

Classical linear regression relies on several important assumptions.

1. Linearity

The relationship between predictors and the expected target should be appropriately represented by a linear function.

2. Independence

Observations/errors should generally be independent in the context where ordinary regression assumptions are being applied.

3. Homoscedasticity

The variance of errors should be approximately constant across relevant levels of the predictors.

4. Normally Distributed Errors

For traditional statistical inference, residuals are often assumed to be approximately normally distributed.

This assumption is more important for confidence intervals and hypothesis tests than for obtaining predictions alone.

5. Low Multicollinearity

In multiple regression, predictors should not have problematic levels of linear dependence.

7.6.17 Multicollinearity

7.6.18 Overfitting in Linear Regression

Linear regression can also overfit, particularly when:

Example:

7.6.19 Regularization

\[Loss = SSE+\lambda\sum_j b_j^2\]

Lasso Regression

Uses an L1 penalty.

\[Loss = SSE+\lambda\sum_j |b_j|\]

Lasso can shrink some coefficients exactly to zero, making it useful for feature selection in some situations.

These techniques are especially useful when there are many predictors or multicollinearity.

7.6.20 Linear Regression Using Python

Using Scikit-learn:

from sklearn.linear_model import LinearRegression
X = [
[1],
[2],
[3],
[4],
[5]
]
y = [
350000,
450000,
550000,
650000,
750000
]
model = LinearRegression()
model.fit(X, y)
prediction = model.predict([[6]])
print("Predicted salary:", prediction[0])

The important steps are:

Data

↓
Create Model
↓
fit()
↓
Learn coefficients
↓
predict()
↓
Generate prediction

7.6.21 Inspecting Coefficients

After training:

print("Intercept:", model.intercept_)
print("Coefficient:", model.coef_)

\[Salary=250000+100000(Experience)\]

7.6.22 Multiple Linear Regression in Python

from sklearn.linear_model import LinearRegression
X = [
[1000, 2, 10],
[1500, 3, 8],
[2000, 3, 5],
[2500, 4, 3]
]
y = [
4000000,
6000000,
8500000,
11000000
]
model = LinearRegression()
model.fit(X, y)
prediction = model.predict([
[1800, 3, 6]
])
print("Predicted price:", prediction[0])

7.6.23 Train-Test Split

A model should be evaluated on data that was not used for training.

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

The test set provides an estimate of how well the model generalizes to unseen observations.

7.6.24 Evaluating a Regression Model

Scikit-learn provides several useful metrics.

from sklearn.metrics import (
mean_absolute_error,
mean_squared_error,
r2_score
)
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = mse ** 0.5
r2 = r2_score(y_test, y_pred)
print("MAE:", mae)
print("MSE:", mse)
print("RMSE:", rmse)
print("R2:", r2)

Interpretation:

Metric General Interpretation
MAE Average absolute error
MSE Average squared error
RMSE Error in target units
Variance explained relative to mean baseline

7.6.25 When Should You Use Linear Regression?

Linear regression is a good candidate when:

7.6.26 When Linear Regression May Not Be Appropriate

Linear regression may perform poorly when:

For nonlinear problems, alternatives may include:

7.6.27 Linear Regression vs Logistic Regression

These algorithms are frequently confused.

Linear Regression Logistic Regression
Regression algorithm Classification algorithm
Predicts continuous values Predicts class probabilities/classes
Output can be any real value Probability typically between 0 and 1
Example: Salary Example: Churn
Common metrics: MAE, RMSE, R² Accuracy, Precision, Recall, F1, ROC-AUC

Example:

Linear Regression

Experience → ₹8,50,000

versus:

Logistic Regression

Customer → 0.87 probability of churn

7.6.28 Practical Example — Sales Prediction

Suppose a company wants to predict monthly sales using:

\[Sales = b_0+ b_1(Advertising)+ b_2(Salespeople)+ b_3(Discount)+ b_4(Visitors)+ b_5(PreviousSales)\]

The workflow is:

Historical Sales Data

↓
Data Cleaning
↓
Feature Engineering
↓
Train/Test Split
↓
Linear Regression
↓
Prediction
↓
MAE / RMSE / R²
↓
Business Evaluation

The company can then use the model to estimate future sales and support planning decisions.

7.6.29 Key Takeaways

\[\hat{y}=b_0+b_1x\]

\[\hat{y}=b_0+b_1x_1+\cdots+b_nx_n\]

Module 7 · Lesson 7.7

Logistic Regression

7.7.1 Introduction

Logistic Regression is a supervised machine learning algorithm primarily used for classification problems.

Despite the word "Regression" in its name, Logistic Regression is generally used to predict the probability of a class and then assign an observation to a class based on a decision threshold.

Typical applications include:

The basic workflow is:

Input Features

↓
Linear Combination
↓
Sigmoid Function
↓
Probability
↓
Decision Threshold
↓
Predicted Class

7.7.2 Why Not Use Linear Regression for Classification?

Suppose we want to predict whether a customer will churn:

0 → No Churn
1 → Churn

Values such as -0.4 and 1.3 cannot represent valid probabilities.

Logistic Regression solves this problem by passing a linear combination of features through the sigmoid function, which maps any real-valued input into the interval:

\[0 < p < 1\]

7.7.3 Binary Classification

The most common form of Logistic Regression is binary classification.

There are two possible classes:

0 → Negative Class
1 → Positive Class

\[P(y=1|x)\]

which means:

The probability that the observation belongs to class 1 given its input features.

7.7.4 The Logistic Regression Equation

First, Logistic Regression calculates a linear combination:

\[z=b_0+b_1x_1+b_2x_2+\cdots+b_nx_n\]

Then it applies the sigmoid function:

\[\boxed{ \sigma(z)=\frac{1}{1+e^{-z}} }\]

Therefore:

\[P(y=1|x)=\frac{1}{1+e^{-z}}\]

where:

\[z=b_0+b_1x_1+\cdots+b_nx_n\]

7.7.5 Sigmoid Function

The sigmoid function converts any real-valued number into a value between 0 and 1.

Important properties:

For example:

(z) Sigmoid (P)
-5 ≈ 0.007
-2 ≈ 0.119
0 0.500
2 ≈ 0.881
5 ≈ 0.993

7.7.6 Example

Suppose a Logistic Regression model predicts whether a customer will churn.

The model calculates:

\[z=-2+0.05(Age)-0.00001(Income)+0.8(SupportCalls)\]

\[z=-2+(0.05)(30)-(0.00001)(50000)+(0.8)(3)\]

\[z=-2+1.5-0.5+2.4\]

\[z=1.4\]

Applying the sigmoid function:

\[P=\frac{1}{1+e^{-1.4}}\]

Approximately:

\[P\approx0.802\]

So the model estimates an approximately 80.2% probability of churn.

7.7.7 Probability vs Class

\[Threshold=0.5\]

we can classify:

Probability ≥ 0.5 → Class 1
Probability < 0.5 → Class 0

Therefore:

0.80 → Churn
0.30 → No Churn

The threshold does not have to be 0.5. It can be adjusted based on the business objective.

7.7.8 Decision Boundary

The decision boundary separates observations predicted as different classes.

For a binary classifier using a threshold of 0.5:

\[P(y=1|x)=0.5\]

Since:

\[\sigma(0)=0.5\]

the corresponding boundary occurs at:

\[z=0\]

Therefore:

\[b_0+b_1x_1+\cdots+b_nx_n=0\]

This creates a linear decision boundary in the original feature space.

7.7.9 Odds

Logistic Regression can also be understood using odds.

If:

\[p=P(y=1|x)\]

then:

\[Odds=\frac{p}{1-p}\]

For example, if:

\[p=0.8\]

then:

\[Odds=\frac{0.8}{0.2}=4\]

This means the odds of class 1 relative to class 0 are 4:1.

7.7.10 Log-Odds / Logit

Taking the natural logarithm of the odds gives the logit:

\[\log\left(\frac{p}{1-p}\right)\]

Logistic Regression assumes that the log-odds are a linear function of the predictors:

\[\boxed{ \log\left(\frac{p}{1-p}\right) b_0+b_1x_1+\cdots+b_nx_n }\]

This is one of the most important mathematical ideas behind Logistic Regression.

7.7.11 Interpreting Coefficients

Suppose the model is:

\[\log\left(\frac{p}{1-p}\right) -2+0.5x\]

The coefficient is:

\[b_1=0.5\]

A one-unit increase in (x) increases the log-odds by 0.5.

The corresponding odds ratio is:

\[e^{0.5}\approx1.65\]

So, holding other variables constant, a one-unit increase in (x) multiplies the odds of class 1 by approximately 1.65.

7.7.12 Loss Function

Logistic Regression commonly uses Log Loss, also called Binary Cross-Entropy.

For one observation:

\[L= -[y\log(p)+(1-y)\log(1-p)]\]

For (n) observations:

\[J= -\frac{1}{n} \sum_{i=1}^{n} [ y_i\log(p_i) + (1-y_i)\log(1-p_i) ]\]

The model attempts to minimize this loss.

The important idea is that confidently incorrect predictions receive a large penalty.

7.7.13 Why Use Log Loss?

This is a good prediction.

Model B

Predicted probability = 0.01

This is a very bad and highly confident prediction.

Log loss heavily penalizes Model B.

Therefore, Logistic Regression learns not only which class to predict but also useful probability estimates.

7.7.14 Training Logistic Regression

↓
Linear Combination
↓
Sigmoid
↓
Predicted Probabilities
↓
Log Loss
↓
Optimization
↓
Updated Coefficients
↓
Repeat

Unlike ordinary least squares Linear Regression, Logistic Regression does not normally estimate coefficients by minimizing squared error. Optimization methods such as gradient-based algorithms are commonly used.

7.7.15 Gradient Descent Intuition

↓
Calculate Predictions
↓
Calculate Loss
↓
Calculate Gradients
↓
Update Coefficients
↓
Repeat

A simplified update can be expressed as:

\[\theta_{new} \theta_{old} \alpha\nabla J(\theta)\]

where:

In practice, Scikit-learn handles this optimization for us.

7.7.16 Binary Logistic Regression Using Python

from sklearn.linear_model import LogisticRegression
X = [
[20, 30000],
[25, 40000],
[30, 50000],
[35, 60000],
[40, 80000],
[45, 100000]
]
y = [
1,
1,
1,
0,
0,
0
]
model = LogisticRegression()
model.fit(X, y)
prediction = model.predict([[32, 55000]])
print("Prediction:", prediction)

The model learns the relationship between the features and the binary target.

7.7.17 Predicting Probabilities

Often, probability is more useful than just the predicted class.

Use:

probability = model.predict_proba([[32, 55000]])
print(probability)

The output has two probabilities:

\[Probability of Class 0, Probability of Class 1\]

For example:

\[0.18, 0.82\]

This means:

Class 0 → 18%
Class 1 → 82%

Therefore, with a 0.5 threshold:

Prediction → Class 1

7.7.18 Complete Scikit-learn Example

A more realistic workflow:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import (
    accuracy_score,
    precision_score,
    recall_score,
    f1_score,
    roc_auc_score
)
# Load data
df = pd.read_csv("customers.csv")
# Features
X = df[
    [
        "Age",
        "MonthlyCharges",
        "Tenure",
        "SupportCalls"
]
]
# Target
y = df["Churn"]
# Train-test split
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)
# Pipeline
pipeline = Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression())
])
# Train
pipeline.fit(X_train, y_train)
# Predictions
y_pred = pipeline.predict(X_test)
# Probabilities
y_prob = pipeline.predict_proba(X_test)[:, 1]
# Evaluation
print("Accuracy:", accuracy_score(y_test, y_pred))
print("Precision:", precision_score(y_test, y_pred))
print("Recall:", recall_score(y_test, y_pred))
print("F1:", f1_score(y_test, y_pred))
print("ROC-AUC:", roc_auc_score(y_test, y_prob))

7.7.19 Why Feature Scaling Can Be Important

Logistic Regression can benefit from feature scaling, particularly when predictors have very different numerical ranges.

For example:

Age → 20–70
Annual Income → 20,000–2,000,000

Scaling puts features on comparable numerical scales.

A common approach is:

from sklearn.preprocessing import StandardScaler

and then:

StandardScaler()

Using a Scikit-learn Pipeline ensures that the transformation learned from the training data is consistently applied when making predictions.

7.7.20 Regularization

Logistic Regression commonly uses regularization to reduce overfitting.

Two common forms are:

L2 Regularization

Penalizes the squared magnitude of coefficients.

\[Loss = LogLoss+\lambda\sum_j b_j^2\]

L1 Regularization

Penalizes the absolute magnitude of coefficients.

\[Loss = LogLoss+\lambda\sum_j |b_j|\]

L1 regularization can drive some coefficients to exactly zero, which can make it useful for feature selection.

7.7.21 The C Parameter in Scikit-learn

↓
Stronger regularization
Large C
↓
Weaker regularization

Example:

LogisticRegression(C=0.1)

versus:

LogisticRegression(C=10)

The optimal value should generally be selected using validation or cross-validation rather than guessed.

7.7.22 Multiclass Logistic Regression

Logistic Regression can also be used when there are more than two classes.

For example:

0 → Low
1 → Medium
2 → High

Scikit-learn supports multiclass classification through appropriate solver/model configurations.

Common conceptual approaches include:

One-vs-Rest

Multinomial Logistic Regression

Model the probabilities of all classes jointly.

For (K) classes, the softmax function is commonly used:

\[P(y=k|x) \frac{e^{z_k}} {\sum_{j=1}^{K}e^{z_j}}\]

The probabilities across all classes sum to 1.

7.7.23 Logistic Regression Evaluation

Because Logistic Regression is a classification algorithm, common metrics include:

Accuracy

\[Accuracy= \frac{TP+TN}{TP+TN+FP+FN}\]

Precision

\[Precision= \frac{TP}{TP+FP}\]

Recall

\[Recall= \frac{TP}{TP+FN}\]

F1 Score

\[F1= 2\frac{Precision\times Recall} {Precision+Recall}\]

ROC-AUC

Measures ranking/discrimination performance across classification thresholds.

These metrics are covered in more detail in Sections 7.24–7.28.

7.7.24 Confusion Matrix

For binary classification:

Actual Positive Actual Negative
Predicted Positive TP FP
Predicted Negative FN TN

Where:

Example — fraud detection:

TP → Fraud correctly detected
TN → Genuine transaction correctly accepted
FP → Genuine transaction incorrectly flagged
FN → Fraud incorrectly missed

7.7.25 Choosing the Classification Threshold

The default threshold is often 0.5, but this is not universally optimal.

Suppose a fraud model predicts:

Transaction A → 0.40
Transaction B → 0.60
Transaction C → 0.85

With threshold 0.5:

A → Not Fraud
B → Fraud
C → Fraud
A → Fraud
B → Fraud
C → Fraud

This may increase recall but can also increase false positives.

The appropriate threshold depends on the business cost of different errors.

7.7.26 Advantages of Logistic Regression

1. Simple

It is relatively easy to understand and implement.

2. Fast

Training and prediction can be efficient for many datasets.

3. Interpretable

Coefficients and odds ratios can provide useful insight.

4. Probability Estimates

It naturally produces class probabilities.

5. Strong Baseline

It is often a good first model for classification problems.

6. Regularization

L1 and L2 regularization can help control overfitting.

7.7.27 Limitations

1. Linear Decision Boundary

Basic Logistic Regression assumes a linear relationship between predictors and the log-odds.

It may struggle with highly nonlinear relationships.

2. Feature Engineering May Be Required

Interactions or nonlinear transformations may need to be added manually.

3. Sensitive to Multicollinearity

Highly correlated features can make coefficient interpretation unstable.

4. Outliers Can Affect the Model

Extreme observations can influence coefficient estimates.

5. Complex Relationships

Tree-based models and boosting algorithms may perform better when relationships are highly nonlinear.

7.7.28 Linear Regression vs Logistic Regression

Feature Linear Regression Logistic Regression
Main purpose Regression Classification
Output Continuous value Probability/class
Core transformation Linear Linear + sigmoid
Typical target Price Churn
Loss Often MSE/related objectives Log loss
Common metrics MAE, RMSE, R² Precision, Recall, F1, ROC-AUC
Output range Any real value Probability between 0 and 1
Example ₹85 lakh 0.82 churn probability

A simple memory rule:

Linear Regression predicts "how much"; Logistic Regression predicts "which class/probability."

7.7.29 Real-World Example — Customer Churn

↓
Data Cleaning
↓
Feature Engineering
↓
Train/Test Split
↓
Feature Scaling
↓
Logistic Regression
↓
Probability
↓
Threshold
↓
Churn / No Churn

The business may classify this customer as high risk and consider an appropriate retention action.

7.7.30 Interview Questions

Q1. Is Logistic Regression a regression or classification algorithm?

It is primarily a classification algorithm, despite its name.

Q2. Why is the sigmoid function used?

It converts the linear model output into a value between 0 and 1 that can be interpreted as a probability for binary classification.

Q3. What is the output of Logistic Regression?

It can provide a class probability, which can then be converted into a class using a threshold.

Q4. What is the default classification threshold commonly used?

Typically 0.5, although the threshold should be selected based on the problem and error costs.

Q5. What loss function is commonly used?

Log loss / binary cross-entropy for binary classification.

Q6. What is the difference between probability and prediction?

Probability is a continuous score such as:

0.83

Prediction is the resulting class after applying a threshold:

Class 1

Q7. What is regularization?

A technique that penalizes model complexity, commonly through L1 or L2 penalties, to reduce overfitting.

Q8. What does C mean in Scikit-learn Logistic Regression?

It controls the inverse of regularization strength.

Q9. Can Logistic Regression handle multiple classes?

Yes. It can be used for multiclass classification.

Q10. Why might Logistic Regression perform poorly?

It may perform poorly when the relationship between features and the log-odds is strongly nonlinear or when the feature representation is inadequate.

7.7.31 Key Takeaways

\[P(y=1|x)=\frac{1}{1+e^{-z}}\]

where:

\[z=b_0+b_1x_1+\cdots+b_nx_n\]

Module 7 · Lesson 7.8

Decision Trees

7.8.1 Introduction

A Decision Tree is a supervised machine learning algorithm used for both classification and regression.

It makes predictions by repeatedly asking questions about the input features and following the corresponding branches until it reaches a final prediction.

The basic idea is similar to a flowchart:

Age > 30?

/ \

Yes No

/ \

Income > 50K? Churn

/ \

Yes No

/ \

No Churn Churn

A decision tree consists of:

7.8.2 Simple Example

Suppose a bank wants to determine whether a customer is likely to receive a loan.

The model may learn rules such as:

Credit Score > 700?

/ \

Yes No

/ \

Income > 50K? Reject

/ \

Yes No

/ \

Approve Reject

The model is effectively learning a series of decision rules from historical data.

7.8.3 Why Is It Called a Decision Tree?

The structure looks like a tree turned upside down:

Root

│
┌────────┴────────┐
│ │
Node Node
/ \ / \
/ \ / \
Leaf Leaf Leaf Leaf

It starts at a root node and branches into different decisions until it reaches a leaf.

7.8.4 Main Components

1. Root Node

The first decision in the tree.

Example:

Credit Score > 700?

The root is normally selected because it provides a useful split according to the chosen splitting criterion.

2. Internal Node

An internal node represents another decision.

Example:

Income > ₹50,000?

3. Branch

4. Leaf Node

A leaf represents the final prediction.

Example:

7.8.5 Classification Trees

A classification tree predicts a categorical target.

Examples:

Example:

Support Calls > 5?

/ \

Yes No

/ \

High Risk Low Risk

The leaf nodes contain class predictions.

7.8.6 Regression Trees

A regression tree predicts a continuous numerical value.

Example:

Area > 1500?

/ \

Yes No

/ \

₹80 Lakhs ₹45 Lakhs

The leaf prediction is typically based on the target values of training observations that reach that leaf, commonly their mean for standard squared-error regression trees.

7.8.7 How Does a Decision Tree Learn?

Suppose we have customer churn data:

Age Monthly Charges Support Calls Churn
25 800 5 Yes
42 400 1 No
31 700 4 Yes
50 350 0 No
29 750 6 Yes

The algorithm searches for feature-based splits that make the resulting groups as pure or useful as possible.

For example:

Support Calls > 3?

/ \

Yes No

/ \

Mostly Yes Mostly No

The algorithm continues splitting until stopping conditions are reached.

7.8.8 What Is a Split?

The algorithm evaluates possible splits and chooses one that improves the chosen impurity or loss criterion.

7.8.9 Impurity

The objective is generally to create child nodes that are more homogeneous.

Two important impurity measures are:

7.8.10 Gini Impurity

Gini impurity is:

\[\boxed{ Gini=1-\sum_{i=1}^{K}p_i^2 }\]

where:

For a binary classification problem:

\[Gini=1-(p_1^2+p_2^2)\]

Example

\[Gini=1-(0.8^2+0.2^2)\]

\[=1-(0.64+0.04)\]

\[=0.32\]

If a node contains only one class:

\[Gini=1-(1^2+0^2)=0\]

So:

Lower Gini impurity means a purer node.

7.8.11 Entropy

Another splitting criterion is Entropy.

\[\boxed{ Entropy=-\sum_{i=1}^{K}p_i\log_2(p_i) }\]

For a binary classification problem:

\[Entropy= -[p\log_2(p)+(1-p)\log_2(1-p)]\]

\[Entropy=0\]

then entropy is at its maximum for binary classification:

\[Entropy=1\]

Therefore:

Lower entropy generally means a purer node.

7.8.12 Information Gain

Information Gain measures how much a split reduces entropy.

\[\boxed{ IG=Entropy(parent) -\sum_j \frac{N_j}{N} Entropy(child_j) }\]

where:

↓
Split
↓
Child Entropy
↓
Entropy Reduction
↓
Information Gain

7.8.13 Gini vs Entropy

Gini Entropy
Measures impurity Measures uncertainty
Common default in many tree implementations Alternative splitting criterion
Usually computationally simpler Uses logarithms
Lower is better Lower is better
Often produces similar trees Often produces similar trees

In practice, both can work well.

7.8.14 How a Tree Is Built

A simplified tree-building process is:

Start with all training data

↓
Find candidate splits
↓
Evaluate split quality
↓
Choose best split
↓
Create child nodes
↓
Repeat recursively
↓
Stop according to constraints

The process is recursive.

Each child node can be split again.

7.8.15 Stopping Criteria

A tree cannot grow indefinitely.

Common stopping conditions include:

7.8.16 Maximum Depth

max_depth controls how deep the tree can grow.

Example:

from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(
max_depth=3,
random_state=42
)

A small depth:

Simple Tree

↓
Less complexity

A large depth:

Complex Tree

↓
Higher risk of overfitting

7.8.17 Overfitting in Decision Trees

The tree may have memorized training observations rather than learning general patterns.

The resulting tree may contain many branches:

Root

├── Node
│ ├── Node
│ │ ├── Leaf
│ │ └── Leaf
│ └── Node
│ ├── Leaf
│ └── Leaf
└── Node
├── ...
└── ...

7.8.18 Controlling Overfitting

Common approaches include:

1. Limit Maximum Depth

DecisionTreeClassifier(max_depth=5)

2. Increase Minimum Samples per Leaf

DecisionTreeClassifier(min_samples_leaf=10)

3. Increase Minimum Samples for Splitting

DecisionTreeClassifier(min_samples_split=20)

4. Pruning

Remove unnecessary branches from an already grown tree.

5. Cross-Validation

Compare different hyperparameter settings on validation folds.

7.8.19 Pruning

Pruning removes branches that provide insufficient useful improvement.

There are two broad approaches:

Pre-Pruning

Post-Pruning

7.8.20 Decision Tree Classification Using Python

from sklearn.tree import DecisionTreeClassifier
X = [
[25, 5],
[42, 1],
[31, 4],
[50, 0],
[29, 6],
[45, 1]
]
y = [
1,
0,
1,
0,
1,
0
]
model = DecisionTreeClassifier(
max_depth=3,
random_state=42
)
model.fit(X, y)
prediction = model.predict([
[35, 3]
])
print("Prediction:", prediction)

Here:

Feature 1 → Age
Feature 2 → Support Calls

Target:

1 → Churn
0 → No Churn

7.8.21 Decision Tree Regression Using Python

For a continuous target:

from sklearn.tree import DecisionTreeRegressor
X = [
[1000],
[1500],
[2000],
[2500]
]
y = [
4000000,
6000000,
8500000,
11000000
]
model = DecisionTreeRegressor(
max_depth=3,
random_state=42
)
model.fit(X, y)
prediction = model.predict([
[1800]
])
print("Predicted price:", prediction[0])

7.8.22 Visualizing a Decision Tree

Scikit-learn can display the structure of a trained tree.

from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 8))
plot_tree(
model,
filled=True,
feature_names=["Age", "SupportCalls"],
class_names=["No Churn", "Churn"]
)
plt.show()

The visualization can show:

7.8.23 Feature Importance

Decision Trees can provide an estimate of feature importance.

print(model.feature_importances_)

Example:

Age → 0.25
SupportCalls → 0.60
Income → 0.15

This suggests that SupportCalls contributed more to the tree's impurity reduction than the other features.

However, feature importance should be interpreted carefully, particularly with correlated features.

7.8.24 Do Decision Trees Require Feature Scaling?

Generally, Decision Trees do not require feature scaling.

For example, these features can be used directly:

Age → 25
Annual Income → 800000
Experience → 5

Unlike distance-based algorithms such as KNN or K-Means, tree splitting depends on thresholds rather than distances.

Therefore, StandardScaler is generally not necessary for a basic Decision Tree.

7.8.25 Handling Nonlinear Relationships

↓
Churn

does not have a simple linear relationship.

A Decision Tree can learn rules such as:

Age < 25

↓
High churn
25 ≤ Age < 40
↓
Medium churn
Age ≥ 40
↓
Low churn

This makes trees useful for problems where linear models may be too restrictive.

7.8.26 Handling Feature Interactions

↓
Yes
↓

Credit Score > 700?

↓
Yes
↓
Approve

The effect of credit score can therefore depend on income.

This type of interaction often requires explicit feature engineering in simpler linear models.

7.8.27 Advantages of Decision Trees

1. Easy to Understand

The learned model resembles a sequence of human-readable rules.

2. Works for Classification and Regression

The same general approach supports both tasks.

3. Captures Nonlinear Relationships

No assumption of a globally linear relationship is required.

4. Captures Interactions

Feature interactions can be learned automatically.

5. Little Preprocessing

Trees generally do not require feature scaling.

6. Handles Numerical Features

Continuous variables can be split using thresholds.

7. Can Be Interpretable

Small trees can be visualized and explained relatively easily.

7.8.28 Limitations of Decision Trees

1. Overfitting

Deep trees can memorize training data.

2. Instability

Small changes in training data can sometimes produce substantially different trees.

3. Greedy Learning

Standard tree algorithms generally choose locally optimal splits rather than globally optimizing the entire tree.

4. Large Trees Become Difficult to Interpret

A very deep tree may be as difficult to understand as a complex model.

5. Single Trees Can Be Less Accurate

Ensemble methods such as Random Forest and Gradient Boosting often provide better predictive performance.

6. Regression Trees Produce Piecewise Predictions

A basic regression tree does not smoothly extrapolate like a linear regression model.

7.8.29 Decision Tree vs Linear Regression

Decision Tree Linear Regression
Classification and regression Primarily regression
Can model nonlinear patterns Assumes linear relationship
Threshold-based splits Equation-based
Little scaling required Scaling may be useful depending on context
Can model interactions naturally Interactions often need explicit terms
Can overfit deeply Can underfit nonlinear relationships
Easy to interpret when small Coefficients are directly interpretable

7.8.30 Decision Tree vs Logistic Regression

Decision Tree Logistic Regression
Classification and regression Primarily classification
Nonlinear decision boundaries possible Linear decision boundary in feature space
Rule-based structure Probability model
Feature scaling usually unnecessary Scaling can help optimization
Captures interactions naturally Often requires feature engineering
Can overfit easily Regularization helps control complexity

7.8.31 Practical Example — Customer Churn

/ \

Yes No

/ \

Support Calls > 3? Low Risk

/ \

Yes No

/ \

High Risk Medium Risk

The business can interpret these rules and identify groups of customers with higher churn risk.

7.8.32 Important Hyperparameters

Common Decision Tree hyperparameters include:

Parameter Purpose
criterion Measures split quality
max_depth Maximum tree depth
min_samples_split Minimum samples required to split
min_samples_leaf Minimum samples in a leaf
max_leaf_nodes Maximum number of leaf nodes
max_features Number of features considered for splitting
ccp_alpha Cost-complexity pruning strength

7.8.33 Example with Train-Test Split

from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)
model = DecisionTreeClassifier(
max_depth=4,
random_state=42
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

This provides a basic workflow:

Data

↓
Train/Test Split
↓
Decision Tree
↓
Training
↓
Prediction
↓
Evaluation

7.8.34 Decision Trees and Random Forest

│
┌───────────┼───────────┐
↓ ↓ ↓
Tree 1 Tree 2 Tree 3
↓ ↓ ↓
└───────────┼───────────┘
↓
Final Prediction

Random Forest is covered in Section 7.9.

7.8.35 Key Takeaways

Module 7 · Lesson 7.9

Random Forest

7.9.1 Introduction

Random Forest is a supervised machine learning algorithm that combines multiple Decision Trees to produce a more robust and accurate prediction.

It is an ensemble learning algorithm.

↓
┌─────────────┼─────────────┐
↓ ↓ ↓
Tree 1 Tree 2 Tree 3
↓ ↓ ↓
Prediction Prediction Prediction
└─────────────┼─────────────┘
↓
Majority Vote
↓
Final Class

For regression, the predictions of the trees are typically averaged.

7.9.2 Why Random Forest?

A single Decision Tree can be powerful but has an important weakness:

Training Accuracy → 100%
Test Accuracy → 72%

7.9.3 What Does "Random" Mean?

Random Forest introduces randomness in two major ways:

1. Random Samples of Training Data

Each tree is trained on a randomly generated sample of the training observations.

This is called Bootstrap Sampling.

2. Random Subset of Features

When deciding a split, a tree considers only a random subset of available features.

This makes the trees more diverse.

Therefore:

Random Data Samples

+

Random Feature Subsets

↓
Different Decision Trees
↓
Combined Prediction

7.9.4 What Is an Ensemble?

An ensemble combines multiple models to produce a final prediction.

Instead of:

One Model → Prediction

we use:

Model 1 ─┐
Model 2 ─┤
Model 3 ─┤
Model 4 ─┤→ Combined Prediction
Model 5 ─┘

Random Forest is an example of bagging, short for Bootstrap Aggregating.

7.9.5 Random Forest for Classification

Suppose five trees predict whether a transaction is fraudulent.

Tree Prediction
Tree 1 Fraud
Tree 2 Fraud
Tree 3 Not Fraud
Tree 4 Fraud
Tree 5 Not Fraud

Votes:

Fraud → 3 votes
Not Fraud → 2 votes

Final prediction:

Fraud

This is majority voting.

7.9.6 Random Forest for Regression

For regression, suppose five trees predict a house price:

Tree Prediction
Tree 1 ₹80 L
Tree 2 ₹85 L
Tree 3 ₹82 L
Tree 4 ₹88 L
Tree 5 ₹85 L

The Random Forest prediction is approximately the average:

\[Prediction= \frac{80+85+82+88+85}{5}\]

\[=84\]

Therefore:

Predicted Price ≈ ₹84 L

7.9.7 Bootstrap Sampling

Notice that:

Another tree may receive:

B D D A E

Thus each tree sees a somewhat different training dataset.

7.9.8 Why Sampling Helps

If every tree were trained on exactly the same data with exactly the same feature choices, many trees could become very similar.

Then combining them would provide limited benefit.

Bootstrap sampling creates diversity:

Dataset

│
├── Bootstrap Sample 1 → Tree 1
├── Bootstrap Sample 2 → Tree 2
├── Bootstrap Sample 3 → Tree 3
└── Bootstrap Sample 4 → Tree 4

Different trees learn somewhat different patterns.

7.9.9 Random Feature Selection

At a particular tree split, the algorithm might consider only:

7.9.10 The Random Forest Algorithm

A simplified process is:

1. Start with training dataset
2. Create bootstrap sample
3. Build Decision Tree
4. At each split, randomly select features
5. Find best split among selected features
6. Grow tree
7. Repeat many times
8. Combine predictions

9. Final prediction

7.9.11 Classification Algorithm

For classification:

\[\hat{y} mode( T_1(x),T_2(x),...,T_n(x) )\]

where:

The final class is typically the one receiving the most votes.

7.9.12 Regression Algorithm

For regression:

\[\hat{y} \frac{1}{n} \sum_{i=1}^{n}T_i(x)\]

The final prediction is the average of the individual tree predictions.

7.9.13 Important Hyperparameters

RandomForestClassifier(
n_estimators=100
)
max_depth=10

Limiting depth can reduce overfitting.

max_features

Controls how many features are considered when looking for a split.

Example:

7.9.14 Random Forest Classification in Python

from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=100,
max_depth=10,
random_state=42
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

The key operation is:

model.fit(X_train, y_train)

which trains the forest.

7.9.15 Complete Classification Example

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import (
    accuracy_score,
    precision_score,
    recall_score,
    f1_score
)
df = pd.read_csv("customers.csv")
X = df[
    [
        "Age",
        "Tenure",
        "MonthlyCharges",
        "SupportCalls"
]
]
y = df["Churn"]
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)
model = RandomForestClassifier(
n_estimators=200,
max_depth=10,
random_state=42
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
print("Precision:", precision_score(y_test, y_pred))
print("Recall:", recall_score(y_test, y_pred))
print("F1:", f1_score(y_test, y_pred))

7.9.16 Random Forest Regression

For continuous targets, use RandomForestRegressor.
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(
n_estimators=200,
max_depth=10,
random_state=42
)
model.fit(X_train, y_train)
predictions = model.predict(X_test)

Evaluation can use:

from sklearn.metrics import (
mean_absolute_error,
mean_squared_error,
r2_score
)
mae = mean_absolute_error(y_test, predictions)
mse = mean_squared_error(y_test, predictions)
rmse = mse ** 0.5
r2 = r2_score(y_test, predictions)
print("MAE:", mae)
print("RMSE:", rmse)
print("R2:", r2)

7.9.17 Feature Importance

Random Forest can estimate feature importance.

importance = model.feature_importances_
for feature, value in zip(X.columns, importance):
print(feature, value)

Example:

This suggests that SupportCalls contributed more to the forest's split-based importance measure than the other listed features.

However, feature importance should not automatically be interpreted as causal importance.

7.9.18 Why Random Forest Usually Does Not Need Scaling

Therefore, unlike KNN or K-Means, Random Forest generally does not require feature scaling.

For example, these can be used without standardization:

Age → 25
Income → 850000
Balance → 120000

7.9.19 Random Forest and Overfitting

↓
Tree 1 ─┐
Tree 2 ─┤
Tree 3 ─┤
Tree 4 ─┤
Tree 5 ─┘
↓
Aggregation
↓
More Stable Model

However, Random Forest is not immune to overfitting.

Very complex trees, noisy features, extreme parameter choices, or insufficient data can still lead to poor generalization.

7.9.20 Bias-Variance Perspective

Random Forest is particularly effective because averaging many sufficiently diverse trees can reduce variance.

A simplified view:

Single Decision Tree

↓
High Variance
↓
Random Forest
↓
Variance Reduction

The randomization and aggregation make the individual trees less correlated.

This is a major reason Random Forest often performs better than a single Decision Tree.

7.9.21 Out-of-Bag (OOB) Evaluation

Because bootstrap sampling is used, not every training observation is included in every tree's bootstrap sample.

The observations not selected for a particular tree are called out-of-bag (OOB) observations for that tree.

These can be used to estimate model performance without requiring a separate validation set in some situations.

In Scikit-learn:

model = RandomForestClassifier(
n_estimators=200,
oob_score=True,
random_state=42
)
model.fit(X_train, y_train)
print(model.oob_score_)

OOB evaluation can be useful as an internal performance estimate.

However, a separate test set is still valuable for final unbiased evaluation.

7.9.22 Random Forest vs Decision Tree

Decision Tree Random Forest
One tree Many trees
High variance possible Usually lower variance
Easier to visualize Harder to visualize
Faster to train for one tree More computationally expensive
Can easily overfit Generally more robust
Single prediction Aggregated prediction
Less stable More stable

Simple analogy

Think of a Decision Tree as asking one expert.

Random Forest is like asking hundreds of experts and taking their combined opinion.

7.9.23 Random Forest vs Logistic Regression

Random Forest Logistic Regression
Tree-based ensemble Linear classification model
Nonlinear relationships Linear decision boundary
Interactions learned automatically Often need explicit feature engineering
Scaling generally unnecessary Scaling can help optimization
More complex Simpler
Less directly interpretable More directly interpretable
Often strong predictive performance Strong baseline

7.9.24 Random Forest vs Gradient Boosting

Both use multiple trees, but they are built differently.

Random Forest

Trees are generally trained independently/in parallel and their predictions are aggregated.

Tree 1 ─┐
Tree 2 ─┤
Tree 3 ─┤ → Aggregate
Tree 4 ─┤
Tree 5 ─┘
Gradient Boosting

Trees are built sequentially, with later trees focusing on errors or residual structure left by earlier trees.

Tree 1

↓
Errors
↓
Tree 2
↓
Errors
↓
Tree 3
↓
Final Model

XGBoost, LightGBM, and CatBoost are important gradient boosting algorithms covered later in this module.

7.9.25 Advantages of Random Forest

1. Strong Predictive Performance

It often performs well across a wide range of tabular datasets.

2. Handles Nonlinear Relationships

No global linearity assumption is required.

3. Captures Feature Interactions

Interactions can be learned automatically.

4. Less Sensitive to Overfitting Than a Single Tree

Aggregation reduces variance in many settings.

5. Minimal Preprocessing

Feature scaling is generally unnecessary.

6. Handles Many Features

It can work effectively with relatively large feature sets.

7. Classification and Regression

Both tasks are supported.

8. Provides Feature Importance

Useful for exploratory analysis, although importance measures require careful interpretation.

7.9.26 Limitations of Random Forest

1. Less Interpretable

Hundreds of trees are much harder to explain than one small tree.

2. Computational Cost

Large forests require more memory and computation.

3. Prediction Can Be Slower

Compared with a single small tree or simple linear model.

4. Large Model Size

Storing many trees can increase memory usage.

5. Not Always the Best Model

Gradient boosting methods can outperform Random Forest on some structured/tabular datasets.

6. Feature Importance Can Be Misleading

Simple impurity-based importance can favor certain types of features, especially high-cardinality or continuous variables.

7.9.27 Important Hyperparameter Tuning

Suppose we want to find the best configuration.

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
params = {
"n_estimators": [100, 200],
"max_depth": [5, 10, None],
"min_samples_split": [2, 10],
"min_samples_leaf": [1, 5]
}
grid = GridSearchCV(
RandomForestClassifier(random_state=42),
params,
cv=5,
scoring="f1"
)
grid.fit(X_train, y_train)
print(grid.best_params_)

The best configuration should be selected based on an appropriate validation strategy and metric.

7.9.28 Practical Example — Fraud Detection

↓
Data Cleaning
↓
Feature Engineering
↓
Train/Test Split
↓
Random Forest
↓
Predicted Probability
↓
Threshold
↓
Fraud / Not Fraud
↓

Precision / Recall / F1 / ROC-AUC

For fraud detection, accuracy alone may be misleading because fraud is often a minority class.

7.9.29 Practical Example — Customer Churn

Random Forest can learn rules such as:

Short Tenure

+

High Monthly Charges

+

Many Support Calls

↓
Higher Churn Risk

The advantage is that the model does not require us to manually specify all possible interactions.

7.9.30 Interview Questions

Q1. What is Random Forest?

Random Forest is an ensemble algorithm that combines multiple Decision Trees using bootstrap sampling and randomized feature selection.

Q2. Is Random Forest supervised or unsupervised?

It is a supervised learning algorithm.

Q3. Can Random Forest perform regression?

Yes. RandomForestRegressor is used for regression.

Q4. What is bagging?

Bootstrap Aggregating: train models on bootstrap samples and combine their predictions.

Q5. Why are random features selected?

To make trees less correlated and improve the benefit of ensemble averaging.

Q6. Does Random Forest require feature scaling?

Generally, no.

Q7. What is n_estimators?

The number of trees in the forest.

Q8. What happens if max_depth is too large?

Individual trees may become excessively complex and overfit.

Q9. What is OOB evaluation?

It uses observations not selected for a particular tree's bootstrap sample to estimate performance for that tree and can provide an internal validation estimate.

Q10. Why is Random Forest usually better than a single Decision Tree?

Combining diverse trees generally reduces variance and produces more stable predictions.

7.9.31 Key Takeaways

Module 7 · Lesson 7.10

Support Vector Machines (SVM)

7.10.1 Introduction

Support Vector Machine (SVM) is a supervised machine learning algorithm used primarily for classification, although it can also be used for regression.

The central idea of SVM is to find a decision boundary that separates different classes while maximizing the margin between them.

For a simple binary classification problem:

Class A ○ ○ ○

○ ○ ○

← Margin →
│
│ Decision Boundary
│
← Margin →
● ● ●
Class B ● ● ●

The observations closest to the decision boundary are called support vectors.

7.10.2 Simple Example

Suppose we have two types of customers:

○ → Low Risk
● → High Risk

○ ○ ○ ○ ○ ○

○ ○ ○ ○ ○ ○

| / \

| / \

● ● ● ● ● ●

● ● ● ● ● ●

SVM prefers the boundary with the largest margin between the classes.

7.10.3 What Is a Hyperplane?

In SVM, the decision boundary is called a hyperplane.

For two features:

\[w_1x_1+w_2x_2+b=0\]

where:

7.10.4 Margin

The margin is the distance between the decision boundary and the closest training observations from each class.

Conceptually:

Class A

│
│ ← Margin
│
────┼──── Decision Boundary
│
│ ← Margin
│
●
●
●
Class B

SVM attempts to maximize this margin.

A larger margin generally helps the classifier generalize better to unseen data.

7.10.5 Support Vectors

The observations closest to the decision boundary are called support vectors.

Example:

○ ○ ○

○ ← Support Vector
\
\
-----\--------- Decision Boundary
\
● ← Support Vector
● ● ●

These observations are particularly important because they help determine the position of the optimal boundary.

Observations far away from the boundary generally have less direct influence on the final separating hyperplane.

7.10.6 Maximum Margin Classifier

\[\min_{w,b}\frac{1}{2}|w|^2\]

subject to:

\[y_i(w^Tx_i+b)\geq1\]

This formulation maximizes the margin while correctly classifying all training observations.

7.10.7 Why Maximize the Margin?

Consider two possible boundaries:

Small Margin:

○ ○

│
│
●
● ●

Large Margin:

○ ○

│
│
│
●
● ●

A boundary with a larger margin is generally less sensitive to small variations in the data.

This can improve generalization.

7.10.8 Hard Margin vs Soft Margin

Real-world datasets are rarely perfectly separable.

There may be:

Therefore, SVM commonly uses a soft-margin formulation.

Soft-margin SVM allows some observations to violate the margin or even be misclassified.

The optimization objective can be expressed as:

\[\min_{w,b,\xi} \frac{1}{2}|w|^2 + C\sum_i\xi_i\]

subject to:

\[y_i(w^Tx_i+b)\geq1-\xi_i\]

where:

7.10.9 The C Parameter

The C parameter controls the trade-off between:

↓
Wider margin
↓
More tolerance for errors
Large C

Penalizes errors strongly.

Large C

↓
Fewer training errors
↓
Potentially narrower margin

A very large C can increase the risk of overfitting.

7.10.10 SVM with Nonlinear Data

A basic linear SVM works when the classes can be separated reasonably well by a hyperplane.

But real-world data may look like:

● ● ●

● ●

● ○○ ●

● ○○○ ●

● ● ●

A straight line cannot separate the classes effectively.

This is where the kernel trick becomes important.

7.10.11 Kernel Trick

The kernel trick allows SVM to model nonlinear relationships by implicitly working in a higher-dimensional feature space.

Conceptually:

Original Feature Space

↓
Kernel Function
↓
Higher-Dimensional Representation
↓
Linear Separation

The model can therefore produce a nonlinear decision boundary in the original feature space.

7.10.12 Common SVM Kernels

Important kernels include:

  1. Linear

  2. Polynomial

  3. RBF

  4. Sigmoid

The most commonly encountered nonlinear kernel is the RBF (Radial Basis Function) kernel.

7.10.13 Linear Kernel

The linear kernel is:

\[K(x_i,x_j)=x_i^Tx_j\]

It is useful when the classes are approximately linearly separable.

In Scikit-learn:

from sklearn.svm import SVC
model = SVC(kernel="linear")

7.10.14 Polynomial Kernel

The polynomial kernel can be written as:

\[K(x_i,x_j)= (\gamma x_i^Tx_j+r)^d\]

where:

It can model polynomial relationships.

Example:

model = SVC(
kernel="poly",
degree=3
)

7.10.15 RBF Kernel

The RBF kernel is:

\[\boxed{ K(x_i,x_j) \exp(-\gamma|x_i-x_j|^2) }\]

It measures similarity based on distance between observations.

RBF is powerful for many nonlinear classification problems.

Example:

model = SVC(
kernel="rbf"
)

7.10.16 The Gamma Parameter

For the RBF kernel, gamma controls how strongly the influence of an individual training observation falls off with distance.

↓
Broader influence
↓
Smoother decision boundary
High Gamma
High gamma
↓
Localized influence
↓
More complex boundary

A very high gamma can contribute to overfitting.

7.10.17 C and Gamma Together

For an RBF SVM, C and gamma interact.

Parameter Low Value High Value
C More tolerance for errors, wider margin Stronger penalty for errors
gamma Smoother/broader influence More localized/complex boundaries

A useful conceptual picture:

C ↓ + gamma ↓
↓
Simpler model
C ↑ + gamma ↑
↓
More complex model

The optimal values should normally be selected using validation or cross-validation.

7.10.18 Feature Scaling

Feature scaling is particularly important for SVM, especially with RBF, polynomial, or other distance-sensitive kernels.

Suppose:

Age → 20–70
Income → 20,000–2,000,000

Income has a much larger scale.

Without scaling, the distance calculations can be dominated by income.

Therefore, a typical SVM pipeline is:

Raw Data

↓
StandardScaler
↓
SVM

Example:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
model = Pipeline([
("scaler", StandardScaler()),
("svm", SVC(kernel="rbf"))
])

Using a pipeline is preferable because the scaler is fitted only on the training data and then consistently applied to validation/test/new data.

7.10.19 SVM Classification Using Python

A basic example:

from sklearn.svm import SVC
X = [
[1, 2],
[2, 3],
[3, 3],
[7, 8],
[8, 9],
[9, 8]
]
y = [
0,
0,
0,
1,
1,
1
]
model = SVC(
kernel="linear",
C=1.0
)
model.fit(X, y)
prediction = model.predict([
[5, 6]
])
print("Prediction:", prediction)

7.10.20 SVM with Standardization

A more practical implementation:

from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)
model = Pipeline([
("scaler", StandardScaler()),
("svm", SVC(
kernel="rbf",
C=1.0,
gamma="scale"
))
])
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))

7.10.21 Probability Estimates

By default, SVC does not provide probability estimates.

If probability estimates are required:

model = SVC(
kernel="rbf",
probability=True
)

Then:

probabilities = model.predict_proba(X_test)

Probability estimation adds additional computational cost because Scikit-learn uses an additional calibration procedure.

7.10.22 Support Vector Regression

SVM can also be used for regression.

This is called Support Vector Regression (SVR).

In Scikit-learn:

from sklearn.svm import SVR
model = SVR(
kernel="rbf"
)
model.fit(X_train, y_train)
predictions = model.predict(X_test)

The basic idea differs from ordinary least-squares regression.

SVR attempts to fit a function while allowing errors within an epsilon-insensitive tube.

7.10.23 Epsilon in SVR

SVR introduces a parameter:

\[\epsilon\]

-----------------------

• • •

• •

----------------------- ← Regression function
• •
• • •
-----------------------
Lower ε-bound

Predictions inside the epsilon tube do not contribute to the same type of penalty as observations outside it.

7.10.24 Multiclass SVM

SVM is naturally a binary classification method.

For multiple classes, strategies are used to extend it.

One-vs-Rest

For (K) classes, train (K) binary classifiers.

Example:

One-vs-One

Scikit-learn's SVC uses a one-vs-one strategy internally for multiclass classification.

7.10.25 Advantages of SVM

1. Effective in High-Dimensional Spaces

SVM can work well when the number of features is relatively large.

2. Strong Margin-Based Learning

Maximizing the margin can provide good generalization.

3. Kernel Trick

Allows nonlinear decision boundaries.

4. Effective with Small-to-Medium Datasets

SVM can perform very well when datasets are not extremely large.

5. Flexible

Different kernels allow different types of decision boundaries.

6. Support Vectors

Only a subset of training observations directly determines the boundary in the dual formulation.

7.10.26 Limitations of SVM

1. Computationally Expensive

Training can become expensive with very large datasets, particularly for nonlinear kernels.

2. Feature Scaling Is Important

Unscaled features can significantly affect performance.

3. Hyperparameter Tuning

Selecting C, gamma, kernel type, and other parameters can require substantial experimentation.

4. Less Interpretable

An RBF SVM is harder to explain than a small Decision Tree or Logistic Regression model.

5. Sensitive to Noise and Outliers

Poor data quality can affect the learned boundary.

6. Probability Estimates Are Not Native

Standard SVM primarily learns a decision function; calibrated probabilities require additional processing.

7.10.27 SVM vs Logistic Regression

SVM Logistic Regression
Maximizes margin Models class probability through log-odds
Can use nonlinear kernels Basic model has linear decision boundary
Excellent for complex boundaries with kernels Strong simple baseline
Feature scaling usually important Often useful
Probability requires additional calibration Probability is a natural model output
Can be computationally expensive Generally faster
Less interpretable with nonlinear kernels More interpretable

7.10.28 SVM vs Decision Tree

SVM Decision Tree
Margin-based Rule/split-based
Feature scaling important Scaling generally unnecessary
Can model nonlinear patterns using kernels Naturally handles nonlinear splits
Less interpretable Small trees are easy to interpret
Sensitive to hyperparameters Also sensitive to depth/splitting parameters
Often good for small/medium datasets Often strong on tabular data

7.10.29 SVM vs Random Forest

SVM Random Forest
Kernel/margin-based Tree ensemble
Scaling important Scaling generally unnecessary
Can create complex boundaries Captures nonlinear relationships naturally
Can be expensive for large datasets Usually scales differently and can parallelize trees
Less interpretable Feature importance available
Strong for certain high-dimensional problems Strong general-purpose tabular model

7.10.30 Practical Example — Spam Classification

↓
Text Processing
↓
Feature Extraction
↓
Feature Scaling where appropriate
↓
SVM
↓
Decision Function
↓
Spam / Not Spam

For high-dimensional text features, a linear SVM is often a useful baseline.

7.10.31 Practical Example — Customer Churn

An RBF SVM may learn a nonlinear boundary such as:

High Charges

+

Short Tenure

+

Many Support Calls

↓
Higher Churn Risk

Unlike a simple linear classifier, the kernel allows the decision boundary to be nonlinear.

7.10.32 Hyperparameter Tuning

Important parameters can be tuned using cross-validation.

from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
pipeline = Pipeline([
("scaler", StandardScaler()),
("svm", SVC())
])
params = {
"svm__C": [0.1, 1, 10],
"svm__gamma": ["scale", 0.01, 0.1],
"svm__kernel": ["linear", "rbf"]
}
grid = GridSearchCV(
pipeline,
params,
cv=5,
scoring="f1"
)
grid.fit(X_train, y_train)
print(grid.best_params_)

The best hyperparameters should be selected based on the evaluation metric appropriate to the business problem.

7.10.33 SVM Workflow

A practical SVM workflow is:

1. Collect Data
2. Clean Data
3. Select Features
4. Split Train/Test
5. Scale Features
6. Select Kernel
7. Choose C / Gamma
8. Train SVM
9. Evaluate
10. Tune Hyperparameters
11. Final Test
12. Deploy

7.10.34 Important Terms

Term Meaning
Hyperplane Decision boundary
Margin Distance around the separating boundary
Support Vector Training observation defining the margin/boundary
Kernel Function enabling nonlinear similarity computation
C Controls penalty for margin violations
gamma Controls locality of influence for kernels such as RBF
RBF Radial Basis Function kernel
SVR Support Vector Regression
Soft Margin Allows some violations/misclassification

7.10.35 Interview Questions

Q1. What is SVM?

SVM is a supervised learning algorithm that finds a separating hyperplane while attempting to maximize the margin between classes.

Q2. What are support vectors?

They are the training observations closest to the decision boundary that determine the optimal margin/boundary.

Q3. What is the margin?

The margin is the distance between the decision boundary and the closest observations from the classes.

Q4. Why is feature scaling important for SVM?

Many SVM formulations, particularly kernel-based ones, depend on feature magnitudes and distances. Large-scale features can dominate the optimization or kernel calculations.

Q5. What is the kernel trick?

It allows SVM to model nonlinear relationships by implicitly operating in a higher-dimensional feature space without explicitly constructing all transformed features.

Q6. What does C control?

It controls the penalty associated with margin violations and training errors.

Q7. What does gamma control?

For kernels such as RBF, it controls how localized the influence of individual observations is.

Q8. What happens with very high gamma?

The model can create highly localized, complex decision boundaries and may overfit.

Q9. What is the difference between hard and soft margin?

Hard margin requires perfect separation; soft margin allows some violations to improve robustness to noise and non-separable data.

Q10. Can SVM be used for regression?

Yes. Support Vector Regression (SVR) performs regression using an epsilon-insensitive loss formulation.

7.10.36 Key Takeaways

Module 7 · Lesson 7.11

KNN

7.11.1 Introduction

K-Nearest Neighbors (KNN) is a supervised machine learning algorithm used for both:

For example, if we want to classify a new customer as Low Risk or High Risk, KNN looks at the customer's nearest existing customers and uses their labels to make the prediction.

Existing Data

↓
Calculate Distance
↓
Find K Nearest Points
↓
Look at Their Labels
↓
Majority Vote
↓
Prediction

7.11.2 Simple Example

Suppose we have customers classified as:

○ → Low Risk
● → High Risk

A new customer is represented by:

★ → Unknown

KNN finds the closest customers:

○ ○

● ○

If:

\[K=5\]

and the nearest five customers contain:

○ → 3
● → 2

then the prediction is:

Low Risk

because Low Risk has the majority vote.

7.11.3 Why Is It Called K-Nearest Neighbors?

Nearest

The algorithm identifies observations closest to the new observation.

Neighbors

7.11.4 KNN Is a Lazy Learning Algorithm

KNN is often called a lazy learner.

Why?

↓
Store Data
↓
No complex model fitting

At prediction time:

New Observation

↓
Calculate Distances
↓
Find Neighbors
↓
Make Prediction

This is also why KNN is often described as an instance-based or memory-based learning method.

7.11.5 KNN Classification

For classification, KNN generally uses majority voting.

Suppose:

\[K=5\]

The nearest neighbors are:

Neighbor Class
1 A
2 B
3 A
4 A
5 B

Votes:

Class A → 3
Class B → 2

Prediction:

\[\boxed{Class\ A}\]

7.11.6 KNN Regression

KNN can also predict continuous values.

Suppose the nearest five houses have prices:

A simple KNN regression prediction is their average:

\[Prediction= \frac{50+55+52+58+55}{5}\]

\[=54\]

Therefore:

Predicted Price ≈ ₹54 Lakhs

7.11.7 Distance

\[A=(x_1,y_1)\]

and:

\[B=(x_2,y_2)\]

the Euclidean distance is:

\[\boxed{ d(A,B)= \sqrt{(x_1-x_2)^2+(y_1-y_2)^2} }\]

7.11.8 Example of Euclidean Distance

Suppose:

\[A=(2,3)\]

and:

\[B=(5,7)\]

Then:

\[d= \sqrt{(5-2)^2+(7-3)^2}\]

\[\sqrt{3^2+4^2}\]

\[\sqrt{25}\]

\[=5\]

Therefore, the distance between the two points is:

\[\boxed{5}\]

7.11.9 Manhattan Distance

Another common distance metric is Manhattan distance.

\[\boxed{ d(A,B)= |x_1-x_2|+|y_1-y_2| }\]

For:

\[A=(2,3)\]

and:

\[B=(5,7)\]

we get:

\[d=|5-2|+|7-3|\]

\[=3+4\]

\[=7\]

7.11.10 Minkowski Distance

Minkowski distance is a generalization of several distance measures:

\[d(x,y)= \left( \sum_i |x_i-y_i|^p \right)^{1/p}\]

Different values of (p) produce different distances.

For example:

p = 1 → Manhattan
p = 2 → Euclidean

7.11.11 Why Feature Scaling Is Important

Feature scaling is very important for KNN.

Suppose we have:

Age → 20–70
Income → 20,000–2,000,000

Distance calculations may be dominated by Income because its numerical values are much larger.

This can cause the algorithm to identify inappropriate neighbors.

Therefore, we commonly scale features before using KNN.

7.11.12 Standardization

A common scaling technique is Standardization:

\[z=\frac{x-\mu}{\sigma}\]

where:

After standardization, features are typically centered around 0 with unit variance.

Using Scikit-learn:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

Notice the important distinction:

Training data → fit_transform()
Test data → transform()

The scaler should be fitted only using training data.

7.11.13 Choosing K

7.11.14 Small K

Suppose:

\[K=1\]

The prediction depends entirely on the single nearest observation.

Advantages:

Disadvantage:

Conceptually:

Small K

↓
Very local decisions
↓
High variance

7.11.15 Large K

Suppose:

\[K=50\]

The algorithm considers many neighbors.

Advantages:

Disadvantages:

Conceptually:

Large K

↓
Broader neighborhood
↓
Smoother model

7.11.16 Bias-Variance Tradeoff in KNN

K controls the balance between bias and variance.

K too small

↓
Low bias
High variance
↓
Overfitting

Whereas:

K too large

↓
High bias
Low variance
↓
Underfitting

The goal is to find a K that generalizes well.

Cross-validation is commonly used to select it.

7.11.17 Odd Values of K

For binary classification, odd values such as:

are sometimes preferred because they reduce the chance of a tie in simple majority voting.

However, odd K is not a universal requirement.

7.11.18 Weighted KNN

Neighbor 1 → Weight 0.50
Neighbor 2 → Weight 0.25
Neighbor 3 → Weight 0.15
Neighbor 4 → Weight 0.07
Neighbor 5 → Weight 0.03

The nearest observations therefore have more influence.

In Scikit-learn:

KNeighborsClassifier(
n_neighbors=5,
weights="distance"
)

7.11.19 KNN Classification Using Python

from sklearn.neighbors import KNeighborsClassifier
X = [
[1, 2],
[2, 3],
[3, 3],
[7, 8],
[8, 9],
[9, 8]
]
y = [
0,
0,
0,
1,
1,
1
]
model = KNeighborsClassifier(
n_neighbors=3
)
model.fit(X, y)
prediction = model.predict([
[5, 6]
])
print("Prediction:", prediction)

7.11.20 KNN with Feature Scaling

A practical implementation should usually use a pipeline:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
model = Pipeline([
("scaler", StandardScaler()),
("knn", KNeighborsClassifier(
n_neighbors=5
))
])
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

The pipeline prevents accidental data leakage during scaling.

7.11.21 Complete KNN Classification Example

from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)
model = Pipeline([
    ("scaler", StandardScaler()),
    ("knn", KNeighborsClassifier(
        n_neighbors=5
    ))
])
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(
    "Accuracy:",
    accuracy_score(y_test, y_pred)
)

7.11.22 KNN Regression Using Python

For regression:

from sklearn.neighbors import KNeighborsRegressor
model = KNeighborsRegressor(
n_neighbors=5
)
model.fit(X_train, y_train)
prediction = model.predict(X_test)

For weighted regression:

model = KNeighborsRegressor(
n_neighbors=5,
weights="distance"
)

7.11.23 KNN Classification vs Regression

Classification Regression
Predicts a class Predicts a numerical value
Uses voting Uses averaging/weighted averaging
KNeighborsClassifier KNeighborsRegressor
Example: Spam/Not Spam Example: House Price
Accuracy/F1 etc. MAE/RMSE/R²

7.11.24 KNN Probability

For classification, Scikit-learn can estimate class probabilities.

model = KNeighborsClassifier(
n_neighbors=5
)
model.fit(X_train, y_train)
probability = model.predict_proba(X_test)
print(probability)

If 4 out of 5 neighbors belong to Class 1 and 1 belongs to Class 0, a simple uniform-weight interpretation gives approximately:

Class 0 → 20%
Class 1 → 80%

With distance weighting, the probabilities can differ because closer neighbors have more influence.

7.11.25 KNN and High-Dimensional Data

KNN can struggle when the number of features becomes very large.

This is related to the Curse of Dimensionality.

As dimensionality increases:

For example:

2 features

↓
Distance is meaningful
1000 features
↓
Distances may become less discriminative

Possible approaches include:

7.11.26 Computational Complexity

KNN has an important characteristic:

Prediction can be computationally expensive because distances to many training observations may need to be calculated.

If the training dataset is very large:

Millions of observations

↓
Many distance calculations
↓
Slower predictions

Efficient nearest-neighbor search structures such as KD-trees or Ball Trees can help in suitable lower-dimensional settings, but their effectiveness depends on the data and dimensionality.

7.11.27 KNN and Missing Values

↓
Imputation
↓
Scaling
↓
KNN
Scikit-learn provides tools such as SimpleImputer for preprocessing.

Example:

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy="median")

This can be combined with a pipeline.

7.11.28 KNN and Categorical Features

7.11.29 Practical Example — Customer Classification

Suppose a company wants to classify customers into:

↓
Missing Value Handling
↓
Categorical Encoding
↓
Feature Scaling
↓
Choose K
↓
Calculate Distances
↓
Find K Nearest Customers
↓
Majority Vote
↓
Customer Segment

7.11.30 Selecting the Best K

Instead of randomly choosing K, use cross-validation.

from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
pipeline = Pipeline([
("scaler", StandardScaler()),
("knn", KNeighborsClassifier())
])
params = {
"knn__n_neighbors": [3, 5, 7, 9, 11, 15]
}
grid = GridSearchCV(
pipeline,
params,
cv=5,
scoring="accuracy"
)
grid.fit(X_train, y_train)
print(grid.best_params_)

The best K is selected based on validation performance rather than simply assuming that a particular value is always best.

7.11.31 Advantages of KNN

1. Simple

The basic algorithm is easy to understand.

2. Easy to Implement

Scikit-learn provides ready-to-use implementations.

3. No Complex Training

Most computation happens during prediction.

4. Naturally Handles Nonlinear Boundaries

It does not require a linear decision boundary.

5. Can Perform Classification and Regression

Both are supported.

6. Flexible

Different distance metrics and weighting schemes can be used.

7.11.32 Limitations of KNN

1. Prediction Can Be Slow

Large training datasets can make inference expensive.

2. Sensitive to Feature Scaling

Different feature scales can distort distances.

3. Sensitive to Irrelevant Features

Irrelevant variables can affect distance calculations.

4. Curse of Dimensionality

Performance can degrade in high-dimensional spaces.

5. Memory Intensive

The algorithm typically needs access to the training observations during prediction.

6. Choice of K Matters

Poor selection can lead to overfitting or underfitting.

7. Sensitive to Distance Metric

Different metrics can produce different neighbors and therefore different predictions.

7.11.33 KNN vs Logistic Regression

KNN Logistic Regression
Instance-based Parametric linear model
No traditional model fitting Learns coefficients
Nonlinear boundaries possible Linear boundary by default
Scaling important Scaling often useful
Prediction can be expensive Prediction usually fast
Easy conceptually Easy to interpret
Sensitive to K Sensitive to regularization and feature representation

7.11.34 KNN vs Decision Tree

KNN Decision Tree
Distance-based Rule-based
Scaling important Scaling unnecessary
Lazy learning Eager learning
Prediction can be expensive Prediction usually fast
Sensitive to irrelevant features Can perform feature selection through splits
Nonlinear boundaries Nonlinear rules
High-dimensional data can be difficult Often handles tabular data well

7.11.35 KNN vs SVM

KNN SVM
Instance-based Margin-based
Stores training data Learns a decision function
Scaling important Scaling important
Prediction can be expensive Prediction often more compact
K controls neighborhood size C/kernel parameters control model
Simple concept More mathematically involved
Can struggle in high dimensions Can perform well in high-dimensional spaces

7.11.36 Interview Questions

Q1. What is KNN?

KNN is a supervised learning algorithm that predicts an observation based on the labels or values of its nearest training observations.

Q2. What does K represent?

The number of nearest neighbors considered when making a prediction.

Q3. Is KNN supervised or unsupervised?

KNN is primarily a supervised learning algorithm.

Q4. Can KNN perform regression?

Yes. KNN regression predicts a numerical value using nearby observations.

Q5. Why is scaling important?

Because KNN relies on distance calculations, features with larger numerical scales can dominate the distance.

Q6. What happens if K is too small?

The model can become sensitive to noise and overfit.

Q7. What happens if K is too large?

The model can become overly smooth and underfit.

Q8. What is the most common distance metric?

Euclidean distance is commonly used, although other metrics are available.

Q9. Why is KNN called a lazy learner?

Because it does little traditional model fitting during training and performs much of its computation when predictions are requested.

Q10. What is the Curse of Dimensionality?

As the number of features increases, distance-based methods can become less effective because observations become sparse and distances become less discriminative.

7.11.37 Key Takeaways

Module 7 · Lesson 7.12

Naive Bayes

7.12.1 Introduction

Naive Bayes is a supervised machine learning algorithm mainly used for classification.

It is based on Bayes' Theorem and makes a simplifying assumption that the input features are conditionally independent given the class.

Despite this "naive" assumption, Naive Bayes can work extremely well, especially for:

The basic workflow is:

Training Data

↓
Calculate Class Probabilities
↓
Calculate Feature Probabilities
↓
Apply Bayes' Theorem
↓
Calculate Probability for Each Class
↓
Choose Highest Probability
↓
Predicted Class

7.12.2 Bayes' Theorem

7.12.3 Basic Terminology

\[P(Spam)\]

Probability that an email is spam before considering the word "free".

Likelihood

\[P(Free|Spam)\]

Probability that an email contains "free" given that it is spam.

Evidence

\[P(Free)\]

Overall probability that an email contains "free".

Posterior Probability

\[P(Spam|Free)\]

Probability that the email is spam given that it contains "free".

7.12.4 Bayes' Theorem Formula

For events (A) and (B):

\[P(A|B)= \frac{P(B|A)P(A)} {P(B)}\]

In classification:

\[P(Class|Features) \frac{ P(Features|Class)P(Class) }{ P(Features) }\]

The model compares the posterior probability for each possible class.

7.12.5 Simple Spam Detection Example

\[P(Spam|Free,Offer)\]

and:

\[P(NotSpam|Free,Offer)\]

Prediction → Spam

7.12.6 Why Is It Called "Naive"?

Naive Bayes assumes that, given the class, the presence of these features can be treated as conditionally independent:

\[P(Free,Offer,Winner|Spam)\]

is approximated as:

\[P(Free|Spam) P(Offer|Spam) P(Winner|Spam)\]

This assumption is often unrealistic in real-world data.

Nevertheless, the method can still perform surprisingly well.

7.12.7 Naive Bayes Classification Formula

For a feature vector:

\[X=(x_1,x_2,\ldots,x_n)\]

we want:

\[P(C|x_1,x_2,\ldots,x_n)\]

Using Bayes' theorem:

\[P(C|X) \frac{P(X|C)P(C)} {P(X)}\]

With the Naive Bayes independence assumption:

\[P(X|C) \prod_{i=1}^{n}P(x_i|C)\]

Therefore:

\[P(C|X) \propto P(C) \prod_{i=1}^{n}P(x_i|C)\]

For classification, we can compare these values across classes and choose the class with the largest posterior probability.

7.12.8 Prior Probability

The prior probability is the probability of a class before considering the input features.

Suppose we have 1,000 emails:

Spam → 300
Not Spam → 700

Then:

\[P(Spam)=\frac{300}{1000}=0.3\]

and:

\[P(NotSpam)=\frac{700}{1000}=0.7\]

These are the class priors.

7.12.9 Likelihood

The word "free" is therefore much more common in spam messages.

7.12.10 Posterior Probability

+

Evidence

↓
Posterior

7.12.11 A Complete Numerical Example

\[P(Spam|Free) \frac{ P(Free|Spam)P(Spam) }{ P(Free) }\]

First calculate:

\[P(Free) P(Free|Spam)P(Spam) + P(Free|NotSpam)P(NotSpam)\]

\[=(0.7)(0.4)+(0.1)(0.6)\]

\[=0.28+0.06\]

\[=0.34\]

Therefore:

\[P(Spam|Free) \frac{0.7\times0.4}{0.34}\]

\[=\frac{0.28}{0.34}\]

\[\approx0.824\]

So:

P(Spam | Free) ≈ 82.4%

The email would likely be classified as Spam.

7.12.12 Multiple Features

Now suppose an email contains:

\[P(Free,Offer,Winner|Spam)\]

as:

\[P(Free|Spam) \times P(Offer|Spam) \times P(Winner|Spam)\]

Then:

\[P(Spam|Free,Offer,Winner) \propto P(Spam) P(Free|Spam) P(Offer|Spam) P(Winner|Spam)\]

The same calculation is performed for Not Spam.

Whichever class gets the larger value is selected.

7.12.13 Types of Naive Bayes

Scikit-learn provides several important Naive Bayes variants.

1. Gaussian Naive Bayes

Used primarily for continuous numerical features.

from sklearn.naive_bayes import GaussianNB

2. Multinomial Naive Bayes

Commonly used for count-based features such as word counts.

from sklearn.naive_bayes import MultinomialNB

3. Bernoulli Naive Bayes

Useful when features are binary:

0 → Feature absent
1 → Feature present
from sklearn.naive_bayes import BernoulliNB

4. Complement Naive Bayes

Designed particularly for imbalanced text classification and often useful with sparse count-based features.

from sklearn.naive_bayes import ComplementNB

7.12.14 Gaussian Naive Bayes

Gaussian Naive Bayes assumes that continuous features follow a Gaussian/normal distribution within each class.

\[P(x|C) \frac{1} {\sqrt{2\pi\sigma_C^2}} e^{-\frac{(x-\mu_C)^2}{2\sigma_C^2}}\]

where:

Example:

from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

7.12.15 Multinomial Naive Bayes

Multinomial Naive Bayes is especially popular for text classification.

Suppose a document contains word counts:

free → 4
offer → 2
winner → 1
meeting → 0

These counts can be used as features.

Multinomial Naive Bayes is commonly paired with:

Example:

from sklearn.naive_bayes import MultinomialNB
model = MultinomialNB()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

7.12.16 Bernoulli Naive Bayes

Bernoulli Naive Bayes works with binary features.

For example:

free → 1
offer → 1
winner → 0
meeting → 0

Here:

1 → Feature present
0 → Feature absent

It can be useful when the presence or absence of a feature matters more than its count.

7.12.17 Smoothing

A major problem with Naive Bayes is zero probability.

Suppose:

\[P(Winner|NotSpam)=0\]

Then:

\[P(Free,Winner|NotSpam)\]

7.12.18 Laplace Smoothing

A common smoothed estimate is:

\[P(x_i|C) \frac{count(x_i,C)+\alpha} {count(C)+\alpha V}\]

where:

In Scikit-learn's MultinomialNB:
model = MultinomialNB(alpha=1.0)

The alpha parameter controls smoothing.

7.12.19 Why Naive Bayes Is Excellent for Text

Naive Bayes is particularly effective for text because text datasets often have:

For example:

10,000 documents

↓
50,000 unique words
↓
Sparse feature matrix
↓
Naive Bayes
↓
Classification

Naive Bayes can be fast and computationally efficient in such settings.

7.12.20 Text Classification Workflow

A typical spam classifier can be built as:

Emails

↓
Text Cleaning
↓
Tokenization
↓
Feature Extraction
↓
Bag of Words / TF-IDF
↓
Naive Bayes
↓
Spam / Not Spam

For example:

"Congratulations! You won a free prize"

might become numerical features such as:

free → 1
won → 1
prize → 1
congratulations → 1

The Naive Bayes model then uses these features.

7.12.21 Naive Bayes with CountVectorizer

Example:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
documents = [
    "free offer now",
    "win free prize",
    "meeting at 10",
    "project meeting tomorrow"
]
labels = [
    1,
    1,
    0,
    0
]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(documents)
model = MultinomialNB()
model.fit(X, labels)

Now we can classify a new document:

new_text = [

"free prize"

]
X_new = vectorizer.transform(new_text)
prediction = model.predict(X_new)
print(prediction)

7.12.22 Using a Pipeline

A cleaner production-style approach is to use a Scikit-learn pipeline.

from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
model = Pipeline([
("tfidf", TfidfVectorizer()),
("classifier", MultinomialNB())
])
model.fit(X_train_text, y_train)
predictions = model.predict(X_test_text)

This combines:

Text

↓
TF-IDF
↓
Naive Bayes
↓
Prediction

7.12.23 Naive Bayes Probability

Naive Bayes can provide class probabilities.

probabilities = model.predict_proba(X_test)
print(probabilities)

For example:

Class 0 → 0.10
Class 1 → 0.90

The model strongly favors Class 1.

7.12.24 Advantages of Naive Bayes

1. Simple

The underlying concept is relatively straightforward.

2. Fast

Training and prediction can be very efficient.

3. Works Well with High-Dimensional Data

Especially useful for text classification.

4. Works with Small Training Datasets

It can perform reasonably well even when training data is limited.

5. Easy to Implement

Scikit-learn provides several implementations.

6. Handles Many Features

It can work effectively with large sparse feature spaces.

7. Probabilistic Output

It can provide class probability estimates.

7.12.25 Limitations of Naive Bayes

1. Independence Assumption

contains two words whose meanings are related.

Naive Bayes treats features much more independently than they actually are.

2. Probability Estimates May Be Poorly Calibrated

The predicted probabilities may not always correspond closely to real-world frequencies, even when classification accuracy is good.

3. Zero-Frequency Problem

Without smoothing, unseen feature/class combinations can cause zero probabilities.

4. Feature Representation Matters

The quality of text/vector features can strongly affect performance.

5. Complex Relationships

It may perform worse than more sophisticated models when complex feature interactions are important.

7.12.26 Naive Bayes vs Logistic Regression

Naive Bayes Logistic Regression
Generative classifier Discriminative classifier
Uses Bayes' theorem Directly models class probabilities/log-odds
Assumes conditional independence Does not make that same independence assumption
Often excellent for text Strong general-purpose classifier
Usually very fast Also efficient
Can work well with small datasets Often needs careful regularization
Probability calibration may be weaker Often better calibrated depending on data/model

7.12.27 Naive Bayes vs KNN

Naive Bayes KNN
Probabilistic model Instance-based model
Learns class/feature statistics Stores training observations
Prediction usually fast Prediction can be expensive
Strong for high-dimensional text Can struggle in high dimensions
Does not rely on distance Relies heavily on distance
Feature independence assumption Local similarity assumption

7.12.28 Naive Bayes vs Decision Tree

Naive Bayes Decision Tree
Probabilistic Rule-based
Uses Bayes' theorem Uses recursive splits
Strong for text Strong general-purpose tabular model
Conditional independence assumption No such assumption
Very fast Can be more computationally involved
Requires suitable feature representation Naturally handles many tabular features

7.12.29 Practical Example — Spam Detection

Suppose we have:

Email 1 → "Free prize winner" → Spam
Email 2 → "Win a free offer" → Spam
Email 3 → "Meeting at 3 PM" → Not Spam
Email 4 → "Project meeting tomorrow" → Not Spam

The model learns:

free + win + prize

↓
Strong evidence for Spam

\[P(Spam|Free,Winner,Offer)\]

and:

\[P(NotSpam|Free,Winner,Offer)\]

If the first is higher:

Prediction → Spam

7.12.30 Complete Text Classification Example

from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, classification_report
texts = [
    "free prize winner",
    "win a free offer",
    "claim your free reward",
    "meeting at office",
    "project meeting tomorrow",
"team discussion at 10"
]
labels = [
1,
1,
1,
0,
0,
0
]
X_train, X_test, y_train, y_test = train_test_split(
texts,
labels,
test_size=0.33,
random_state=42,
stratify=labels
)
model = Pipeline([
("tfidf", TfidfVectorizer()),
("classifier", MultinomialNB())
])
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))

7.12.31 Choosing the Right Naive Bayes Variant

Variant Typical Data
GaussianNB Continuous numerical features
MultinomialNB Counts/frequency features, especially text
BernoulliNB Binary features
ComplementNB Often useful for imbalanced text classification

A useful rule:

Continuous Numerical Data

↓
GaussianNB
Word Counts / TF-IDF
↓
MultinomialNB
Binary Features
↓
BernoulliNB
Imbalanced Text Classification
↓
Consider ComplementNB

The exact choice should ultimately be validated experimentally.

7.12.32 Important Hyperparameters

alpha
Controls smoothing in MultinomialNB and related models.
MultinomialNB(alpha=1.0)
fit_prior

Controls whether class prior probabilities are learned from the training data.

MultinomialNB(fit_prior=True)
class_prior

Allows explicit class priors to be supplied when appropriate.

MultinomialNB(
class_prior=[0.7, 0.3]
)

These settings should be chosen based on the problem and validated appropriately.

7.12.33 Real-World Applications

Naive Bayes is commonly used for:

Email Spam Detection

Email → Spam / Not Spam
Sentiment Analysis
Review → Positive / Negative
News Classification
Article → Sports / Politics / Business / Technology
Document Classification
Document → Category
Language Identification
Text → English / Hindi / Telugu / etc.
Support Ticket Classification
Ticket → Billing / Technical / Account / Other

7.12.34 Interview Questions

Q1. What is Naive Bayes?

A probabilistic supervised learning algorithm based on Bayes' theorem and the assumption of conditional independence between features given the class.

Q2. Why is it called "Naive"?

Because of the simplifying assumption that features are conditionally independent given the class.

Q3. What is Bayes' theorem?

It provides a way to update the probability of a hypothesis using observed evidence.

Q4. What is prior probability?

The probability of a class before considering the current evidence.

Q5. What is likelihood?

The probability of observing the features given a particular class.

Q6. What is posterior probability?

The probability of a class after incorporating the observed evidence.

Q7. What is Laplace smoothing?

A technique that prevents zero probabilities for unseen feature/class combinations.

Q8. Which Naive Bayes is commonly used for text classification?

Multinomial Naive Bayes is a common choice, particularly with count-based text features.

Q9. Which Naive Bayes is suitable for continuous features?

Gaussian Naive Bayes is commonly used when continuous features are reasonably modeled by Gaussian distributions within each class.

Q10. Is Naive Bayes a supervised algorithm?

Yes.

7.12.35 Key Takeaways

Module 7 · Lesson 7.13

K-Means Clustering

7.13.1 Introduction

K-Means Clustering is an unsupervised machine learning algorithm used to divide data into groups called clusters.

Unlike supervised learning, K-Means does not require predefined labels.

The algorithm attempts to group observations so that:

Data points within the same cluster are similar to each other, while points in different clusters are relatively dissimilar.

For example, a company may have customer data:

K-Means can automatically discover groups such as:

Cluster 1 → Budget Customers
Cluster 2 → Regular Customers
Cluster 3 → Premium Customers

The basic workflow is:

Unlabeled Data

↓
Choose K
↓
Initialize Centroids
↓
Assign Points to Nearest Centroid
↓
Recalculate Centroids
↓
Repeat
↓
Final Clusters

7.13.2 What Is Clustering?

Clustering is the process of grouping similar observations without predefined class labels.

For example:

● ●

● ● ●

▲ ▲

▲ ▲ ▲

■ ■

■ ■ ■

A clustering algorithm might discover:

Cluster 1 → ●
Cluster 2 → ▲
Cluster 3 → ■

The important point is that we did not tell the algorithm which observations belonged together.

7.13.3 Why Is K-Means Called "K-Means"?

The name has two parts.

\[K=3\]

means:

Divide the data into 3 clusters.

Means

Each cluster is represented by the mean/average position of the points assigned to it.

That average point is called the centroid.

7.13.4 Example

Suppose we have customer spending data.

We want:

\[K=3\]

clusters.

The algorithm initially chooses three centroids:

C1

● ●

C2

C3

The points are assigned to their nearest centroid.

Then the centroids move toward the average location of their assigned points.

This process repeats until the assignments stabilize or another stopping criterion is reached.

7.13.5 Centroid

A centroid is the mean position of all observations assigned to a cluster.

Suppose a cluster contains:

\[(2,2), (4,4), (6,6)\]

The centroid is:

\[\left( \frac{2+4+6}{3}, \frac{2+4+6}{3} \right)\]

\[=(4,4)\]

Therefore:

Points:

(2,2)

(4,4)

(6,6)

Centroid:

(4,4)

7.13.6 K-Means Algorithm

Example:

\[K=3\]

Repeat assignment and update until the algorithm converges or reaches the iteration limit.

7.13.7 Complete K-Means Process

Data

↓
Choose K
↓
Initialize Centroids
↓
Calculate Distances
↓
Assign to Nearest Centroid
↓
Calculate New Means
↓
Move Centroids
↓

Converged?

/ \

No Yes

↓ ↓
Repeat Final Clusters

7.13.8 Distance Calculation

K-Means commonly uses Euclidean distance.

For a point:

\[x=(x_1,x_2)\]

and centroid:

\[c=(c_1,c_2)\]

the distance is:

\[d(x,c)= \sqrt{(x_1-c_1)^2+(x_2-c_2)^2}\]

The point is assigned to the centroid with the smallest distance.

7.13.9 Simple Distance Example

Suppose:

\[P=(3,4)\]

and two centroids:

\[C_1=(1,1)\]

\[C_2=(6,5)\]

Distance to (C_1):

\[d(P,C_1) \sqrt{(3-1)^2+(4-1)^2}\]

\[=\sqrt{4+9}\]

\[=\sqrt{13} \approx3.61\]

Distance to (C_2):

\[d(P,C_2) \sqrt{(3-6)^2+(4-5)^2}\]

\[=\sqrt{9+1}\]

\[=\sqrt{10} \approx3.16\]

Since:

\[3.16<3.61\]

the point is assigned to:

\[\boxed{C_2}\]

7.13.10 Objective Function

K-Means attempts to minimize the within-cluster sum of squared distances.

This is often called Within-Cluster Sum of Squares (WCSS) or inertia.

The objective is:

\[\boxed{ J= \sum_{k=1}^{K} \sum_{x_i\in C_k} |x_i-\mu_k|^2 }\]

where:

The algorithm tries to make this value as small as possible.

7.13.11 Why Squared Distance?

Squaring the distance:

Conceptually:

Point close to centroid

↓
Small error
Point far from centroid
↓
Large squared error

7.13.12 K-Means Example — Customer Segmentation

Suppose we have:

Customer Annual Income Spending Score
A 25 20
B 30 25
C 28 22
D 70 75
E 80 85
F 75 80
G 45 50
H 50 55

We choose:

\[K=3\]

These labels were not supplied to the algorithm.

The clusters were discovered from the feature patterns.

7.13.13 Choosing K

One of the biggest challenges in K-Means is determining the appropriate number of clusters.

Common approaches include:

7.13.14 Elbow Method

│\
│ \
│ \
│ \
│ \__
│ \__
└──────────── K
↑
Elbow

The elbow is a useful heuristic, not a guaranteed optimal answer.

7.13.15 Using the Elbow Method in Python

from sklearn.cluster import KMeans
inertias = []
for k in range(1, 11):
model = KMeans(
n_clusters=k,
random_state=42,
n_init=10
)
model.fit(X)
inertias.append(model.inertia_)
print(inertias)

You can plot K against inertia and look for an elbow.

7.13.16 Silhouette Score

Another useful metric is the Silhouette Score.

For an observation (i):

\[s(i)= \frac{b(i)-a(i)} {\max(a(i),b(i))}\]

where:

The score ranges approximately from:

\[-1 \text{ to } 1\]

Interpretation:

Score Interpretation
Near 1 Well-separated cluster
Near 0 Overlapping/boundary observation
Negative Potentially assigned to the wrong cluster

A higher average silhouette score is generally desirable.

7.13.17 Silhouette Score in Python

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
for k in range(2, 11):
model = KMeans(
n_clusters=k,
random_state=42,
n_init=10
)
labels = model.fit_predict(X)
score = silhouette_score(X, labels)
print(
"K =", k,
"Silhouette =", score
)

7.13.18 Initialization

K-Means++ chooses initial centroids in a way intended to spread them out and improve the starting point.

Example:

KMeans(
n_clusters=3,
init="k-means++",
random_state=42
)

7.13.19 n_init

Because K-Means can converge to different solutions depending on initialization, it is often useful to run the algorithm multiple times with different initializations.

n_init controls how many initializations are attempted.

Example:

KMeans(
n_clusters=3,
n_init=10,
random_state=42
)

The implementation selects the result with the best objective value among the runs.

7.13.20 Feature Scaling

Feature scaling can be very important for K-Means because it relies on distances.

Suppose:

Age → 20–70
Income → 20,000–2,000,000

Income could dominate the distance calculation.

A common solution is StandardScaler:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

Then:

model = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
model.fit(X_scaled)

7.13.21 Complete K-Means Example

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
df = pd.read_csv("customers.csv")
X = df[
    [
        "AnnualIncome",
        "SpendingScore"
]
]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
model = KMeans(
n_clusters=3,
n_init=10,
random_state=42
)
clusters = model.fit_predict(X_scaled)
df["Cluster"] = clusters
print(df.head())

7.13.22 Cluster Centers

After training:

print(model.cluster_centers_)

These are the centroids in the scaled feature space if the model was trained on scaled data.

If you need the centers in the original units:

centers_original = scaler.inverse_transform(
model.cluster_centers_
)
print(centers_original)

This is useful for interpreting clusters.

7.13.23 Predicting the Cluster of New Data

Once trained, we can assign new observations to the nearest learned centroid.

new_customer = [
[65000, 80]
]
new_customer_scaled = scaler.transform(
new_customer
)
cluster = model.predict(
new_customer_scaled
)
print("Cluster:", cluster)

The new customer is assigned to the closest existing cluster.

7.13.24 K-Means Is Unsupervised

This is an important distinction.

Therefore:

No Labels

↓
K-Means
↓
Discovered Clusters

7.13.25 K-Means vs Classification

Do not confuse clustering with classification.

Classification

Classes are known during training.

Customer Data

+

Known Labels

↓
Model
↓
Predicted Label
Clustering

Labels are not known.

Customer Data

↓
Clustering
↓
Discovered Groups

7.13.26 K-Means vs KNN

The names are similar, but they are completely different algorithms.

K-Means KNN
Unsupervised Supervised
Clustering Classification/regression
K = number of clusters K = number of neighbors
Learns centroids Uses training observations directly
No labels required Requires labels for supervised tasks
Used for segmentation Used for prediction

Memory trick:

K-Means

↓
K = Clusters
KNN
↓
K = Neighbors

7.13.27 K-Means vs Hierarchical Clustering

K-Means Hierarchical Clustering
Requires K in advance Can build hierarchy without initially fixing K
Produces flat clusters Produces hierarchy/tree
Uses centroids Uses pairwise distances/linkage
Usually faster for large datasets Can be computationally expensive
Good for large datasets Useful for dendrogram-based exploration
Sensitive to initialization Agglomerative results depend on linkage/distance choices

Hierarchical Clustering is covered in Section 7.14.

7.13.28 Limitations of K-Means

1. Need to Choose K

The number of clusters must generally be specified.

2. Sensitive to Initialization

Different initial centroids can produce different solutions.

3. Sensitive to Scaling

Features with larger scales can dominate distance calculations.

4. Sensitive to Outliers

Extreme points can pull centroids away from the main data.

5. Assumes Cluster Structure Suits the Objective

6. Categorical Data

Standard K-Means is designed for numerical feature spaces and Euclidean-style distance/objective functions.

7.13.29 Example of a Problematic Cluster Shape

Suppose the data looks like:

████████████

███

███

███

A centroid-based method may not identify this elongated structure effectively.

Other clustering methods can be more suitable depending on the shape and data characteristics.

7.13.30 Advantages of K-Means

1. Simple

Easy to understand and implement.

2. Fast

K-Means is computationally efficient for many datasets.

3. Scalable

It can work well on relatively large numerical datasets.

4. Easy to Interpret

Each cluster has a centroid that can be analyzed.

5. Useful for Segmentation

Commonly used for customer and product segmentation.

6. Flexible

Can be applied to many numerical clustering problems.

7.13.31 Real-World Applications

Customer Segmentation

Customers

↓
Age
Income
Spending
↓
K-Means
↓
Customer Segments
Image Compression
↓
K-Means
↓
256 Representative Colors

Document Clustering

Documents can be represented numerically using techniques such as TF-IDF or embeddings and then clustered based on similarity.

Anomaly Detection

K-Means itself is not primarily an anomaly-detection algorithm, but distance from cluster centroids can sometimes be used as one signal of unusual observations.

7.13.32 Practical Customer Segmentation Project

↓
Data Cleaning
↓
Select Numerical Features
↓
Handle Missing Values
↓
Scale Features
↓
Try K = 2 ... 10
↓
Elbow Method
+
Silhouette Score
↓
Select K
↓
Train K-Means
↓
Analyze Centroids
↓
Name Segments

The resulting clusters might be interpreted as:

Cluster 0 → Low-value occasional customers
Cluster 1 → High-value frequent customers
Cluster 2 → Discount-sensitive customers

The labels are assigned after analyzing the clusters; K-Means itself only produces cluster IDs.

7.13.33 Important Hyperparameters

Parameter Purpose
n_clusters Number of clusters
init Centroid initialization method
n_init Number of initialization attempts
max_iter Maximum iterations
tol Convergence tolerance
random_state Reproducibility

Example:

KMeans(
n_clusters=3,
init="k-means++",
n_init=10,
max_iter=300,
random_state=42
)

7.13.34 Interview Questions

Q1. What is K-Means?

K-Means is an unsupervised clustering algorithm that partitions numerical data into K clusters by minimizing within-cluster squared distances to centroids.

Q2. What does K represent?

The number of clusters.

Q3. Is K-Means supervised or unsupervised?

Unsupervised.

Q4. What is a centroid?

The mean position of observations assigned to a cluster.

Q5. What objective does K-Means minimize?

The within-cluster sum of squared distances, commonly called inertia or WCSS.

Q6. How do you choose K?

Common approaches include the Elbow Method, Silhouette Score, domain knowledge, and cluster stability analysis.

Q7. Why is scaling important?

K-Means uses distances, so features with larger numerical scales can dominate the clustering.

Q8. What happens if K is too small?

Distinct groups may be combined into the same cluster.

Q9. What happens if K is too large?

A natural group may be unnecessarily divided into multiple clusters, potentially producing overly fragmented segments.

Q10. Is K-Means sensitive to outliers?

Yes. Because centroids are means, extreme observations can significantly affect their positions.

7.13.35 Key Takeaways

Module 7 · Lesson 7.14

Hierarchical Clustering

7.14.1 Introduction

Hierarchical Clustering is an unsupervised machine learning algorithm used to group similar data points into clusters.

Unlike K-Means, hierarchical clustering creates a hierarchy of clusters that can be represented using a tree-like diagram called a dendrogram.

The main idea is:

Start with individual data points and progressively merge similar groups, or start with one large cluster and progressively split it.

The two major approaches are:

  1. Agglomerative Clustering — bottom-up

  2. Divisive Clustering — top-down

Agglomerative clustering is much more commonly used in practice.

7.14.2 Simple Example

|

┌────────┴────────┐
| |
Group 1 Group 2
/ \ / \
A B C F
\ /
D E

The hierarchy can then be visualized using a dendrogram.

7.14.3 What Is a Dendrogram?

A dendrogram is a tree-like visualization showing how observations or clusters are merged.

Example:

Distance

|

10| ┌───────────────┐
8| ┌────┤ │
6| ┌───┤ │ │
4| ┌──┤ │ │ ┌────┤
2| │ │ │ │ │ │

0| A B C D E F

+--------------------------------

The height at which two branches join represents the distance/dissimilarity at which the clusters were merged.

7.14.4 Agglomerative Clustering

Then the closest clusters are merged:

7.14.5 Agglomerative Algorithm

The basic algorithm is:

Start with each observation as its own cluster

↓
Calculate pairwise distances
↓
Find the closest two clusters
↓
Merge them
↓
Recalculate cluster distances
↓
Repeat
↓
One large hierarchy

After the hierarchy is created, we can choose a level at which to cut the dendrogram to obtain a desired number of clusters.

7.14.6 Divisive Clustering

Divisive clustering follows a top-down approach.

It starts with all observations in one cluster:

ABCDEFG

Then splits it:

ABCDEFG

/ \

/ \ / \

↓
One cluster
↓
Split
↓
Smaller clusters
↓
Split again

In practical machine learning workflows, agglomerative clustering is generally more common.

7.14.7 Distance Between Data Points

\[A=(x_1,y_1)\]

and:

\[B=(x_2,y_2)\]

the distance is:

\[d(A,B)= \sqrt{(x_1-x_2)^2+(y_1-y_2)^2}\]

Other distance metrics can also be used depending on the data.

7.14.8 Linkage

Once individual observations have been grouped into clusters, we need to determine:

How should the distance between two clusters be calculated?

This is controlled by the linkage method.

Important linkage methods include:

7.14.9 Single Linkage

Single linkage defines the distance between two clusters as the distance between their closest pair of observations.

\[d(A,B) \min d(A_i,B_j)\]

Conceptually:

A A A

\ ← Closest pair
B B B
Advantage

Can identify elongated or irregularly shaped clusters.

Disadvantage

Can suffer from the chaining effect.

7.14.10 Chaining Effect

Single linkage can create long chains:

● ●

● ●

Although the endpoints may not be very similar, intermediate points can connect them into one cluster.

This is called chaining.

7.14.11 Complete Linkage

Complete linkage uses the farthest pair of observations between two clusters.

\[d(A,B) \max d(A_i,B_j)\]

Conceptually:

A ● ● ● ● B

↑ ↑
Largest distance

Complete linkage tends to create relatively compact clusters.

7.14.12 Average Linkage

Average linkage calculates the average distance between all pairs of observations across the two clusters.

\[d(A,B) \frac{1}{|A||B|} \sum_{i\in A} \sum_{j\in B} d(i,j)\]

It provides a compromise between single and complete linkage.

7.14.13 Ward Linkage

Ward linkage merges clusters in a way that attempts to minimize the increase in within-cluster variance.

Conceptually:

Before Merge

↓
Cluster A + Cluster B
↓
Calculate increase in variance
↓
Choose merge causing smallest increase

Ward linkage is commonly used with Euclidean distance and is often effective for compact, roughly spherical clusters.

7.14.14 Linkage Comparison

Linkage Cluster Distance Typical Behavior
Single Minimum pairwise distance Can create chains
Complete Maximum pairwise distance Compact clusters
Average Average pairwise distance Balanced behavior
Ward Increase in within-cluster variance Compact, variance-oriented clusters

7.14.15 Example of Hierarchical Clustering

Suppose we have:

A = (1,1)

B = (2,1)

C = (5,5)

D = (6,5)

Distances:

A ↔︎ B → Small
C ↔︎ D → Small
A ↔︎ C → Large
A ↔︎ D → Large
B ↔︎ C → Large
B ↔︎ D → Large

The algorithm might first merge:

(A,B)

and:

(C,D)

Then:

(A,B) + (C,D)

The resulting hierarchy can be represented as:

┌──────────────┐
│ │
┌──┴──┐ ┌──┴──┐
A B C D

7.14.16 Cutting the Dendrogram

One major advantage of hierarchical clustering is that we can choose the number of clusters after constructing the hierarchy.

Suppose:

Distance

|

10| ┌─────────────┐
| │ │
8| ┌────┤ │
| │ │ │
6| ┌───┤ │ ┌────┤
| │ │ │ │ │
4| ┌──┤ │ │ │ │
| │ │ │ │ │ │

0| A B C D E F

If we cut horizontally at distance 5:

──────────── Cut

we might get:

Cluster 1 → A B
Cluster 2 → C D
Cluster 3 → E F

Thus:

The dendrogram allows us to explore different numbers of clusters without retraining the hierarchy from scratch.

7.14.17 Python Implementation

Scikit-learn provides AgglomerativeClustering.
from sklearn.cluster import AgglomerativeClustering
model = AgglomerativeClustering(
n_clusters=3,
linkage="ward"
)
labels = model.fit_predict(X)
print(labels)

The resulting labels might be:

\[0, 0, 1, 1, 2, 2\]

These numbers are simply cluster identifiers.

7.14.18 Feature Scaling

Like K-Means, hierarchical clustering can be highly affected by feature scales when distance-based methods are used.

Suppose:

Age → 20–70
Income → 20,000–2,000,000

Income can dominate Euclidean distance.

Therefore, standardization is often useful:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

Then:

model = AgglomerativeClustering(
n_clusters=3,
linkage="ward"
)
labels = model.fit_predict(X_scaled)

7.14.19 Creating a Dendrogram with SciPy

Scikit-learn's AgglomerativeClustering is useful for generating cluster labels, while SciPy provides convenient tools for building and visualizing dendrograms.
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt
Z = linkage(
X_scaled,
method="ward"
)
plt.figure(figsize=(12, 6))
dendrogram(Z)
plt.title("Hierarchical Clustering Dendrogram")
plt.xlabel("Data Points")
plt.ylabel("Distance")
plt.show()

7.14.20 Complete Example

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import AgglomerativeClustering
df = pd.read_csv("customers.csv")
X = df[
    [
        "AnnualIncome",
        "SpendingScore"
    ]
]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
model = AgglomerativeClustering(
    n_clusters=3,
    linkage="ward"
)
df["Cluster"] = model.fit_predict(X_scaled)
print(df.head())

7.14.21 Determining the Number of Clusters

Hierarchical clustering has an advantage over K-Means because the entire hierarchy is generated before selecting the final number of clusters.

You can use:

1. Dendrogram

Look for large vertical gaps.

2. Silhouette Score

Evaluate different numbers of clusters.

3. Domain Knowledge

Determine whether the resulting groups are meaningful.

4. Cluster Stability

Check whether clusters remain consistent under reasonable changes to the data or methodology.

7.14.22 Silhouette Score

The silhouette score can also be used for hierarchical clustering.

from sklearn.metrics import silhouette_score
score = silhouette_score(
X_scaled,
labels
)
print("Silhouette Score:", score)

Higher values generally indicate better-separated clusters, although interpretation should consider the specific dataset.

7.14.23 Hierarchical Clustering for Customer Segmentation

Suppose an e-commerce company has:

Customer

├── Age
├── Income
├── Orders
├── Spending
└── Website Visits

Hierarchical clustering can identify:

Customers

|

┌────────┴────────┐
│ │
Group A Group B
/ \ / \
A1 A2 B1 B2

The company can then analyze each cluster and assign business-friendly names such as:

Cluster A → Premium Customers
Cluster B → Regular Customers
Cluster C → Occasional Customers

Again, the algorithm does not know these business names; they are assigned through interpretation.

7.14.24 Hierarchical Clustering for Biology

↓
Expression Profiles
↓
Distance Calculation
↓
Hierarchical Clustering
↓
Dendrogram
↓
Groups of Similar Genes

A dendrogram can reveal groups of genes with similar expression patterns.

7.14.25 Hierarchical Clustering for Documents

Documents can be converted into numerical representations such as:

Then hierarchical clustering can identify groups:

Documents

↓
Vector Representation
↓
Distance/Similarity
↓
Hierarchical Clustering
↓
Document Hierarchy

For very high-dimensional text data, the choice of representation and distance metric is especially important.

7.14.26 Hierarchical Clustering vs K-Means

K-Means Hierarchical Clustering
Requires K before training Builds a hierarchy first
Produces flat clusters Produces hierarchy
Uses centroids Uses pairwise cluster distances
Usually faster Can be computationally expensive
Good for large datasets Better for exploratory analysis on smaller/moderate datasets
Sensitive to initialization Agglomerative method doesn't use random centroid initialization
Cluster structure not hierarchical Dendrogram provides hierarchy
Typically compact centroid-based clusters Depends strongly on linkage

7.14.27 Hierarchical Clustering vs K-Means Example

\[K=3\]

|

┌────────┴────────┐
│ │
AA BBCC
|
┌────┴────┐
BB CC

The hierarchy can reveal relationships between groups.

7.14.28 Advantages of Hierarchical Clustering

1. No Need to Choose K Initially

The hierarchy can be constructed before selecting the final cluster count.

2. Dendrogram Visualization

The dendrogram provides an intuitive visual representation of cluster relationships.

3. Useful for Exploratory Analysis

It helps discover nested or hierarchical structure.

4. Flexible Linkage Methods

Different linkage strategies can be chosen based on the data.

5. No Random Initialization for Standard Agglomerative Methods

Unlike K-Means, standard agglomerative clustering does not depend on randomly initialized centroids.

7.14.29 Limitations

1. Computational Cost

Naive hierarchical clustering can become expensive for very large datasets.

2. Sensitive to Distance Metric

An inappropriate distance measure can produce poor clusters.

3. Sensitive to Linkage

Different linkage methods can produce significantly different results.

4. Irreversible Merges

In standard agglomerative clustering, once two clusters are merged, that merge is not undone.

5. Sensitive to Noise and Outliers

Certain linkage methods can be strongly affected by unusual observations.

6. Scaling Matters

Distance-based clustering can be distorted by features on different scales.

7.14.30 Important Parameters in Scikit-learn

AgglomerativeClustering includes parameters such as:
Parameter Purpose
n_clusters Number of clusters to return
metric Distance metric
linkage Cluster linkage method
compute_full_tree Controls tree computation
distance_threshold Cut hierarchy at a specified distance

Example:

AgglomerativeClustering(
n_clusters=3,
metric="euclidean",
linkage="ward"
)

For ward linkage, Euclidean distance is required.

7.14.31 Using a Distance Threshold

Instead of directly specifying the number of clusters, some workflows use a distance threshold.

Conceptually:

model = AgglomerativeClustering(
distance_threshold=5,
n_clusters=None,
linkage="ward"
)

The hierarchy is cut according to the specified distance threshold.

This can be useful when the meaningful separation distance is more interpretable than a fixed number of clusters.

7.14.32 Interview Questions

Q1. What is hierarchical clustering?

An unsupervised clustering method that builds a hierarchy of clusters based on distances or similarities between observations.

Q2. What are the two major types?

Q3. Which is more commonly used?

Agglomerative clustering.

Q4. What is a dendrogram?

A tree-like visualization showing how observations or clusters are progressively merged or divided.

Q5. What is linkage?

A method for calculating the distance between clusters.

Q6. What is single linkage?

The distance between two clusters is based on the closest pair of observations.

Q7. What is complete linkage?

The distance is based on the farthest pair of observations.

Q8. What is Ward linkage?

It chooses merges that minimize the increase in within-cluster variance and is commonly used with Euclidean distance.

Q9. Does hierarchical clustering require K?

The hierarchy itself does not require choosing K beforehand; a final number of clusters can be selected by cutting the hierarchy. Some implementations such as Scikit-learn's AgglomerativeClustering allow either n_clusters or a distance threshold.

Q10. What is the main difference between K-Means and hierarchical clustering?

K-Means directly creates a specified number of centroid-based clusters, whereas hierarchical clustering builds a nested hierarchy that can be visualized using a dendrogram.

7.14.33 Key Takeaways

Module 7 · Lesson 7.15

PCA

7.15.1 Introduction

Principal Component Analysis (PCA) is an unsupervised dimensionality reduction technique used to transform a dataset with many potentially correlated features into a smaller number of new features called principal components.

↓
PCA
↓
10 principal components

Instead of working with 100 original variables, a machine learning model can work with 10 transformed variables while retaining a large proportion of the dataset's variance.

7.15.2 Why Do We Need PCA?

│
├── Age
├── Income
├── Spending
├── Purchases
├── Website Visits
├── Login Frequency
├── Mobile Usage
├── Email Opens
├── Discount Usage
├── ...
└── 100+ features

A large number of features can cause:

PCA can transform these features into a smaller set of components.

7.15.3 Simple Example

Suppose we have two highly correlated features:

Height

|

| ●

| ●

| ●

| ●

| ●

|●

+---------------- Height

Most of the variation lies along one direction.

PCA can represent much of this information using one principal component:

Height + Weight

↓
Principal Component 1

Instead of keeping both original dimensions, we might use one transformed dimension with relatively little information loss.

7.15.4 What Is a Principal Component?

A principal component is a new feature created as a weighted combination of the original features.

For example:

\[PC_1= 0.7X_1+ 0.5X_2- 0.2X_3\]

The coefficients are called loadings.

The first principal component captures the largest possible amount of variance subject to the PCA constraints.

The second component captures the largest remaining amount of variance while being orthogonal to the first, and so on.

7.15.5 Key Idea: Maximum Variance

PCA searches for directions in feature space where the data varies the most.

Suppose the data looks like:

↗
↗
↗
↗

That direction becomes the first principal component.

7.15.6 Principal Components

If we start with:

\[X_1,X_2,X_3,X_4\]

PCA can transform them into:

\[PC_1,PC_2,PC_3,PC_4\]

The components are ordered by the amount of variance they explain:

PC1 → Highest variance
PC2 → Second highest
PC3 → Third highest
PC4 → Lowest

Therefore, we can retain only the first few components.

7.15.7 Example

Suppose PCA produces:

Component Explained Variance
PC1 55%
PC2 25%
PC3 10%
PC4 5%
PC5 3%
PC6 2%

Cumulative variance:

PC1 → 55%
PC1 + PC2 → 80%
PC1 + PC2 + PC3 → 90%

If we want to preserve approximately 90% of the variance, we could retain:

\[\boxed{3\text{ components}}\]

instead of all 6.

7.15.8 Explained Variance

Explained variance tells us how much of the original data's variance is captured by each principal component.

For example:

PC1 → 60%
PC2 → 25%
PC3 → 10%
PC4 → 5%

Cumulative:

PC1 → 60%
PC1 + PC2 → 85%
PC1 + PC2 + PC3 → 95%
PC1 + PC2 + PC3 + PC4 → 100%

If 95% is sufficient, we can keep three components.

7.15.9 Explained Variance Ratio in Python

Using Scikit-learn:

from sklearn.decomposition import PCA
pca = PCA()
pca.fit(X_scaled)
print(pca.explained_variance_ratio_)

Example output:

\[0.55, 0.25, 0.10, 0.05, 0.03, 0.02\]

The values add up to approximately:

\[1.0\]

or:

\[100%\]

7.15.10 Cumulative Explained Variance

import numpy as np
cumulative_variance = np.cumsum(
pca.explained_variance_ratio_
)
print(cumulative_variance)

Example:

\[0.55, 0.80, 0.90, 0.95, 0.98, 1.00\]

This helps determine how many components to retain.

7.15.11 PCA Requires Feature Scaling

Feature scaling is usually extremely important before PCA.

Suppose:

Age → 20–70
Income → 20,000–2,000,000

PCA is based on variance and covariance.

The feature with the larger numerical scale could dominate the calculation.

Therefore, a common workflow is:

Raw Data

↓
Handle Missing Values
↓
StandardScaler
↓
PCA
↓
Reduced Dataset

Example:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

Then:

pca = PCA(
n_components=2
)
X_pca = pca.fit_transform(X_scaled)

7.15.12 StandardScaler + PCA

A complete example:

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
pca = PCA(
n_components=2
)
X_pca = pca.fit_transform(X_scaled)
print(X_pca.shape)

7.15.13 PCA Mathematical Intuition

PCA is closely related to the covariance matrix.

Suppose the standardized dataset has features:

\[X_1,X_2,\ldots,X_n\]

PCA examines how these features vary together.

The covariance matrix is:

\[\Sigma= \begin{bmatrix} Cov(X_1,X_1) & Cov(X_1,X_2) & \cdots\ Cov(X_2,X_1) & Cov(X_2,X_2) & \cdots\ \vdots & \vdots & \ddots \end{bmatrix}\]

PCA finds the eigenvectors and eigenvalues of this covariance matrix.

7.15.14 Eigenvectors

↓
Eigenvectors
↓
Principal Component Directions

For example:

Eigenvector 1 → PC1 direction
Eigenvector 2 → PC2 direction
Eigenvector 3 → PC3 direction

7.15.15 Eigenvalues

The eigenvalues represent how much variance is captured by the corresponding principal component.

For example:

Eigenvalue 1 → 5.5
Eigenvalue 2 → 2.5
Eigenvalue 3 → 1.0

The larger the eigenvalue, the more variance the component captures.

Therefore:

Largest eigenvalue

↓
PC1
Second largest
↓
PC2

7.15.16 PCA Mathematical Process

A simplified PCA workflow is:

Original Dataset

↓
Center / Standardize Data
↓
Calculate Covariance Matrix
↓
Calculate Eigenvectors
and Eigenvalues
↓
Sort by Eigenvalue
↓
Select Top Components
↓
Project Data
↓
Reduced Dataset

Modern numerical implementations may use Singular Value Decomposition (SVD) directly rather than explicitly computing the covariance matrix.

7.15.17 Centering the Data

Before PCA, the data is generally centered.

For each feature:

\[X_{centered}=X-\mu\]

where:

\[\mu=\text{feature mean}\]

StandardScaler goes further by also dividing by the standard deviation:
    \[Z= \frac{X-\mu}{\sigma}\]

This gives each feature approximately zero mean and unit variance.

7.15.18 PCA Transformation

Suppose:

\[X\]

is the centered data matrix.

Let:

\[W\]

contain the selected principal component directions.

Then the transformed data is:

\[\boxed{ Z=XW }\]

where (Z) is the lower-dimensional representation.

7.15.19 PCA Is a Linear Transformation

Standard PCA produces linear combinations of the original features.

For example:

\[PC_1= 0.6X_1+ 0.5X_2+ 0.3X_3\]

Therefore, PCA is a linear dimensionality reduction technique.

For strongly nonlinear structures, other dimensionality-reduction techniques may be more appropriate.

7.15.20 PCA for Visualization

One of the most common uses of PCA is reducing high-dimensional data to two or three dimensions for visualization.

Then we can plot:

PC2

|

| ● ●

| ●

|

| ▲ ▲

| ▲

|

+------------------------- PC1

This can help reveal:

However, a 2D PCA plot can hide important information that exists in discarded components.

7.15.21 PCA Visualization in Python

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
plt.scatter(
X_pca[:, 0],
X_pca[:, 1]
)
plt.xlabel("PC1")
plt.ylabel("PC2")
plt.show()

7.15.22 PCA and Machine Learning

PCA can be used before a machine learning model:

Original Features

↓
Scaling
↓
PCA
↓
Reduced Features
↓
Machine Learning Model
↓
Prediction

For example:

100 Features

↓
PCA
↓
20 Components
↓
Logistic Regression

This can reduce computational complexity and sometimes improve generalization.

However, PCA does not automatically improve model performance; it should be validated against a suitable baseline.

7.15.23 PCA with Logistic Regression

Example:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
model = Pipeline([
("scaler", StandardScaler()),
("pca", PCA(n_components=10)),
("classifier", LogisticRegression())
])
model.fit(X_train, y_train)
predictions = model.predict(X_test)

Using a pipeline is important because PCA must be fitted only on the training data during model evaluation.

7.15.24 PCA and K-Means

PCA can also be combined with clustering.

High-Dimensional Data

↓
Scaling
↓
PCA
↓
Reduced Features
↓
K-Means
↓
Clusters

Example:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
model = Pipeline([
("scaler", StandardScaler()),
("pca", PCA(n_components=2)),
("kmeans", KMeans(
n_clusters=3,
random_state=42,
n_init=10
))
])
model.fit(X)

PCA can help when the original feature space contains many correlated dimensions, but reducing to only two components may discard information, so the number of components should be chosen carefully.

7.15.25 Selecting Number of Components

There are several approaches.

1. Explained Variance

Keep enough components to capture a target percentage, such as:

pca = PCA(
n_components=0.95
)

This tells PCA to retain enough components to explain approximately 95% of the variance.

2. Scree Plot

Plot eigenvalues or explained variance against component number.

Variance

|

|\

| \

| \

| \__

| \___

+---------------- Components

↑
Elbow

A sharp drop followed by a flatter region can suggest a reasonable cutoff.

7.15.26 PCA Loadings

Income → 0.70
Spending → 0.65
Purchases → 0.30
Age → 0.05

This suggests that PC1 is strongly associated with income and spending.

In Scikit-learn:

print(pca.components_)

Each row corresponds to a principal component.

7.15.27 Interpreting Components

We might interpret PC1 as something like:

7.15.28 PCA and Multicollinearity

PCA can combine correlated information into fewer orthogonal components.

The principal components are uncorrelated under the standard PCA construction.

7.15.29 PCA and Information Loss

The discarded 90 components contain some variance.

The objective is to discard relatively less important variation while retaining the major patterns.

Therefore:

PCA is a compression technique, not a lossless transformation when components are discarded.

7.15.30 Inverse Transform

)

If only some components are retained, the reconstruction will generally be approximate.

The reconstruction error reflects information lost through dimensionality reduction.

7.15.31 PCA for Image Compression

↓
Pixel Matrix
↓
PCA
↓
Reduced Components
↓
Compressed Representation

The image can then be approximately reconstructed from fewer components.

This demonstrates the idea of dimensionality reduction.

7.15.32 PCA for Noise Reduction

Suppose important information is concentrated in the first few components while noise appears more strongly in later components.

Then we can:

Original Data

↓
PCA
↓
Keep important components
↓
Discard low-variance components
↓
Reconstruct
↓
Reduced Noise

However, low variance does not automatically mean noise; useful information can also have low variance.

7.15.33 Advantages of PCA

1. Reduces Dimensionality

Transforms many features into fewer components.

2. Reduces Redundancy

Can combine correlated variables.

3. Helps Visualization

Makes 2D/3D visualization of high-dimensional data possible.

4. Can Reduce Computational Cost

Fewer features can make downstream models faster.

5. Can Help with Multicollinearity

Principal components are orthogonal in standard PCA.

6. Useful for Data Compression

A smaller number of components can represent much of the original variation.

7.15.34 Limitations of PCA

1. Components Are Less Interpretable

Original features may have clear meanings, while PC1 and PC2 are combinations of many variables.

2. Sensitive to Scaling

Features with larger scales can dominate PCA if scaling is inappropriate.

3. Linear Technique

Standard PCA cannot naturally capture nonlinear relationships.

4. Variance Is Not Always the Same as Predictive Importance

A low-variance feature may still be highly predictive of the target.

5. Information Loss

Discarding components removes some information.

6. Can Complicate Model Interpretation

A model trained on principal components is harder to explain in terms of original business features.

7.15.35 PCA vs Feature Selection

These are often confused.

Feature Selection

Selects a subset of the original features.

Example:

100 Features

↓
Select
↓
10 Original Features
PCA

Creates new transformed features.

100 Features

↓
PCA
↓
10 Principal Components

Comparison:

Feature Selection PCA
Keeps original features Creates new features
Easier to interpret Components less interpretable
Removes features Combines information
Can retain business meaning May lose direct feature meaning
Useful when feature identity matters Useful for compression/correlation reduction

Feature Selection is covered in Section 7.16.

7.15.36 PCA vs K-Means

PCA K-Means
Dimensionality reduction Clustering
Unsupervised Unsupervised
Creates components Creates clusters
No cluster labels Produces cluster assignments
Maximizes retained variance Minimizes within-cluster squared distances
Often used before clustering Can be applied after PCA

7.15.37 PCA vs t-SNE

Both can be used for dimensionality reduction and visualization, but they have different goals.

PCA t-SNE
Linear Nonlinear
Preserves global variance structure Focuses strongly on local neighborhood structure
Deterministic under fixed preprocessing/solver conditions Often sensitive to initialization/settings
Faster and more suitable for preprocessing Primarily visualization
Easier to transform new data with standard workflows Standard t-SNE is not generally used as a simple production preprocessing transform

7.15.38 Complete PCA Example

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
df = pd.read_csv("customers.csv")
X = df[
    [
        "Age",
        "Income",
        "Spending",
        "Orders",
        "Visits"
    ]
]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
pca = PCA(
    n_components=0.95
)
X_pca = pca.fit_transform(X_scaled)
print(
    "Original dimensions:",
    X.shape[1]
)
print(
    "Reduced dimensions:",
    X_pca.shape[1]
)
print(
    "Explained variance:",
    pca.explained_variance_ratio_
)
print(
    "Cumulative variance:",
    pca.explained_variance_ratio_.cumsum()
)

7.15.39 PCA Workflow

A typical PCA workflow is:

Raw Dataset

↓
Understand Features
↓
Handle Missing Values
↓
Select Numerical Features
↓
Scale / Standardize
↓
Fit PCA on Training Data
↓
Examine Explained Variance
↓
Choose Number of Components
↓
Transform Data
↓
Train Model / Visualize
↓
Evaluate

For supervised machine learning, PCA should generally be fitted inside the training process/pipeline to avoid data leakage.

7.15.40 Interview Questions

Q1. What is PCA?

PCA is an unsupervised linear dimensionality reduction technique that transforms correlated features into a smaller set of orthogonal principal components.

Q2. What is the first principal component?

The direction that captures the maximum possible variance in the data.

Q3. What is the second principal component?

The direction capturing the largest remaining variance while being orthogonal to the first component.

Q4. What are eigenvectors in PCA?

They represent the directions of the principal components.

Q5. What do eigenvalues represent?

They indicate the amount of variance captured by the corresponding principal components.

Q6. Why is scaling important?

PCA is variance-based, so features with larger scales can dominate the analysis.

Q7. How do you choose the number of components?

Common approaches include explained variance, cumulative explained variance, scree plots, and downstream model validation.

Q8. Does PCA use the target variable?

Standard PCA is unsupervised and does not use the target variable when finding components.

Q9. Does PCA always improve model accuracy?

No. It can improve, worsen, or have little effect depending on the dataset and model.

Q10. What is the difference between PCA and feature selection?

Feature selection keeps a subset of original features; PCA creates new features that are linear combinations of the originals.

7.15.41 Key Takeaways

Module 7 · Lesson 7.16

Feature Selection

7.16.1 Introduction

Feature Selection is the process of identifying the most useful input variables for a machine learning model and removing features that are irrelevant, redundant, or noisy.

For example, suppose a dataset contains:

Customer Data

│
├── Age
├── Income
├── Purchase Frequency
├── Total Spending
├── Website Visits
├── Customer ID
├── Random Number
├── Duplicate Feature
└── Unrelated Column
↓
Feature Selection
↓
Age
Income
Purchase Frequency
Total Spending
Website Visits

The goal is to build a model using a smaller and more useful set of original features.

7.16.2 Why Feature Selection Is Important

A dataset can contain hundreds or thousands of features.

Some may be:

Using unnecessary features can lead to:

Feature selection attempts to keep the useful information while removing unnecessary variables.

7.16.3 Feature Selection vs Feature Extraction

↓
Feature Selection
↓
Age
Income
Spending

The features remain recognizable.

Feature Extraction

↓
PCA
↓
PC1
PC2

Comparison:

Feature Selection Feature Extraction
Keeps original variables Creates new variables
Better interpretability Often less interpretable
Removes unnecessary features Transforms existing information
Example: SelectKBest Example: PCA

7.16.4 Example

The final choice should be based on domain knowledge, data analysis, validation, and the modeling objective.

7.16.5 Types of Feature Selection

Feature selection methods are generally divided into three major categories:

  1. Filter Methods

  2. Wrapper Methods

  3. Embedded Methods

Feature Selection

│
├── Filter
│
├── Wrapper
│
└── Embedded

7.16.6 Filter Methods

Filter methods evaluate features using statistical properties of the data, generally without training the final machine learning model for every candidate subset.

Examples:

They are usually fast and scalable.

7.16.7 Variance Threshold

A feature with almost no variation may contain little useful information.

Example:

\[0\]

This feature does not distinguish observations.

VarianceThreshold can remove low-variance features.

from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold(
threshold=0.01
)
X_selected = selector.fit_transform(X)

The threshold should be chosen according to the feature scale and problem; it is not a universal value.

7.16.8 Correlation-Based Selection

\[r=0.99\]

correlation_matrix = df.corr(numeric_only=True)
print(correlation_matrix)

A high correlation does not automatically mean one feature should be removed. The decision depends on the model, target relationship, business meaning, and other features.

7.16.9 Correlation with the Target

Income and Tenure may be more promising than Random ID.

However:

Low correlation does not necessarily mean a feature is useless.

A feature can have a nonlinear relationship with the target while having low linear correlation.

7.16.10 Chi-Square Test

The Chi-Square test can be useful for selecting categorical/non-negative features in classification problems.

It tests whether a feature and the target have a statistically significant association.

In Scikit-learn:

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
selector = SelectKBest(
score_func=chi2,
k=5
)
X_selected = selector.fit_transform(
X,
y
)

Important:

chi2 requires non-negative feature values.

Therefore, raw features may need suitable preprocessing before applying it.

7.16.11 ANOVA F-Test

For classification with numerical features, ANOVA F-test can be used to assess whether feature values differ systematically across target classes.

Scikit-learn provides:

from sklearn.feature_selection import f_classif
selector = SelectKBest(
score_func=f_classif,
k=5
)

This is a univariate method: each feature is evaluated individually with respect to the target.

7.16.12 Mutual Information

Mutual Information (MI) measures the amount of information one variable provides about another.

It can capture some nonlinear relationships, unlike simple Pearson correlation.

For classification:

from sklearn.feature_selection import mutual_info_classif
selector = SelectKBest(
score_func=mutual_info_classif,
k=10
)

For regression:

from sklearn.feature_selection import mutual_info_regression
selector = SelectKBest(
score_func=mutual_info_regression,
k=10
)

7.16.13 Wrapper Methods

↓
Choose Subset
↓
Train Model
↓
Evaluate
↓
Change Subset
↓
Train Again
↓
Compare Results

They can provide better task-specific selections but are usually more computationally expensive.

Common wrapper techniques include:

7.16.14 Forward Selection

Forward selection starts with no features.

Start:

[]

Add best feature:

[A]

Add next best:

\[A, C\]

Add next:

\[A, C, D\]

At each step, the feature that provides the best improvement according to the chosen evaluation criterion is added.

7.16.15 Backward Elimination

Backward elimination starts with all features.

\[A B C D E F\]

↓
Remove least useful
↓
[A B C D E]
↓
Remove another
↓
[A B C E]

The process continues until a desired number of features or performance criterion is reached.

7.16.16 Recursive Feature Elimination — RFE

Recursive Feature Elimination (RFE) repeatedly trains a model and removes the least important features.

Workflow:

All Features

↓
Train Model
↓
Rank Features
↓
Remove Least Important
↓
Train Again
↓
Repeat
↓
Selected Features

Example:

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(
max_iter=1000
)
selector = RFE(
estimator=model,
n_features_to_select=5
)
selector.fit(X_train, y_train)

7.16.17 RFECV

RFECV extends RFE by using cross-validation to help determine how many features to retain.

from sklearn.feature_selection import RFECV
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(
max_iter=1000
)
selector = RFECV(
estimator=model,
cv=5,
scoring="accuracy"
)
selector.fit(X_train, y_train)

This can be more robust than manually choosing the number of features, but it requires additional computation.

7.16.18 Embedded Methods

Embedded methods perform feature selection during model training.

Examples:

The model itself identifies features that are useful.

7.16.19 L1 Regularization

\[Loss+\lambda\sum_j|w_j|\]

where:

L1 regularization can force some coefficients exactly to zero.

Feature A → 1.25
Feature B → 0.72
Feature C → 0
Feature D → -0.91
Feature E → 0

Features C and E can therefore be removed.

7.16.20 Lasso Regression

For regression, L1 regularization is commonly associated with Lasso Regression.

from sklearn.linear_model import Lasso
model = Lasso(
alpha=0.1
)
model.fit(X_train, y_train)

Features with coefficients equal to zero are excluded from the fitted linear prediction.

7.16.21 Logistic Regression with L1

For classification:

from sklearn.linear_model import LogisticRegression
model = LogisticRegression(
penalty="l1",
solver="liblinear"
)
model.fit(X_train, y_train)

The coefficients can be inspected:

print(model.coef_)
Features whose coefficients are zero can be considered excluded by the regularized model.

7.16.22 Tree-Based Feature Selection

Tree-based models can provide feature importance measures.

For example:

from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=200,
random_state=42
)
model.fit(X_train, y_train)
importance = model.feature_importances_
print(importance)

Example:

A threshold can then be used to select features.

However, impurity-based tree importance can be biased in some situations, particularly with high-cardinality or continuous features. Permutation importance can provide a useful complementary analysis.

7.16.23 Permutation Importance

Permutation importance measures how much model performance decreases when a feature's values are randomly shuffled.

Conceptually:

Original Model Performance

↓
Shuffle Feature A
↓
Performance decreases significantly
↓
Feature A is likely important

If shuffling a feature has almost no effect:

Feature B shuffled

↓
Performance barely changes
↓
Feature B may contribute little

Example:

from sklearn.inspection import permutation_importance
result = permutation_importance(
model,
X_test,
y_test,
n_repeats=10,
random_state=42
)
print(result.importances_mean)

Permutation importance should be interpreted carefully when features are strongly correlated: shuffling one correlated feature may have little impact because another feature contains similar information.

7.16.24 SelectKBest

SelectKBest selects the top K features according to a scoring function.

Example:

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classif
selector = SelectKBest(
score_func=f_classif,
k=10
)
X_train_selected = selector.fit_transform(
X_train,
y_train
)
X_test_selected = selector.transform(
X_test
)

Important:

Training data

↓
fit_transform()
Test data
↓
transform()

The selector should not be fitted on the test set.

7.16.25 Selecting All Features Above a Percentile

Instead of specifying an exact number of features, we can use a percentile.

from sklearn.feature_selection import SelectPercentile
from sklearn.feature_selection import f_classif
selector = SelectPercentile(
score_func=f_classif,
percentile=20
)

This retains approximately the top 20% of features according to the scoring method.

7.16.26 Feature Selection Pipeline

A production-style approach is to place feature selection inside a pipeline.

from sklearn.pipeline import Pipeline
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classif
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
pipeline = Pipeline([
("selector", SelectKBest(
score_func=f_classif,
k=10
)),
("scaler", StandardScaler()),
("model", LogisticRegression())
])
pipeline.fit(
X_train,
y_train
)
predictions = pipeline.predict(
X_test
)

This is particularly important during cross-validation because feature selection must be performed independently within each training fold.

7.16.27 Data Leakage in Feature Selection

This is a very important machine learning concept.

Incorrect:

Entire Dataset

↓
Feature Selection
↓
Train/Test Split
↓
Train/Test Split
↓
Training Data → Fit Feature Selector
↓
Training Data → Transform
Test Data → Transform

Even better for model evaluation:

Cross-Validation

↓
Feature Selection
inside each training fold
↓
Model

A Scikit-learn pipeline makes this much easier to implement correctly.

7.16.28 Feature Selection for Classification

Suppose the target is:

Churn

0 → No
1 → Yes

The selected feature subset should be evaluated using the appropriate classification metric.

7.16.29 Feature Selection for Regression

Evaluation metrics might include:

7.16.30 Feature Selection Example

↓
Less Computation
↓
Simpler Model
↓
Better Interpretability
↓
Potentially Better Generalization

The last benefit is not guaranteed and should be verified using validation data.

7.16.31 Feature Selection and Overfitting

↓
Excellent Performance
New Data
↓
Poor Performance

Removing irrelevant features can reduce the opportunity for the model to fit noise.

7.16.32 Feature Selection and Interpretability

This is easier to explain than a model using 500 variables.

7.16.33 Feature Selection and Model Performance

Feature selection can have three possible effects:

Improvement

Remove Noise

↓
Better Generalization
No Significant Change
Removed Features
↓
Mostly Redundant
↓
Performance Similar
Performance Decrease
Removed Features
↓
Useful Information Lost
↓
Worse Performance

Therefore, feature selection should always be validated empirically.

7.16.34 Feature Selection Methods Comparison

Method Type Speed Model Dependent? Common Use
Variance Threshold Filter Fast No Remove near-constant features
Correlation Filter Fast No Remove redundant linear relationships
Chi-Square Filter Fast No Categorical/non-negative features
ANOVA Filter Fast No Classification
Mutual Information Filter Moderate No Nonlinear relationships
Forward Selection Wrapper Slow Yes Feature subset search
Backward Elimination Wrapper Slow Yes Feature subset search
RFE Wrapper Slow Yes Model-specific selection
L1 Embedded Fast/Moderate Yes Sparse linear models
Tree Importance Embedded Moderate Yes Tree-based models

7.16.35 Filter vs Wrapper vs Embedded

Filter

Data

↓
Statistical Test
↓
Selected Features
↓
Model
↓
Train Model
↓
Evaluate
↓
Try Another Subset
↓
Repeat
↓
Model Training
↓
Feature Importance / Coefficients
↓
Selected Features

Selection happens as part of model fitting.

7.16.36 Real-World Example — Credit Risk

Important:

But in regulated applications, feature removal should also be evaluated against fairness, policy, and compliance requirements.

7.16.37 Real-World Example — Machine Learning Pipeline

A typical pipeline could be:

Raw Data

↓
Data Cleaning
↓
Train/Test Split
↓
Feature Engineering
↓
Feature Selection
↓
Model Training
↓
Cross Validation
↓
Hyperparameter Tuning
↓
Final Evaluation
↓
Deployment

Feature selection should be part of the reproducible training process rather than an informal manual step performed using the entire dataset.

7.16.38 Important Interview Questions

Q1. What is feature selection?

Feature selection is the process of selecting the most relevant original features for a machine learning model and removing unnecessary or redundant features.

Q2. What are the three main types?

Q3. What is the difference between feature selection and PCA?

Feature selection keeps original variables. PCA creates new variables called principal components.

Q4. What is RFE?

Recursive Feature Elimination repeatedly trains a model, ranks features, removes the least important ones, and continues until the desired feature subset remains.

Q5. What is L1 feature selection?

L1 regularization can drive some model coefficients exactly to zero, effectively removing those features from the model.

Q6. What is SelectKBest?

It selects the top K features according to a specified statistical scoring function.

Q7. Can correlation be used for feature selection?

Yes, especially to identify redundant numerical features, but correlation alone should not be treated as a universal feature-importance measure.

Q8. Why is feature selection performed only on training data during evaluation?

To prevent data leakage from the validation/test data.

Q9. Can feature selection reduce overfitting?

Yes, removing irrelevant or noisy features can reduce model complexity and sometimes improve generalization.

Q10. Does feature selection always improve accuracy?

No. Removing useful features can reduce performance, so the selected feature set should be validated.

7.16.39 Key Takeaways

Module 7 · Lesson 7.17

Cross Validation

7.17.1 Introduction

Cross Validation (CV) is a model evaluation and selection technique used to estimate how well a machine learning model will perform on unseen data.

Instead of relying on only one train/test split, cross-validation repeatedly divides the training data into different training and validation sets.

The basic idea is:

Train the model on one portion of the data and validate it on another portion, repeating this process several times.

This provides a more reliable estimate of model performance.

7.17.2 Why Do We Need Cross Validation?

Training → 8,000
Testing → 2,000

The model performs:

Training Accuracy → 96%
Test Accuracy → 82%

7.17.3 Basic Idea

Suppose we have 100 observations.

With 5-fold cross-validation, we divide the training data into five groups:

Fold 1 → 20 observations
Fold 2 → 20 observations
Fold 3 → 20 observations
Fold 4 → 20 observations
Fold 5 → 20 observations

Then:

Round 1:

Train → Fold 2 + 3 + 4 + 5
Validate → Fold 1

Round 2:

Train → Fold 1 + 3 + 4 + 5
Validate → Fold 2

Round 3:

Train → Fold 1 + 2 + 4 + 5
Validate → Fold 3

Round 4:

Train → Fold 1 + 2 + 3 + 5
Validate → Fold 4

Round 5:

Train → Fold 1 + 2 + 3 + 4
Validate → Fold 5

Every observation is used for validation exactly once.

7.17.4 K-Fold Cross Validation

\[K=5\]

The model is trained and evaluated five times.

The final score is usually the average of the five validation scores.

7.17.5 Example

Suppose a model produces:

Fold Accuracy
Fold 1 90%
Fold 2 88%
Fold 3 92%
Fold 4 89%
Fold 5 91%

Mean accuracy:

\[\frac{90+88+92+89+91}{5}\]

\[=\frac{450}{5}\]

\[=\boxed{90%}\]

So we can report:

Cross-validation accuracy ≈ 90%

7.17.6 Standard K-Fold Workflow

Training Data

↓
Divide into K folds
↓
┌──────────────────────┐
│ Fold 1 → Validation │
│ Fold 2-5 → Training │
└──────────────────────┘
↓
┌──────────────────────┐
│ Fold 2 → Validation │
│ Others → Training │
└──────────────────────┘
↓

...

↓
┌──────────────────────┐
│ Fold K → Validation │
│ Others → Training │
└──────────────────────┘
↓
Average Scores

7.17.7 Why Not Use the Test Set for Cross Validation?

↓
Train/Test Split
↓
Training Data
↓
Cross Validation
↓
Model Selection
↓
Hyperparameter Tuning
↓
Final Model
↓
Test Set
↓
Final Evaluation

The test set acts as an independent estimate of performance after the modeling decisions are complete.

7.17.8 Cross Validation Example in Scikit-learn

from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(
    max_iter=1000
)
scores = cross_val_score(
    model,
    X_train,
    y_train,
    cv=5,
    scoring="accuracy"
)
print("Scores:", scores)
print(
    "Mean Accuracy:",
    scores.mean()
)

Example:

Scores:

\[0.90 0.88 0.92 0.89 0.91\]

Mean:

0.90

7.17.9 Standard Deviation of CV Scores

The mean score tells us average performance.

The standard deviation tells us how much performance varies across folds.

print("Mean:", scores.mean())
print("Std:", scores.std())

Suppose:

\[Mean=0.90\]

and:

\[Std=0.015\]

We could summarize:

Accuracy = 90% ± 1.5%

A large standard deviation can indicate that model performance is sensitive to which observations are used for validation.

7.17.10 Choosing K

10-Fold

Advantages:

Disadvantage:

There is no universally optimal K.

7.17.11 Very Small K

Suppose:

\[K=2\]

The model is trained on approximately half the data and validated on the other half in each round.

This provides fewer validation rounds and can produce a less stable estimate depending on the dataset.

7.17.12 Very Large K

Suppose:

\[K=n\]

Training → All observations except one
Validation → One observation

This can be computationally expensive.

7.17.13 Stratified K-Fold Cross Validation

For classification problems, especially with imbalanced classes, ordinary K-Fold may accidentally produce folds with different class proportions.

Stratified K-Fold attempts to preserve class proportions in each fold.

Example:

Suppose the dataset contains:

Class 0 → 80%
Class 1 → 20%

Stratified K-Fold tries to keep approximately:

Each Fold:

Class 0 → ~80%
Class 1 → ~20%

This is usually preferred for classification tasks.

7.17.14 StratifiedKFold in Python

from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
cv = StratifiedKFold(
n_splits=5,
shuffle=True,
random_state=42
)
scores = cross_val_score(
model,
X_train,
y_train,
cv=cv,
scoring="accuracy"
)
print(scores)
print(scores.mean())

7.17.15 Why Use shuffle=True?

If the data is ordered in some meaningful way, simply dividing it into consecutive folds can produce biased folds.

For example:

Rows 1–100 → Class A
Rows 101–200 → Class B
Rows 201–300 → Class C

Use a fixed random_state when you want reproducible results.

For time-series data, however, random shuffling is generally inappropriate; specialized time-series validation should be used instead.

7.17.16 Regression Cross Validation

For regression, the target is continuous.

Example:

...

Standard K-Fold is commonly used:

from sklearn.model_selection import KFold
cv = KFold(
n_splits=5,
shuffle=True,
random_state=42
)

7.17.17 Choosing the Correct Scoring Metric

Cross-validation is only as useful as the metric used to evaluate the model.

The metric should reflect the actual business objective.

For example, if missing a positive case is expensive, recall may be more important than accuracy.

7.17.18 Cross Validation for Hyperparameter Tuning

Cross-validation is heavily used for selecting hyperparameters.

Suppose we are training a KNN model.
↓
5-Fold CV
↓
Mean Score
K = 5
↓
5-Fold CV
↓
Mean Score
K = 7
↓
5-Fold CV
↓
Mean Score

Choose the hyperparameter with the best validation performance according to the selected metric.

7.17.19 GridSearchCV

Scikit-learn provides GridSearchCV for systematic hyperparameter search.

Example:

from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier()
params = {
"n_neighbors": [3, 5, 7, 9],
"weights": ["uniform", "distance"]
}
grid = GridSearchCV(
estimator=model,
param_grid=params,
cv=5,
scoring="accuracy"
)
grid.fit(X_train, y_train)
print(grid.best_params_)
print(grid.best_score_)

best_score_ is the best mean cross-validation score found during the search.

7.17.20 RandomizedSearchCV

Grid search can become expensive when there are many hyperparameters.

RandomizedSearchCV evaluates a selected number of randomly sampled parameter combinations.

from sklearn.model_selection import RandomizedSearchCV
search = RandomizedSearchCV(
estimator=model,
param_distributions=params,
n_iter=20,
cv=5,
scoring="accuracy",
random_state=42
)
search.fit(X_train, y_train)

This can be much more efficient for large hyperparameter spaces.

7.17.21 Cross Validation and Feature Selection

↓
Select Features
↓
Cross Validation
├── Training portion
│ ↓
│ Feature Selection
│ ↓
│ Model
│
└── Validation portion
↓
Transform
↓
Evaluate

A Scikit-learn pipeline handles this properly.

7.17.22 Cross Validation with a Pipeline

Example:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classif
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
pipeline = Pipeline([
("scaler", StandardScaler()),
("selector", SelectKBest(
f_classif,
k=10
)),
("model", LogisticRegression(
max_iter=1000
))
])
scores = cross_val_score(
pipeline,
X_train,
y_train,
cv=5,
scoring="accuracy"
)
print(scores.mean())

This ensures preprocessing and feature selection are fitted separately within each fold.

7.17.23 Nested Cross Validation

When hyperparameter tuning and performance estimation must be kept strictly separate, Nested Cross Validation can be used.

It has two loops:

Outer CV

│
├── Training data
│ ↓
│ Inner CV
│ ↓
│ Hyperparameter tuning
│ ↓
│ Best model
│
└── Outer validation
↓
Performance estimate
Inner Loop

Used for:

Outer Loop

Used for:

Nested CV is particularly useful when you need an unbiased estimate of performance after extensive model selection.

7.17.24 Nested CV Example

Conceptually:

Complete Training Dataset

↓
Outer CV
/ | \

Fold1 Fold2 Fold3 ...

↓
Inner CV
↓
Tune Hyperparameters
↓
Train Best Model
↓
Evaluate on Outer Fold

Nested CV can be computationally expensive because many models are trained.

7.17.25 Leave-One-Out Cross Validation

Train → B C D E
Test → A
Train → A C D E
Test → B
Train → A B D E
Test → C
Train → A B C E
Test → D
Train → A B C D
Test → E

Advantages:

Disadvantages:

7.17.26 Group K-Fold

Sometimes observations are grouped.

Example:

Patient A → 10 records
Patient B → 15 records
Patient C → 12 records

If records from the same patient appear in both training and validation sets, the model may effectively see information about the same patient during training and validation.

This can cause leakage.

GroupKFold keeps groups together.

from sklearn.model_selection import GroupKFold
cv = GroupKFold(
n_splits=5
)
scores = cross_val_score(
model,
X,
y,
groups=patient_ids,
cv=cv
)

The exact grouping variable depends on the problem.

7.17.27 Time Series Cross Validation

Standard K-Fold is usually inappropriate for time-series data because it can train on future observations and validate on past observations.

Example:

2023 → 2024 → 2025 → 2026
Train → 2023
Valid → early 2024

Fold 2:

Train → 2023 + early 2024
Valid → late 2024

Fold 3:

Train → previous periods
Valid → 2025

Example:

from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(
n_splits=5
)
scores = cross_val_score(
model,
X,
y,
cv=tscv,
scoring="neg_mean_absolute_error"
)

This respects temporal ordering.

7.17.28 Cross Validation and Data Leakage

Data leakage occurs when information from validation/test data influences model training.

Common sources include:

Incorrect:

Entire Dataset

↓
Scaling
↓
Cross Validation

Correct:

Each Fold

↓
Fit Scaling on Training Fold
↓
Transform Validation Fold
↓
Train Model
↓
Evaluate

Again, pipelines are extremely useful.

7.17.29 Cross Validation and Imbalanced Data

Suppose:

Class 0 → 95%
Class 1 → 5%

The model might simply predict every observation as Class 0.

Therefore, consider metrics such as:

depending on the problem.

7.17.30 Repeated K-Fold

A single K-Fold split can still depend somewhat on how observations are divided.

Repeated K-Fold repeats K-Fold multiple times with different random partitions.

Example:

5-Fold

↓
Repeat 1
5-Fold
↓
Repeat 2
5-Fold
↓
Repeat 3

This provides more validation measurements but requires more computation.

Example:

from sklearn.model_selection import RepeatedKFold
cv = RepeatedKFold(
n_splits=5,
n_repeats=3,
random_state=42
)

7.17.31 Cross Validation Scores

Suppose we obtain:

Fold 1 → 0.88
Fold 2 → 0.91
Fold 3 → 0.90
Fold 4 → 0.87
Fold 5 → 0.92

Mean:

\[\bar{x}=0.896\]

Standard deviation can also be calculated.

print(scores.mean())
print(scores.std())

A useful summary is:

CV Accuracy = 89.6% ± standard deviation

For serious reporting, also consider confidence intervals or repeated/nested validation where appropriate.

7.17.32 Cross Validation Does Not Replace the Test Set

↓
Train/Test Split
↓
Training Data
↓
Cross Validation
↓
Model + Hyperparameter Selection
↓
Final Training
↓
Untouched Test Set
↓
Final Performance

The test set provides an independent final check.

7.17.33 Cross Validation Workflow

A professional machine learning workflow may look like:

Raw Data

↓
Basic Cleaning
↓
Train/Test Split
↓
Training Data
↓
Cross Validation
│
├── Preprocessing
├── Feature Selection
├── Hyperparameter Tuning
└── Model Selection
↓
Best Configuration
↓
Train Final Model
↓
Untouched Test Set
↓
Final Evaluation

7.17.34 Advantages of Cross Validation

1. More Reliable Evaluation

Uses multiple validation splits instead of one.

2. Better Use of Limited Data

Most observations are used for training and validation across different folds.

3. Helps Select Models

Different algorithms can be compared using the same CV strategy.

4. Helps Tune Hyperparameters

5. Helps Detect Instability

Large variation between fold scores may indicate that the model is sensitive to the sample.

7.17.35 Limitations of Cross Validation

1. Computational Cost

A 10-fold CV requires approximately ten model fits for a single configuration.

2. More Complex

Requires careful selection of the validation strategy.

3. Not Suitable for Every Dataset

Time series, grouped observations, and certain dependent data require specialized strategies.

4. Leakage Can Still Occur

Cross-validation does not automatically prevent leakage. Preprocessing and feature engineering must be handled correctly.

5. Metric Variance

Different folds can produce different scores, especially with small or heterogeneous datasets.

7.17.36 Cross Validation for Different Problems

Problem Recommended CV
General classification StratifiedKFold
General regression KFold
Imbalanced classification StratifiedKFold
Grouped observations GroupKFold / related group-aware CV
Time series TimeSeriesSplit or suitable temporal validation
Very small dataset K-Fold / possibly LOOCV
Extensive model selection Nested CV

The exact choice should reflect how the data will be encountered in production.

7.17.37 Interview Questions

Q1. What is cross-validation?

A technique for estimating model performance by repeatedly training and validating the model on different subsets of the training data.

Q2. What is K-Fold Cross Validation?

It divides data into K folds and uses each fold as a validation set once while using the remaining folds for training.

Q3. What is a common value of K?

5 or 10 are common choices.

Q4. What is Stratified K-Fold?

A cross-validation strategy that attempts to preserve class proportions across folds.

Q5. Why should the test set not be used during cross-validation?

Because the test set should provide an unbiased final estimate after model selection and tuning are complete.

Q6. What is LOOCV?

Leave-One-Out Cross Validation uses one observation as the validation set and all remaining observations for training, repeating this for every observation.

Q7. What is nested cross-validation?

It uses an inner loop for model/hyperparameter selection and an outer loop for estimating generalization performance.

Q8. Why use a pipeline during cross-validation?

To ensure preprocessing, feature selection, and modeling are fitted correctly within each training fold and to prevent leakage.

Q9. Should K-Fold be used for time-series data?

Usually not. Temporal validation such as TimeSeriesSplit is generally more appropriate because future observations should not be used to predict the past.

Q10. Does cross-validation eliminate overfitting?

No. It helps detect and manage overfitting and supports model selection, but the final model can still overfit if the overall process is poorly designed.

7.17.38 Key Takeaways

Module 7 · Lesson 7.18

Hyperparameter Tuning

7.18.1 Introduction

Hyperparameter Tuning is the process of finding the best values for a machine learning model's hyperparameters to improve its performance on unseen data.

A hyperparameter is a setting that is chosen before or outside the model's normal parameter-learning process.

For example:

Machine Learning Model

↓
Hyperparameters
↓
Train
↓
Evaluate
↓
Try different values
↓
Select best configuration

Examples:

7.18.2 Parameters vs Hyperparameters

This distinction is extremely important.

Parameters

Parameters are learned from training data.

For Linear Regression:

\[y=w_1x_1+w_2x_2+b\]

These are parameters.

Hyperparameters

These are hyperparameters.

7.18.3 Simple Example — KNN

Suppose we are using KNN.

We don't know the best value of:

\[K\]

↓
Cross Validation
↓
Performance

Suppose:

K CV Accuracy
3 88%
5 91%
7 93%
9 90%
11 87%

The best value is:

\[\boxed{K=7}\]

because it produced the highest validation accuracy in this example.

7.18.4 Why Hyperparameter Tuning Is Important

↓
Accuracy = 82%

After tuning:

Tuned Model

↓
Accuracy = 90%
The improvement depends heavily on the dataset and model.

Hyperparameter tuning can help find a better balance between:

7.18.5 Hyperparameter Tuning Workflow

A typical process is:

Training Data

↓
Choose Model
↓
Define Hyperparameter Search Space
↓
Choose Cross-Validation Strategy
↓
Search Hyperparameter Combinations
↓
Evaluate Each Configuration
↓
Select Best Configuration
↓
Train Final Model
↓
Evaluate on Untouched Test Set

7.18.6 Common Hyperparameter Tuning Methods

Important approaches include:

  1. Manual Search

  2. Grid Search

  3. Random Search

  4. Bayesian Optimization

  5. Successive Halving / Early-Stopping-Based Search

For this curriculum, the most important are:

7.18.7 Manual Hyperparameter Tuning

The simplest approach is to manually test values.

Example:

from sklearn.neighbors import KNeighborsClassifier
for k in [3, 5, 7, 9]:
model = KNeighborsClassifier(
n_neighbors=k
)
model.fit(X_train, y_train)
score = model.score(
X_test,
y_test
)
print(k, score)

However, using the test set repeatedly like this is not recommended for model selection because the test set becomes part of the tuning process.

Instead, use cross-validation on the training data.

7.18.8 Grid Search

Grid Search evaluates every combination in a predefined hyperparameter grid.

Suppose:

C:

\[3\times3=9\]

combinations.

7.18.9 GridSearchCV

Scikit-learn provides GridSearchCV.

Example:

from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
model = SVC()
param_grid = {
"C": [0.1, 1, 10],
"gamma": [0.01, 0.1, 1],
"kernel": ["rbf"]
}
grid = GridSearchCV(
estimator=model,
param_grid=param_grid,
cv=5,
scoring="accuracy"
)
grid.fit(
X_train,
y_train
)
print(grid.best_params_)
print(grid.best_score_)

7.18.10 What Does GridSearchCV Do?

\[9\times5=45\]

model fits, excluding any additional final refitting.

Therefore:

Grid Search can become computationally expensive when the search space is large.

7.18.11 Random Search

Instead of evaluating every possible combination, Random Search samples a specified number of combinations from the search distributions.

Example:

This can be much more efficient than evaluating all 10,000 configurations.

7.18.12 RandomizedSearchCV

from sklearn.model_selection import RandomizedSearchCV
from sklearn.svm import SVC
model = SVC()
param_distributions = {
"C": [0.01, 0.1, 1, 10, 100],
"gamma": [0.001, 0.01, 0.1, 1],
"kernel": ["rbf", "linear"]
}
search = RandomizedSearchCV(
estimator=model,
param_distributions=param_distributions,
n_iter=20,
cv=5,
scoring="accuracy",
random_state=42
)
search.fit(
X_train,
y_train
)
print(search.best_params_)
print(search.best_score_)

7.18.13 Grid Search vs Random Search

Grid Search Random Search
Tests every specified combination Tests selected random combinations
Can become expensive Usually more computationally efficient
Good for small search spaces Good for larger search spaces
Easy to understand More efficient when only a few parameters strongly affect performance
Number of runs grows multiplicatively Number of runs controlled by n_iter

7.18.14 Why Random Search Can Be Better

Suppose a model has:

10 hyperparameters

7.18.15 Bayesian Optimization

Bayesian Optimization uses information from previous trials to decide which hyperparameters to try next.

Instead of blindly testing configurations:

Try → Evaluate
Try → Evaluate
Try → Evaluate

it learns from previous results:

Previous Trials

↓
Build Surrogate Model
↓
Choose Promising Hyperparameters
↓
Evaluate
↓
Update
↓
Repeat

This can reduce the number of expensive model evaluations.

Popular libraries include tools such as Optuna and scikit-optimize.

7.18.16 Hyperparameter Search Space

}

The search algorithm then evaluates possible combinations.

7.18.17 Important Hyperparameters by Algorithm

7.18.18 Hyperparameter Tuning Example — Random Forest

Example:

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
model = RandomForestClassifier(
random_state=42
)
param_grid = {
"n_estimators": [100, 200],
"max_depth": [5, 10, None],
"min_samples_split": [2, 5]
}
grid = GridSearchCV(
model,
param_grid,
cv=5,
scoring="f1",
n_jobs=-1
)
grid.fit(
X_train,
y_train
)
print("Best Parameters:")
print(grid.best_params_)
print("Best CV Score:")
print(grid.best_score_)

7.18.19 Choosing the Scoring Metric

The metric should match the business objective.

7.18.20 Accuracy Can Be Misleading

Suppose:

1000 transactions

990 → Legitimate
10 → Fraud

A model that predicts every transaction as legitimate gets:

\[99%\]

Recall → 0%

So accuracy is clearly not an adequate tuning metric here.

depending on the business costs of false positives and false negatives.

7.18.21 Hyperparameter Tuning with Pipelines

Suppose we have:

Scaling

+

SVM

We should tune the complete pipeline.

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("svm", SVC())
])
param_grid = {
    "svm__C": [0.1, 1, 10],
    "svm__gamma": ["scale", 0.01, 0.1],
    "svm__kernel": ["rbf"]
}
grid = GridSearchCV(
    pipeline,
    param_grid=param_grid,
    cv=5,
    scoring="accuracy"
)
grid.fit(
    X_train,
    y_train
)
The svm__ prefix means:
    Pipeline step "svm"
↓
Hyperparameter

This is an important Scikit-learn pattern.

7.18.22 Why Pipeline Is Important

Suppose we standardize the entire dataset before cross-validation:

Entire Dataset

↓
StandardScaler
↓
Cross Validation
↓
Training portion
↓
Fit scaler
↓
Transform training + validation
↓
Train model
↓
Validate

A Pipeline ensures this process happens correctly during CV.

7.18.23 Hyperparameter Tuning and Cross Validation

↓
Configuration
↓
Cross Validation
↓
Score
↓
Compare Configurations
↓
Best Hyperparameters

7.18.24 Best Parameters vs Best Score

After GridSearchCV:
print(grid.best_params_)
print(grid.best_score_)
best_params_

7.18.25 Final Model

After selecting the best configuration, we generally train the final model using the complete training dataset.

Scikit-learn's search object can do this automatically when:

final_model = grid.best_estimator_
y_pred = final_model.predict(
X_test
)

The test set should be used only after model selection/tuning is complete.

7.18.26 Train, Validation, and Test

A simple conceptual structure is:

Dataset

↓
Train/Test Split
↓
Training Data
↓
Cross Validation
├── Fold 1
├── Fold 2
├── Fold 3
├── Fold 4
└── Fold 5
↓
Hyperparameter Tuning
↓
Best Model
↓
Untouched Test Data
↓
Final Evaluation

You don't necessarily need a separate static validation set when cross-validation is being used for tuning.

7.18.27 Overfitting During Hyperparameter Tuning

It is possible to overfit the validation process if you try a huge number of configurations and repeatedly make decisions based on the same validation data.

For example:

Try 10 configurations

↓
Choose best
↓
Try another 100
↓
Choose best
↓
Tune again
↓

...

The selected configuration may become overly specialized to the validation process.

This is one reason an untouched test set is important.

For very extensive model-selection workflows, nested cross-validation can provide a more rigorous performance estimate.

7.18.28 Hyperparameter Tuning vs Model Parameters

Example: Linear Regression

Training Data

↓
Linear Regression
↓

Learn:

w1, w2, b

These are parameters.

Now consider a Decision Tree:

max_depth = 5

min_samples_split = 10

These are hyperparameters.

The model learns its internal split rules from the training data, while these configuration values control how the learning process behaves.

7.18.29 Hyperparameter Tuning — KNN

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
pipeline = Pipeline([
("scaler", StandardScaler()),
("knn", KNeighborsClassifier())
])
param_grid = {
"knn__n_neighbors": [3, 5, 7, 9, 11],
"knn__weights": ["uniform", "distance"],
"knn__metric": ["euclidean", "manhattan"]
}
grid = GridSearchCV(
pipeline,
param_grid,
cv=5,
scoring="accuracy"
)
grid.fit(
X_train,
y_train
)
print(grid.best_params_)

7.18.30 Hyperparameter Tuning — SVM

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
pipeline = Pipeline([
("scaler", StandardScaler()),
("svm", SVC())
])
param_grid = {
"svm__C": [0.1, 1, 10, 100],
"svm__gamma": ["scale", 0.01, 0.1],
"svm__kernel": ["rbf", "linear"]
}
grid = GridSearchCV(
pipeline,
param_grid,
cv=5,
scoring="f1"
)
grid.fit(
X_train,
y_train
)
print(grid.best_params_)

7.18.31 Hyperparameter Tuning — Decision Tree

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
model = DecisionTreeClassifier(
random_state=42
)
param_grid = {
"max_depth": [3, 5, 10, None],
"min_samples_split": [2, 5, 10],
"min_samples_leaf": [1, 2, 5]
}
grid = GridSearchCV(
model,
param_grid,
cv=5,
scoring="accuracy"
)
grid.fit(
X_train,
y_train
)

7.18.32 Hyperparameter Tuning — Logistic Regression

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
model = LogisticRegression(
max_iter=1000
)
param_grid = {
"C": [0.01, 0.1, 1, 10, 100],
"penalty": ["l2"]
}
grid = GridSearchCV(
model,
param_grid,
cv=5,
scoring="accuracy"
)
grid.fit(
X_train,
y_train
)

7.18.33 Search Space Design

A common mistake is choosing arbitrary hyperparameter values.

Instead, understand the model.

For example, SVM C often spans multiple orders of magnitude:

This is more informative than:

For continuous parameters, distributions are often useful with Randomized Search.

7.18.34 Log-Scale Search

For parameters spanning orders of magnitude, use a logarithmic distribution.

Example:

from scipy.stats import loguniform
param_distributions = {
"C": loguniform(
1e-3,
1e3
)
}

Then:

RandomizedSearchCV(
model,
param_distributions,
n_iter=30,
cv=5,
random_state=42
)

This allows the search to explore small and large values efficiently.

7.18.35 Hyperparameter Tuning with Multiple Metrics

Sometimes multiple metrics are important.

Example:

scoring = {

"accuracy": "accuracy",

"f1": "f1",

"roc_auc": "roc_auc"

}

Then:

grid = GridSearchCV(
model,
param_grid,
cv=5,
scoring=scoring,
refit="f1"
)

Here, the search records multiple metrics but refits the final best model based on F1.

This is useful when accuracy alone doesn't capture the business objective.

7.18.36 Parallel Processing

Hyperparameter searches can be expensive.

Scikit-learn supports parallel processing in many search classes:

GridSearchCV(
model,
param_grid,
cv=5,
n_jobs=-1
)

n_jobs=-1 generally tells Scikit-learn to use all available CPU cores.

Be mindful that parallel jobs consume memory and CPU resources.

7.18.37 Early Stopping

↓
Monitor Validation Performance
↓
Performance improves
↓
Continue
↓
Performance stops improving
↓
Stop Training

This can prevent unnecessary training and help control overfitting.

It is commonly used with algorithms such as gradient boosting and neural networks.

7.18.38 Hyperparameter Tuning Strategy

↓
Accuracy = 84%
Step 2 — Identify Important Hyperparameters

7.18.39 Common Mistakes

↓
Test
↓
Change Hyperparameters
↓
Test Again
↓
GridSearchCV

=

10,000 configurations

With 5-fold CV:

\[10,000\times5 50,000\]

7.18.40 Hyperparameter Tuning Example — End to End

from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("svm", SVC())
])
param_grid = {
    "svm__C": [0.1, 1, 10, 100],
    "svm__gamma": [
        "scale",
        0.01,
        0.1
    ],
    "svm__kernel": [
        "rbf"
    ]
}
grid = GridSearchCV(
    pipeline,
    param_grid,
    cv=5,
    scoring="f1",
    n_jobs=-1
)
grid.fit(
    X_train,
    y_train
)
print(
    "Best Parameters:",
    grid.best_params_
)
print(
    "Best CV F1:",
    grid.best_score_
)
final_model = grid.best_estimator_
y_pred = final_model.predict(
    X_test
)
print(
    classification_report(
        y_test,
        y_pred
    )
)

7.18.41 Hyperparameter Tuning Workflow Summary

Dataset

↓
Train/Test Split
↓
Training Data
↓
┌─────────────────────┐
│ Hyperparameter │
│ Search Space │
└──────────┬──────────┘
↓
Cross Validation
↓
┌───────────┼───────────┐
↓ ↓ ↓
Model 1 Model 2 Model N
↓ ↓ ↓
Score Score Score
└───────────┼───────────┘
↓
Best Configuration
↓
Final Model
↓
Untouched Test Set
↓
Final Performance

7.18.42 Advantages of Hyperparameter Tuning

7.18.43 Limitations

7.18.44 Interview Questions

Q1. What is hyperparameter tuning?

It is the process of finding suitable hyperparameter values that optimize model performance based on a validation strategy.

Q2. What is the difference between parameters and hyperparameters?

Parameters are learned from training data; hyperparameters control the learning process and are specified externally.

Q3. What is Grid Search?

Grid Search evaluates every combination of values defined in a parameter grid.

Q4. What is Random Search?

Random Search evaluates a specified number of randomly sampled configurations from a search space.

Q5. Which is better, Grid Search or Random Search?

Neither is universally better. Grid Search is useful for small, carefully defined spaces; Random Search is often more efficient for large spaces.

Q6. Why is cross-validation used during tuning?

It provides a more reliable estimate of each hyperparameter configuration's validation performance.

Q7. Why shouldn't the test set be used for tuning?

Repeatedly using the test set for decisions causes test-set overfitting and produces an overly optimistic final estimate.

Q8. Why use a Pipeline during tuning?

To ensure preprocessing and feature selection are learned independently within each CV training fold and to prevent data leakage.

Q9. What is best_params_?

It contains the hyperparameter configuration that achieved the best cross-validation score during the search.

Q10. What is best_score_?

It is the mean cross-validation score associated with the selected best configuration.

7.18.45 Key Takeaways

Baseline

↓
Define Search Space
↓
Cross-Validation
↓
Hyperparameter Search
↓
Best Configuration
↓
Final Training
↓
Untouched Test Evaluation
Module 7 · Lesson 7.19

Bias vs Variance

7.19.1 Introduction

Bias and Variance are two important sources of error in machine learning models.

They help us understand why a model may perform poorly on unseen data.

The central goal is to find a good balance:

│
├── Bias
├── Variance
└── Irreducible Error

7.19.2 What Is Bias?

Bias is the error caused by a model making overly simplistic assumptions about the relationship between the input and output.

A high-bias model is usually too simple to capture the underlying pattern.

Example:

Actual relationship:

Linear model:

──────────────

If the real relationship is nonlinear but we use an overly simple linear model, the model may systematically miss important patterns.

This is called underfitting.

7.19.3 High Bias

A high-bias model typically has:

Example:

Training Accuracy → 70%
Validation Accuracy → 68%

Both are relatively poor.

The model is not learning enough from the data.

7.19.4 What Is Variance?

Variance refers to how sensitive a model is to changes in the training data.

A high-variance model can fit the training data extremely closely, including random noise.

Example:

Training Data

↓
Very complex model
↓

When new data is presented, performance can drop significantly.

This is called overfitting.

7.19.5 High Variance

A high-variance model typically has:

Example:

Training Accuracy → 99%
Validation Accuracy → 75%

The large gap suggests that the model may be overfitting.

7.19.6 Bias vs Variance

Characteristic High Bias High Variance
Model complexity Too low Too high
Main problem Underfitting Overfitting
Training error High Very low
Validation error High High
Generalization Poor Poor
Sensitivity to training data Low High
Typical solution Increase complexity Reduce complexity

7.19.7 Simple Visualization

Model Complexity

Low ─────────────────────────── High
Bias HIGH ────────────────→ LOW
Variance LOW ─────────────────→ HIGH
↓
Best Balance

The goal is to find a useful balance between the two.

7.19.8 Underfitting

Underfitting occurs when the model is too simple to capture the underlying structure of the data.

Example:

Actual Data

Model

────────────

The model cannot adequately represent the pattern.

Symptoms

Training Error → High
Validation Error → High
Possible solutions

7.19.9 Overfitting

Overfitting occurs when the model learns the training data too closely, including noise.

Example:

Actual observations:

● ●

Overly complex model:

~\/\__/\/\___/\~

The model may perform extremely well on training data but poorly on unseen data.

Symptoms

Training Error → Very Low
Validation Error → High
Possible solutions

7.19.10 Bias-Variance Tradeoff

│
│\ /
│ \ /
│ \ /
│ \ /
│ \____/\____/
│ ↑
│ Best Region
└────────────────────
Model Complexity

The optimal model lies somewhere between these extremes.

7.19.11 Bias-Variance Decomposition

For squared-error regression, expected prediction error can be conceptually decomposed as:

\[\boxed{ \text{Expected Error} \text{Bias}^2 + \text{Variance} + \text{Irreducible Noise} }\]

Where:

7.19.12 Irreducible Error

Some uncertainty exists in the data that no model can completely eliminate.

For example, suppose we predict house prices.

Two houses can have almost identical measurable features but different selling prices because of factors that were not captured.

Observed Features

+

Unknown Factors

↓
Prediction Uncertainty

This unavoidable component is called irreducible error or noise.

7.19.13 Understanding Variance Mathematically

Variance measures how much values fluctuate around their mean.

For a random variable (X):

\[Var(X)=E[(X-\mu)^2]\]

where:

\[\mu=E[X]\]

An equivalent expression is:

\[Var(X)=E[X^2]-[E(X)]^2\]

In machine learning, model variance describes how much predictions can change when the model is trained on different samples of the training data.

7.19.14 Example: Decision Tree

/ \

/ \

Bias → Higher
Variance → Lower
Very Deep Tree
max_depth = None
Bias → Lower
Variance → Higher

7.19.15 Training and Validation Error

One of the easiest ways to understand bias and variance is by comparing training and validation performance.

High Bias

Training Error → HIGH
Validation Error → HIGH

There isn't a large gap.

High Variance

Training Error → LOW
Validation Error → HIGH

There is a large gap.

7.19.16 Example

Suppose we train three models:

Model Training Error Validation Error
Model A 20% 22%
Model B 5% 7%
Model C 1% 25%

7.19.17 Effect of Model Complexity

Consider increasing the complexity of a model.
Complexity
Low ─────────────────────→ High

Typically:

Bias

HIGH ────────────────────→ LOW
Variance
LOW ─────────────────────→ HIGH

At first, increasing complexity improves performance because the model reduces underfitting.

Eventually, excessive complexity causes overfitting.

7.19.18 Learning Curves

Learning curves show model performance as the amount of training data changes.

They are useful for diagnosing bias and variance.

Example:

Error

│
│ Training ──────────
│ \
│ \________
│
│ Validation ─────────
│
└────────────────────────
Training Size

The exact shape depends on the problem.

7.19.19 High Bias Learning Curve

A typical high-bias situation may show:

Training Error ───────────
Validation Error ───────────

7.19.20 High Variance Learning Curve

A typical high-variance situation may show:

Training Error

↓
Very Low
Validation Error
↓
Much Higher

7.19.21 Regularization and Variance

Regularization penalizes model complexity.

For example, L2 regularization adds:

\[\lambda\sum_j w_j^2\]

to the objective.

Increasing regularization strength generally:

Model Complexity ↓
Variance ↓
Bias ↑

Therefore, regularization is one of the most common tools for controlling high variance.

7.19.22 Example — Linear Regression

Suppose we fit:

Model 1
y = w1x + b
Simple model.

Potentially:

Bias → High
Variance → Low
Model 2

A very high-degree polynomial:

\[y=w_0+w_1x+w_2x^2+\cdots+w_{20}x^{20}\]

Potentially:

Bias → Low
Variance → High

The second model may fit training data extremely well but generalize poorly.

7.19.23 Polynomial Regression Example

from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
model = Pipeline([
    (
        "poly",
        PolynomialFeatures(degree=10)
    ),
    (
        "regression",
        LinearRegression()
    )
])

Increasing the polynomial degree generally increases model flexibility.

For example:

Degree 1 → Simple
Degree 2 → More flexible
Degree 5 → More flexible
Degree 10 → Very flexible

At some point, the model may start fitting noise.

7.19.24 Bias-Variance Tradeoff in KNN

\[K=1\]

The model relies heavily on individual training observations.

Variance → High
Bias → Low

\[K=50\]

The model averages over many observations.

Variance → Lower
Bias → Higher

It may underfit.

Therefore:

Choosing K is a bias-variance tradeoff.

7.19.25 Bias-Variance Tradeoff in Decision Trees

Shallow Tree

max_depth = 2

Bias → High
Variance → Low
Deep Tree
max_depth = 20
Bias → Low
Variance → High

Hyperparameter tuning can help identify a useful depth.

7.19.26 Bias-Variance Tradeoff in Random Forest

Tree 1 → Prediction
Tree 2 → Prediction
Tree 3 → Prediction

...

Tree N → Prediction
↓
Average / Vote
↓
Final Prediction

This is one reason ensemble methods can generalize better than a single highly flexible tree.

7.19.27 Bagging and Variance

↓
Bootstrap Samples
↓
┌────┬────┬────┬────┐

T1 T2 T3 T4 ...

└────┴────┴────┴────┘
↓
Aggregate Predictions
↓
Final Prediction

Random Forest is a classic example of a bagging-based ensemble.

7.19.28 Boosting and Bias

Boosting methods such as:

build models sequentially to improve performance.

Boosting can substantially reduce bias, but excessive complexity or insufficient regularization can also lead to overfitting.

7.19.29 Bias vs Variance: Practical Diagnosis

Observation Likely Issue Possible Action
High train error + high validation error High bias Increase complexity
Low train error + high validation error High variance Regularize / simplify
Both errors low Good fit Keep model
Large train-validation gap High variance More data / regularization
Both errors high and close High bias Better features / more complexity

This is a useful diagnostic framework, but real datasets can have more complicated failure modes.

7.19.30 How to Reduce Bias

If the model has high bias:

1. Increase Model Complexity

Example:

Decision Tree:

depth 2 → depth 5
2. Add Useful Features
Existing Features
+
Relevant New Features

3. Reduce Excessive Regularization

If regularization is too strong, the model may be overly constrained.

4. Use a More Flexible Algorithm

For example:

Linear Model

↓
Tree-Based Model

when appropriate.

7.19.31 How to Reduce Variance

If the model has high variance:

1. Increase Training Data

More representative data can help.

2. Reduce Model Complexity

For example:

Decision Tree depth:

20 → 8
3. Increase Regularization

For example:

L2 regularization

4. Perform Feature Selection

Remove irrelevant or noisy features.

5. Use Ensemble Methods

For example:

Random Forest

can reduce variance relative to a single tree.

6. Use Cross Validation

Cross-validation helps assess whether the model is stable across different subsets of data.

7.19.32 Bias vs Variance vs Noise

A useful conceptual decomposition is:

Total Prediction Error

│
├── Bias²
│
├── Variance
│
└── Irreducible Noise

We can reduce bias and variance through model design, but:

Irreducible noise cannot be completely removed by choosing a more sophisticated model.

7.19.33 Practical Example — House Price Prediction

If the actual relationship is more complex:

Training RMSE → High
Validation RMSE → High

Likely high bias.

Model B — Very Deep Decision Tree

Training RMSE → Very Low
Validation RMSE → High

Likely high variance.

Model C — Regularized Ensemble

Training RMSE → Low
Validation RMSE → Low

Potentially a better bias-variance balance.

7.19.34 Bias-Variance and Cross Validation

Cross-validation from Section 7.17 is particularly useful here.

Suppose:

Fold 1 → 91%
Fold 2 → 90%
Fold 3 → 92%
Fold 4 → 89%
Fold 5 → 91%

The model is relatively stable.

But:

Fold 1 → 98%
Fold 2 → 70%
Fold 3 → 94%
Fold 4 → 65%
Fold 5 → 90%

The large variation may indicate that the model is sensitive to the training sample, although it can also reflect data heterogeneity or a poor validation design.

7.19.35 Bias-Variance and Hyperparameter Tuning

↓
High Bias
max_depth = 5
↓
Balanced
max_depth = 30
↓
High Variance

Cross-validation can help identify a useful value.

max_depth

↓
Cross Validation
↓
Compare Scores
↓
Choose Suitable Complexity

7.19.36 Bias-Variance and Feature Selection

↓
Bias ↑

Too many irrelevant/noisy features:

Model learns noise

↓
Variance ↑

Therefore, feature selection should aim for a useful information-to-complexity balance.

7.19.37 Bias-Variance and PCA

↓
PCA
↓
10 Components

This can reduce variance by simplifying the input representation, but retaining too few components can discard useful information and increase bias.

Therefore:

Too Few Components → Potentially High Bias
Too Many Components → Potentially Higher Variance

7.19.38 A Useful Mental Model

Think of a model as having a flexibility dial:

Less Flexible More Flexible

│ │
▼ ▼
Simple ─────────── Balanced ─────────── Complex
│ │ │
▼ ▼ ▼
High Bias Good Balance High Variance
Underfitting Overfitting

The objective is not to minimize bias or variance independently.

The objective is to achieve the best generalization performance.

7.19.39 Interview Questions

Q1. What is bias?

Bias is systematic error caused by overly simplistic assumptions made by a model.

Q2. What is variance?

Variance measures how sensitive a model's predictions are to changes in the training data.

Q3. What is underfitting?

Underfitting occurs when a model is too simple to capture important patterns.

Q4. What is overfitting?

Overfitting occurs when a model learns the training data too closely, including noise, and performs poorly on unseen data.

Q5. What is the bias-variance tradeoff?

It is the balance between reducing systematic error and avoiding excessive sensitivity to the training data.

Q6. What happens when model complexity increases?

Generally:

Bias ↓
Variance ↑

although the exact behavior depends on the model and problem.

Q7. How can you reduce high bias?

Q8. How can you reduce high variance?

Q9. What is the bias-variance decomposition?

For squared-error prediction, expected error can be conceptually decomposed into:

\[Bias^2+Variance+Irreducible\ Noise\]

Q10. Is low training error always good?

No. Extremely low training error combined with poor validation/test performance can indicate overfitting and high variance.

7.19.40 Key Takeaways

Module 7 · Lesson 7.20

Ensemble Learning

7.20.1 Introduction

Ensemble Learning is a machine learning technique that combines the predictions of multiple models to produce a stronger and often more robust final prediction.

The central idea is:

A group of diverse models can often perform better than a single model.

For example:

Training Data

↓
┌──────────┼──────────┐
↓ ↓ ↓
Model 1 Model 2 Model 3
↓ ↓ ↓
Pred 1 Pred 2 Pred 3
└──────────┼──────────┘
↓
Combine Results
↓
Final Prediction

Ensemble learning is widely used in:

7.20.2 Why Ensemble Learning?

A single model may make mistakes.

Suppose three models predict:

Model 1 → Class A
Model 2 → Class A
Model 3 → Class B

A voting ensemble can produce:

Final Prediction → Class A

The idea is that the models' errors may not be identical.

If their predictions are sufficiently diverse, combining them can improve generalization.

7.20.3 Simple Example

Suppose we want to predict whether a customer will churn.

Three models produce:

Model Prediction
Decision Tree Churn
Logistic Regression Churn
KNN No Churn

Majority vote:

Churn → 2 votes
No Churn → 1 vote

Final prediction:

\[\boxed{Churn}\]

7.20.4 Main Types of Ensemble Learning

The major ensemble approaches are:

  1. Bagging

  2. Boosting

  3. Voting

  4. Stacking

  5. Blending

Conceptually:

Ensemble Learning

│
├── Bagging
│ └── Random Forest
│
├── Boosting
│ ├── AdaBoost
│ ├── Gradient Boosting
│ ├── XGBoost
│ ├── LightGBM
│ └── CatBoost
│
├── Voting
│
├── Stacking
│
└── Blending

7.20.5 Bagging

Bagging stands for:

Bootstrap Aggregating

The basic idea is to train multiple models on different bootstrap samples of the training dataset and then combine their predictions.

Original Dataset

↓
Bootstrap Sampling
↓
┌─────┼─────┬─────┐
↓ ↓ ↓ ↓
Data1 Data2 Data3 Data4
↓ ↓ ↓ ↓
Model Model Model Model
1 2 3 4
└─────┼─────┴─────┘
↓
Aggregate Predictions
↓
Final Prediction

Bagging primarily helps reduce variance.

7.20.6 Bootstrap Sampling

Each sample can be used to train a separate model.

7.20.7 Bagging Example

Suppose we train five decision trees:

Tree 1 → Class A
Tree 2 → Class B
Tree 3 → Class A
Tree 4 → Class A
Tree 5 → Class B

Voting:

Class A → 3
Class B → 2

Final prediction:

Class A

7.20.8 Random Forest

↓
Randomized Samples
↓
┌────┬────┬────┬────┐
↓ ↓ ↓ ↓ ↓
Tree Tree Tree Tree Tree
1 2 3 4 5
└────┴────┴────┴────┘
↓
Voting/Average
↓
Final Prediction

Random Forest was covered earlier in Section 7.9.

7.20.9 Why Random Forest Works

A single decision tree can have high variance.

Random Forest reduces this by:

  1. Training many trees

  2. Using different bootstrap samples

  3. Considering random subsets of features when splitting

The trees are therefore less correlated than identical trees trained on exactly the same data.

Combining their predictions can reduce variance.

7.20.10 Bagging for Classification

For classification, predictions can be combined through majority voting.

Example:

Tree 1 → 0
Tree 2 → 1
Tree 3 → 1
Tree 4 → 1
Tree 5 → 0

Votes:

Class 0 → 2
Class 1 → 3

Final:

\[\boxed{1}\]

7.20.11 Bagging for Regression

For regression, predictions are commonly averaged.

Suppose:

Model 1 → 100
Model 2 → 110
Model 3 → 105
Model 4 → 95

Average:

\[\frac{100+110+105+95}{4}\]

\[=\boxed{102.5}\]

Final prediction:

102.5

7.20.12 Boosting

Boosting is another major ensemble approach.

Unlike bagging, where models can be trained independently, boosting builds models sequentially.

↓
Model 1
↓
Find Errors
↓
Model 2 focuses on remaining errors
↓
Model 3 improves further
↓

...

↓
Final Ensemble

7.20.13 Bagging vs Boosting

Bagging Boosting
Models can be trained independently Models are built sequentially
Uses bootstrap samples Sequentially focuses on errors/residuals
Primarily reduces variance Can strongly reduce bias
Random Forest XGBoost, LightGBM, CatBoost
Parallelizable naturally Sequential dependency makes training less parallel across boosting rounds

Modern boosting algorithms use additional regularization and optimization techniques, so the simple "boosting reduces bias" description is useful conceptually but not a guarantee.

7.20.14 AdaBoost

↓
Train Model 1
↓
Identify Misclassified Points
↓
Increase Their Importance
↓
Train Model 2
↓
Repeat

Example:

Model 1:

✓ ✓ ✓ ✗ ✗

Model 2 focuses more on:

✗ ✗

Model 3:

Improves remaining errors

The final prediction combines the weak learners using weighted voting.

7.20.15 Weak Learners

Boosting often uses weak learners.

A weak learner is a model that performs only somewhat better than random guessing on the task.

A common example is a shallow decision tree:

Decision Stump

↓
Very Small Tree

Multiple weak learners can be combined into a powerful ensemble.

7.20.16 Gradient Boosting

↓
Calculate Residuals
↓
Train Model on Residuals
↓
Update Prediction
↓
Calculate New Residuals
↓
Repeat

Conceptually:

\[F_m(x) F_{m-1}(x) + \eta h_m(x)\]

where:

7.20.17 Learning Rate

Learning Rate ↓
↓
More Estimators Needed

This is a common hyperparameter tradeoff.

7.20.18 Number of Estimators

Boosting algorithms commonly have a parameter such as:

7.20.19 XGBoost

XGBoost is covered in detail in Section 7.21.

7.20.20 LightGBM

LightGBM is a gradient boosting framework designed for efficient and scalable tree-based learning.

7.20.21 CatBoost

CatBoost is a gradient boosting algorithm particularly well known for handling categorical features effectively.

7.20.22 Voting Ensemble

↓
Voting
↓
Final Class

Example:

from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
model1 = LogisticRegression(
max_iter=1000
)
model2 = DecisionTreeClassifier(
max_depth=5,
random_state=42
)
model3 = SVC(
probability=True
)
ensemble = VotingClassifier(
estimators=[
("lr", model1),
("tree", model2),
("svm", model3)
],
voting="hard"
)

7.20.23 Hard Voting

In hard voting, each model produces a class prediction.

Example:

Model 1 → A
Model 2 → A
Model 3 → B
Model 4 → A

7.20.24 Soft Voting

A → 0.80
B → 0.20

Model 2:

A → 0.60
B → 0.40

Model 3:

A → 0.70
B → 0.30

Average probability:

\[P(A)=\frac{0.80+0.60+0.70}{3}=0.70\]

\[P(B)=\frac{0.20+0.40+0.30}{3}=0.30\]

Final:

A

Soft voting can be useful when the component models have reasonably calibrated probabilities.

7.20.25 Voting Regressor

Voting can also be used for regression.

Suppose:

Linear Regression → 100
Random Forest → 110
Gradient Boosting → 105

Average:

\[\frac{100+110+105}{3} 105\]

7.20.26 Stacking

Stacking, or stacked generalization, combines several base models using another model called a meta-model.

Example:

Training Data

↓
┌──────────────┼──────────────┐
↓ ↓ ↓
Logistic Random SVM
Regression Forest
↓ ↓ ↓
Pred 1 Pred 2 Pred 3
└──────────────┼──────────────┘
↓
Meta Model
↓
Final Prediction

The meta-model learns how to combine the base model predictions.

7.20.27 Stacking Example

Suppose:

Model 1 → Logistic Regression
Model 2 → Random Forest
Model 3 → SVM

Their predictions become features for the meta-model:

↓
Meta Model
↓
Final Prediction

7.20.28 Why Stacking Works

→ Linear relationships
Decision Tree
→ Rule-based relationships
SVM
→ Margin-based decision boundaries
A meta-model can learn when to trust each model.

The key benefit comes from complementary errors, not simply from having many models.

7.20.29 Blending

Blending is similar to stacking but usually uses a separate holdout validation set to train the meta-model.

Conceptually:

Training Data

↓
Base Models
↓
Predictions
↓
Validation/Holdout Set
↓
Meta Model
↓
Final Prediction

Difference:

Stacking Blending
Commonly uses out-of-fold predictions Commonly uses a holdout set
More data-efficient when implemented with CV Simpler conceptually
More computationally expensive Usually simpler

7.20.30 Diversity in Ensembles

An important concept is model diversity.

Suppose we have:

Model A → Error on Customer 10
Model B → Correct on Customer 10
Model C → Correct on Customer 10

Combining them can correct Model A's mistake.

But if:

Model A → Wrong
Model B → Wrong
Model C → Wrong

then combining them doesn't help much.

Therefore:

Ensemble performance depends not only on individual model quality but also on how different their errors are.

7.20.31 Correlated Errors

Suppose five models make almost exactly the same predictions:

Model 1 ─┐
Model 2 ─┤
Model 3 ─┼── Same Errors
Model 4 ─┤
Model 5 ─┘

The ensemble may provide little improvement.

But if errors differ:

Model 1 → Error A
Model 2 → Error B
Model 3 → Error C
Model 4 → Correct
Model 5 → Correct

combining them can be more beneficial.

7.20.32 Ensemble Learning and Bias-Variance

\[\boxed{Variance}\]

Example:

Decision Tree

↓
High Variance
↓
Random Forest
↓
Lower Variance
Boosting

Can reduce bias substantially by adding learners sequentially, while regularization controls variance.

7.20.33 Bagging vs Boosting vs Stacking

Feature Bagging Boosting Stacking
Main idea Aggregate independent models Sequentially improve errors/residuals Learn how to combine models
Training Parallelizable Sequential across boosting rounds Base models + meta-model
Typical goal Reduce variance Improve predictive accuracy / reduce bias Combine complementary models
Example Random Forest XGBoost StackingClassifier
Base models Usually same algorithm Usually weak learners Often different algorithms

7.20.34 Ensemble Learning Example

+

Random Forest

+

SVM

↓
Voting Ensemble

The ensemble might achieve better validation performance if the models make sufficiently complementary errors.

This should always be verified experimentally rather than assumed.

7.20.35 Random Forest in Python

from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=200,
max_depth=10,
random_state=42,
n_jobs=-1
)
model.fit(
X_train,
y_train
)
predictions = model.predict(
X_test
)

7.20.36 AdaBoost in Python

from sklearn.ensemble import AdaBoostClassifier
model = AdaBoostClassifier(
n_estimators=100,
learning_rate=0.5,
random_state=42
)
model.fit(
X_train,
y_train
)

7.20.37 Gradient Boosting in Python

from sklearn.ensemble import GradientBoostingClassifier
model = GradientBoostingClassifier(
n_estimators=100,
learning_rate=0.05,
max_depth=3,
random_state=42
)
model.fit(
X_train,
y_train
)

7.20.38 Stacking in Python

from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
estimators = [
    (
        "lr",
        LogisticRegression(
            max_iter=1000
        )
    ),
    (
        "rf",
        RandomForestClassifier(
            n_estimators=100,
            random_state=42
        )
    ),
    (
        "svm",
        SVC(
            probability=True
        )
    )
]
stack = StackingClassifier(
    estimators=estimators,
    final_estimator=LogisticRegression(),
    cv=5
)
stack.fit(
    X_train,
    y_train
)

7.20.39 When Should You Use Ensemble Learning?

Ensembles are particularly useful when:

7.20.40 When Might an Ensemble Be a Poor Choice?

An ensemble may not be ideal when:

For example:

Simple Logistic Regression → 94%
Complex Ensemble → 94.5%

The additional 0.5 percentage point may not justify the extra complexity in every application.

7.20.41 Ensemble Learning Workflow

Raw Data

↓
Preprocessing
↓
Feature Engineering
↓
Train Multiple Models
↓
Evaluate Individual Models
↓
Analyze Model Diversity
↓
Combine Predictions
↓
Cross Validation
↓
Tune Ensemble
↓
Final Evaluation
↓
Deployment

7.20.42 Important Interview Questions

Q1. What is ensemble learning?

A technique that combines predictions from multiple models to produce a stronger final prediction.

Q2. What are the main ensemble techniques?

Q3. What is bagging?

Bagging trains multiple models on bootstrap samples and aggregates their predictions.

Q4. What is the most famous bagging algorithm?

Random Forest is a major example.

Q5. What is boosting?

Boosting builds models sequentially, with later models improving the ensemble based on previous errors or residuals.

Q6. Give examples of boosting algorithms.

Q7. What is hard voting?

Combining class labels using majority voting.

Q8. What is soft voting?

Combining predicted class probabilities, usually by averaging or weighted averaging.

Q9. What is stacking?

Using predictions from multiple base models as inputs to a meta-model that learns how to combine them.

Q10. Why is model diversity important?

If models make different errors, combining them can reduce overall prediction error.

Q11. Which ensemble method primarily reduces variance?

Bagging, such as Random Forest.

Q12. Can ensembles overfit?

Yes. More models do not automatically guarantee better generalization. Boosting and stacking, in particular, need appropriate regularization and validation.

7.20.43 Key Takeaways

Module 7 · Lesson 7.21

XGBoost

7.21.1 Introduction

XGBoost stands for Extreme Gradient Boosting. It is a highly optimized implementation of gradient-boosted decision trees (GBDT).

It is especially popular for structured/tabular data such as:

The basic idea is to build many decision trees sequentially, where each new tree improves the predictions made by the existing ensemble.

Training Data

↓
Initial Prediction
↓
Tree 1
↓
Calculate Errors
↓
Tree 2 improves errors
↓
Tree 3 improves further
↓

...

↓
Final XGBoost Model

7.21.2 Why XGBoost Is Important

XGBoost became widely adopted because it combines:

It is often an excellent baseline for structured machine-learning problems.

However:

XGBoost is not automatically the best model for every dataset.

7.21.3 XGBoost vs a Single Decision Tree

A single decision tree might look like:

Income > 50K?

/ \

Yes No

/ \

↓
Tree 2
↓
Tree 3
↓

...

↓
Tree N
↓
Combined Prediction

Each tree contributes to the overall prediction.

7.21.4 XGBoost and Gradient Boosting

↓
Calculate Loss
↓

Model 2 learns how to improve the loss

↓
Calculate New Loss
↓
Model 3 improves further
↓

...

The final model is an additive combination:

\[\hat{y}_i \sum_{k=1}^{K} f_k(x_i)\]

where:

In practice, a learning-rate/shrinkage factor is commonly used to control how strongly each tree contributes.

7.21.5 How XGBoost Works

A simplified training process is:

Step 1

Initial prediction

↓
Step 2
Calculate loss
↓
Step 3
Calculate gradient information
↓
Step 4

Build a tree to improve the objective

↓
Step 5
Add tree to ensemble
↓
Step 6
Repeat

The optimization uses both first- and second-order information about the loss.

7.21.6 Objective Function

One of the important ideas behind XGBoost is that it optimizes an objective consisting of:

\[\boxed{ Objective = Loss + Regularization }\]

A simplified form is:

\[\mathcal{L} \sum_i l(y_i,\hat y_i) + \sum_k \Omega(f_k)\]

where:

This regularization helps control model complexity and reduce overfitting.

7.21.7 XGBoost Regularization

One major difference between basic gradient boosting and XGBoost is its explicit regularization of tree complexity.

Conceptually:

\[\Omega(f) \gamma T + \frac{1}{2}\lambda\sum_j w_j^2 + \alpha\sum_j|w_j|\]

where:

This allows XGBoost to control model complexity.

7.21.8 Learning Rate

Example:

↓
Multiply contribution by learning rate
↓
Add to existing model

in some problems, but the optimal combination must be validated.

7.21.9 n_estimators

n_estimators controls the number of boosting rounds/trees.

Example:

n_estimators=200
↓
Underfitting
Too Many Trees
↓
Potential Overfitting

Learning rate and number of estimators should generally be considered together.

7.21.10 max_depth

max_depth controls the maximum depth of individual trees.

Example:

max_depth=3

Shallow trees:

max_depth ↓
↓
Simpler trees
↓
Lower model complexity

Deep trees:

max_depth ↑
↓
More complex trees
↓
Potentially better training fit
↓
Potentially higher overfitting risk

7.21.11 min_child_weight

min_child_weight ↑
↓
Fewer aggressive splits
↓
Simpler model
↓
Potentially lower overfitting

7.21.12 gamma

gamma specifies a minimum loss reduction required before a split is made.

Example:

gamma=1

Increasing gamma makes the tree more conservative.

gamma ↑
↓
Harder to create new splits
↓
Simpler trees

7.21.13 subsample

subsample controls the fraction of training observations sampled for each boosting round.

Example:

7.21.14 colsample_bytree

colsample_bytree controls the fraction of features considered for each tree.

Example:

colsample_bytree=0.8

means approximately 80% of the features are sampled for each tree.

This is conceptually similar to feature subsampling used in Random Forest.

7.21.15 Important XGBoost Hyperparameters

Hyperparameter Purpose
n_estimators Number of boosting rounds
learning_rate Contribution of each tree
max_depth Maximum tree depth
min_child_weight Minimum child-node weight/hessian
gamma Minimum split improvement
subsample Fraction of observations sampled
colsample_bytree Fraction of features sampled
reg_alpha L1 regularization
reg_lambda L2 regularization
objective Training objective
eval_metric Evaluation metric
random_state Reproducibility

7.21.16 XGBoost Classification

For binary classification, a common objective is:

binary:logistic

It produces probabilities between 0 and 1.

Example:

from xgboost import XGBClassifier
model = XGBClassifier(
n_estimators=200,
max_depth=5,
learning_rate=0.05,
subsample=0.8,
colsample_bytree=0.8,
random_state=42
)
model.fit(
X_train,
y_train
)
predictions = model.predict(
X_test
)

7.21.17 XGBoost Probability Prediction

For binary classification:

probabilities = model.predict_proba(
X_test
)[:, 1]

These represent estimated probabilities for the positive class.

The classification threshold can then be chosen according to the application's needs.

7.21.18 XGBoost Regression

XGBoost can also be used for regression.

from xgboost import XGBRegressor
model = XGBRegressor(
n_estimators=300,
max_depth=5,
learning_rate=0.05,
subsample=0.8,
colsample_bytree=0.8,
random_state=42
)
model.fit(
X_train,
y_train
)
predictions = model.predict(
X_test
)

Common regression metrics include:

7.21.19 XGBoost Objectives

The exact objective should match the problem.

7.21.20 Multi-Class Classification

Example:

from xgboost import XGBClassifier
model = XGBClassifier(
objective="multi:softprob",
num_class=4,
n_estimators=200,
learning_rate=0.05,
max_depth=5,
random_state=42
)

The model can produce probabilities for all four classes.

7.21.21 Feature Importance

XGBoost provides several ways to analyze feature importance.

A simple approach:

importance = model.feature_importances_
print(importance)

Example:

However, feature importance should be interpreted carefully.

A single importance measure does not necessarily mean:

"This feature causes the prediction."

Feature importance describes the model's use of the feature, not causal importance.

7.21.22 Different Feature Importance Measures

Tree boosting implementations can provide different importance concepts, such as:

Gain

Measures how much a feature contributes to improving the objective through splits.

Weight

Related to how frequently a feature is used for splits.

Cover

Related to the amount of data/hessian information affected by those splits.

For interpretation, gain is often more informative than raw split frequency, but permutation importance or SHAP-based explanations can provide complementary views.

7.21.23 XGBoost and Missing Values

XGBoost can handle missing values in many standard tree-based workflows.

Example:

The tree-learning algorithm can learn appropriate default directions for missing values during split construction.

Nevertheless, missing-data handling should still be understood from a business and data-quality perspective.

7.21.24 XGBoost and Categorical Data

Historically, XGBoost commonly required categorical variables to be encoded before modeling.

Modern XGBoost versions also support categorical features under appropriate configuration.

For a conventional workflow, categorical variables can be encoded using techniques such as:

One-Hot Encoding

7.21.25 XGBoost vs Random Forest

Both are tree-based ensembles, but they work differently.

Random Forest XGBoost
Bagging-style ensemble Boosting ensemble
Trees trained largely independently Trees built sequentially
Primarily reduces variance Sequentially improves the loss
Usually less sensitive to hyperparameters Often requires careful tuning
Strong baseline Often very strong on tabular data
Easy to parallelize across trees Boosting rounds are sequential
Less prone to overfitting in many default settings Can overfit if poorly tuned

7.21.26 XGBoost vs Gradient Boosting

XGBoost is a sophisticated and optimized gradient boosting implementation.

It adds important engineering and algorithmic improvements such as:

7.21.27 XGBoost vs Decision Tree

Decision Tree

↓
One tree
↓
Can have high variance

XGBoost:

Tree 1

↓
Tree 2
↓
Tree 3
↓

...

↓
Tree N
↓
Combined Prediction

The ensemble can capture much more complex patterns.

7.21.28 XGBoost and Overfitting

XGBoost is powerful, but it can overfit.

Signs include:

Training Score → Very High
Validation Score → Much Lower

Ways to control overfitting include:

7.21.29 Early Stopping

↓
10 → Score improves
20 → Score improves
30 → Score improves
40 → Score improves
50 → No improvement
60 → No improvement
↓
Stop

This prevents unnecessarily adding more trees.

The exact API for early stopping depends on the XGBoost version and training interface, so it is good practice to follow the version-specific XGBoost documentation.

7.21.30 XGBoost and Learning Rate

There is an important relationship:

Learning Rate ↓
↓
Each Tree Contributes Less
↓
Usually Need More Trees

Model B is not automatically better. Both configurations need validation.

7.21.31 XGBoost Hyperparameter Tuning

XGBoost has many hyperparameters, so tuning is important.

Example:

from sklearn.model_selection import RandomizedSearchCV
from xgboost import XGBClassifier
model = XGBClassifier(
eval_metric="logloss",
random_state=42
)
param_distributions = {
"n_estimators": [100, 200, 300, 500],
"max_depth": [3, 5, 7, 10],
"learning_rate": [0.01, 0.03, 0.05, 0.1],
"subsample": [0.7, 0.8, 1.0],
"colsample_bytree": [0.7, 0.8, 1.0]
}
search = RandomizedSearchCV(
model,
param_distributions,
n_iter=30,
cv=5,
scoring="f1",
random_state=42,
n_jobs=-1
)
search.fit(
X_train,
y_train
)
print(search.best_params_)
print(search.best_score_)

7.21.32 XGBoost with Cross Validation

A good workflow combines XGBoost with cross-validation:

Training Data

↓
XGBoost
↓
5-Fold CV
↓
Evaluate
↓
Tune Hyperparameters
↓
Best Model

For classification, use an appropriate stratified CV strategy when needed.

7.21.33 XGBoost Pipeline

If preprocessing is required, use a pipeline.

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from xgboost import XGBClassifier
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    (
        "model",
        XGBClassifier(
            n_estimators=200,
            max_depth=5,
            learning_rate=0.05,
            random_state=42
        )
    )
])

However, note that tree-based models generally do not require feature scaling. Standardization is usually unnecessary for XGBoost unless another pipeline component or modeling requirement makes it useful.

7.21.34 Complete XGBoost Classification Example

from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import (
    accuracy_score,
    classification_report,
    roc_auc_score
)
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)
model = XGBClassifier(
    n_estimators=300,
    max_depth=5,
    learning_rate=0.05,
    subsample=0.8,
    colsample_bytree=0.8,
    eval_metric="logloss",
    random_state=42
)
model.fit(
    X_train,
    y_train
)
y_pred = model.predict(
    X_test
)
y_prob = model.predict_proba(
    X_test
)[:, 1]
print(
    "Accuracy:",
    accuracy_score(y_test, y_pred)
)
print(
    "ROC-AUC:",
    roc_auc_score(y_test, y_prob)
)
print(
    classification_report(
        y_test,
        y_pred
    )
)

7.21.35 XGBoost Training Workflow

A production-oriented workflow might look like:

Raw Data

↓
Data Quality Checks
↓
Train/Test Split
↓
Feature Engineering
↓
Training Data
↓
Cross Validation
↓
Hyperparameter Tuning
↓
XGBoost Model
↓
Model Evaluation
↓
Feature/Prediction Analysis
↓
Final Test Evaluation
↓
Deployment

7.21.36 Advantages of XGBoost

1. Strong Predictive Performance

It often performs very well on structured/tabular datasets.

2. Regularization

Supports L1 and L2 regularization.

3. Flexible Objectives

Supports multiple classification and regression objectives.

4. Missing-Value Handling

Can handle missing values in many tree-based workflows.

5. Feature Importance

Provides useful model diagnostics.

6. Efficient Implementation

Designed for efficient training on large datasets.

7. Supports Classification and Regression

It can solve many supervised learning problems.

7.21.37 Limitations of XGBoost

1. Hyperparameter Complexity

There are many parameters to tune.

2. Computational Cost

Large models can consume significant CPU and memory.

3. Interpretability

A large ensemble of trees is harder to interpret than a simple linear model.

4. Overfitting

A poorly tuned model can overfit.

5. Not Always the Best Choice

6. Data Representation Still Matters

Good feature engineering and appropriate handling of missing/categorical data can strongly affect results.

7.21.38 XGBoost in Real-World Applications

Fraud Detection

Transaction

↓
XGBoost
↓
Fraud Probability
Customer Churn
Customer Data
↓
XGBoost
↓
Churn Probability
Credit Risk
Customer Financial Data
↓
XGBoost
↓
Risk Score
Sales Forecasting
Historical Features
↓
XGBoost Regressor
↓
Predicted Sales

7.21.39 XGBoost and SHAP

↓
SHAP
↓
Feature Contributions

For example:

Prediction: High Churn Risk

Support Calls → +0.30
Monthly Charges → +0.20
Tenure → -0.15
Income → -0.05

7.21.40 XGBoost and Feature Selection

XGBoost can naturally identify useful features through tree splits, but this does not mean that all low-importance features should automatically be removed.

A useful workflow is:

Train XGBoost

↓
Analyze Importance
↓
Test Feature Subsets
↓
Cross Validation
↓
Compare Performance

Always validate whether feature removal actually improves generalization.

7.21.41 XGBoost vs LightGBM vs CatBoost

These are all gradient-boosting frameworks, but they have different design goals and behaviors.

XGBoost LightGBM CatBoost
Mature and widely used Designed for efficient large-scale training Strong handling of categorical features
Regularized boosting trees Histogram-based efficient training Ordered boosting techniques
Strong tabular performance Often fast on large datasets Convenient categorical workflows
Large ecosystem Excellent scalability Useful with many categorical variables

There is no universally best choice.

The correct algorithm depends on:

7.21.42 Interview Questions

Q1. What is XGBoost?

XGBoost is an optimized gradient-boosting algorithm based primarily on decision trees.

Q2. What does XGBoost stand for?

Extreme Gradient Boosting.

Q3. Is XGBoost bagging or boosting?

Boosting.

Q4. How does XGBoost work?

It builds decision trees sequentially, with each new tree improving the current ensemble by optimizing the chosen loss/objective.

Q5. What is learning_rate?

It controls how much each new tree contributes to the overall model.

Q6. What is n_estimators?

It controls the number of boosting rounds/trees.

Q7. What is max_depth?

It controls the maximum depth of each tree.

Q8. What is subsample?

It controls the fraction of training observations sampled for each boosting round.

Q9. What is colsample_bytree?

It controls the fraction of features sampled for each tree.

Q10. How does XGBoost reduce overfitting?

It provides several controls including:

Q11. Why use a small learning rate?

A smaller learning rate makes each tree contribute less, often requiring more trees but potentially allowing more controlled optimization.

Q12. What is the difference between Random Forest and XGBoost?

Random Forest is primarily a bagging-style ensemble of randomized trees, whereas XGBoost builds trees sequentially using boosting.

Q13. Can XGBoost handle missing values?

Yes, XGBoost's tree-learning process supports missing values in standard workflows.

Q14. Does XGBoost require feature scaling?

Generally no. Tree-based XGBoost models do not typically require standardization or normalization.

Q15. Can XGBoost be used for regression?

Yes. XGBRegressor can be used for regression problems.

7.21.43 Key Takeaways

Data

↓
Train/Test Split
↓
Feature Engineering
↓
Cross Validation
↓
Hyperparameter Tuning
↓
XGBoost
↓
Validation
↓
Final Test Evaluation
↓
Deployment
Module 7 · Lesson 7.22

LightGBM

7.22.1 Introduction

LightGBM stands for Light Gradient Boosting Machine. It is a gradient boosting framework developed by Microsoft and is designed for efficient, scalable tree-based machine learning.

Like XGBoost, LightGBM builds decision trees sequentially:

Training Data

↓
Tree 1
↓
Calculate Errors
↓
Tree 2
↓
Improve Previous Predictions
↓
Tree 3
↓

...

↓
Final LightGBM Model

LightGBM is particularly useful for:

7.22.2 Why LightGBM?

Traditional gradient boosting can become expensive when datasets contain:

LightGBM introduces techniques designed to make tree boosting more efficient.

Its major characteristics include:

7.22.3 LightGBM vs XGBoost

Both are gradient boosting algorithms.

XGBoost

↓
Gradient Boosting
↓
Decision Trees
LightGBM
↓
Gradient Boosting
↓
Decision Trees

The major differences are in how trees are constructed and optimized.

XGBoost LightGBM
Gradient boosting Gradient boosting
Commonly level-wise/depth-wise tree growth Leaf-wise tree growth
Histogram-based methods available Histogram-based by design
Strong performance on tabular data Strong performance, especially on large tabular data
Can require more memory/time depending on workload Often optimized for speed and memory
Broad ecosystem Strong scalability

Neither is universally superior.

7.22.4 How LightGBM Works

LightGBM follows the gradient boosting principle.

Suppose the initial model produces:

Actual → 100
Predicted → 80
Error → 20
The next tree attempts to improve the current model.

Initial Model

↓
Calculate Gradient Information
↓
Build Tree
↓
Update Predictions
↓
Calculate New Errors
↓
Build Next Tree

This process continues for multiple boosting rounds.

7.22.5 Histogram-Based Learning

...

Histogram Bins:

Bin 1 → 10.0–10.4
Bin 2 → 10.5–10.9
Bin 3 → 11.0–11.4
Bin 4 → 11.5–11.9

This can reduce computational and memory requirements.

7.22.6 Leaf-Wise Tree Growth

One of the most important differences between LightGBM and traditional level-wise tree growth is leaf-wise growth.

Suppose a tree has several leaves:

Root

/ \

A B

/ \ / \

C D E F

A level-wise approach tends to grow nodes across a depth level.

LightGBM's leaf-wise approach selects the leaf whose split gives the largest reduction in the objective and splits that leaf.

↓
Split it
↓
Recalculate best split
↓
Split next best leaf

This can produce lower loss efficiently.

7.22.7 Leaf-Wise vs Level-Wise Growth

Level-Wise

Root

/ \

A B

/ \ / \

/ \

A B

/ \

C D

/ \

E F

The algorithm may continue splitting the leaf that provides the greatest improvement.

7.22.8 Advantage of Leaf-Wise Growth

Leaf-wise growth can reduce training loss faster for a given number of leaves.

This can make LightGBM very effective on many tabular problems.

However:

Leaf-wise growth can overfit more easily if the tree is allowed to become too complex.

Therefore, parameters such as num_leaves, max_depth, and min_child_samples are important.

7.22.9 num_leaves

num_leaves is one of the most important LightGBM hyperparameters.

It controls the maximum number of leaves in a tree.

Example:

num_leaves=31

Generally:

num_leaves ↑
↓
More complex trees
↓
Potentially lower bias
↓
Potentially higher overfitting

A common mistake is choosing a very large number of leaves without adequate regularization.

7.22.10 max_depth

max_depth limits the maximum depth of the tree.

Example:

max_depth=8

This can help control the complexity of leaf-wise trees.

Conceptually:

max_depth ↓
↓
Less complex tree
↓
Lower overfitting risk

7.22.11 learning_rate

The learning rate determines how much each tree contributes to the final model.

Example:

learning_rate=0.05

Generally:

Learning Rate ↓
↓
Smaller updates
↓
Usually more trees required

A common strategy is:

Small learning_rate

+

Large n_estimators

with validation or early stopping used to determine an appropriate number of iterations.

7.22.12 n_estimators

n_estimators controls the number of boosting iterations.

Example:

n_estimators=500

Early stopping is often useful for finding a suitable number of iterations.

7.22.13 min_child_samples

min_child_samples specifies a minimum number of observations required in a leaf.

Example:

min_child_samples=20

Increasing it generally makes the model more conservative:

min_child_samples ↑
↓
Fewer tiny leaves
↓
Simpler model
↓
Potentially less overfitting

7.22.14 min_split_gain

min_split_gain specifies the minimum gain required to make a split.

Example:

min_split_gain=0.1

Increasing it makes splitting more difficult.

min_split_gain ↑
↓
Fewer splits
↓
Lower model complexity

7.22.15 subsample

means roughly 80% of the available observations may be sampled per boosting iteration when row subsampling is enabled appropriately.

This can help reduce overfitting.

7.22.16 colsample_bytree

This parameter controls the fraction of features used for each tree.

Example:

↓
80% sampled
↓
~80 Features considered

This can introduce diversity and reduce overfitting.

7.22.17 Regularization

Regularization ↑
↓
Model Complexity ↓
↓
Potential Overfitting ↓

7.22.18 Important LightGBM Hyperparameters

Parameter Purpose
num_leaves Maximum leaves per tree
max_depth Maximum tree depth
learning_rate Contribution of each tree
n_estimators Number of boosting rounds
min_child_samples Minimum observations in a leaf
min_split_gain Minimum gain required for a split
subsample Row sampling
colsample_bytree Feature sampling
reg_alpha L1 regularization
reg_lambda L2 regularization

7.22.19 LightGBM Classification

LightGBM provides LGBMClassifier.

Example:

from lightgbm import LGBMClassifier
model = LGBMClassifier(
n_estimators=300,
learning_rate=0.05,
num_leaves=31,
max_depth=-1,
random_state=42
)
model.fit(
X_train,
y_train
)
predictions = model.predict(
X_test
)

7.22.20 LightGBM Probability Prediction

For binary classification:

probabilities = model.predict_proba(
X_test
)[:, 1]

Example:

These are estimated probabilities for the positive class.

7.22.21 LightGBM Regression

For regression:

from lightgbm import LGBMRegressor
model = LGBMRegressor(
n_estimators=500,
learning_rate=0.05,
num_leaves=31,
random_state=42
)
model.fit(
X_train,
y_train
)
predictions = model.predict(
X_test
)

Possible metrics:

7.22.22 Multi-Class Classification

LightGBM can handle multiple classes.

For example:

Class 0 → Electronics
Class 1 → Furniture
Class 2 → Clothing
Class 3 → Food

Example:

from lightgbm import LGBMClassifier
model = LGBMClassifier(
objective="multiclass",
num_class=4,
n_estimators=300,
learning_rate=0.05,
num_leaves=31,
random_state=42
)

7.22.23 Native Categorical Features

↓
Premium
Standard
Basic

Instead of necessarily creating thousands of one-hot columns, LightGBM can work with categorical features through its categorical-feature mechanism.

The exact setup depends on the data representation and LightGBM API being used.

7.22.24 Why Categorical Support Matters

One-hot encoding can produce a very wide matrix:

...

For high-cardinality categorical variables, this can become expensive.

Native categorical handling can sometimes be more efficient.

However, categorical encoding should always be validated against the specific dataset and model configuration.

7.22.25 LightGBM and Missing Values

The tree-learning process can determine appropriate split behavior for missing values.

Nevertheless, missing values should still be investigated because they may represent important business or data-quality signals.

7.22.26 LightGBM Feature Importance

LightGBM provides feature importance.

importance = model.feature_importances_
print(importance)

Possible importance measures include:

Gain is often more useful when assessing how much features contribute to reducing the objective.

7.22.27 Plotting Feature Importance

LightGBM provides utilities for visualizing feature importance.

For example:

import lightgbm as lgb
import matplotlib.pyplot as plt
lgb.plot_importance(
model,
importance_type="gain"
)
plt.show()

This can help identify important features.

But feature importance is not equivalent to causal influence.

7.22.28 LightGBM and Overfitting

Because LightGBM uses leaf-wise growth, controlling tree complexity is particularly important.

A model may overfit when:

num_leaves ↑
max_depth ↑
min_child_samples ↓

7.22.29 Early Stopping

↓
100 → Improving
200 → Improving
300 → Improving
400 → Improving
450 → No improvement
500 → No improvement
↓
Stop

This can prevent unnecessary boosting iterations.

The exact LightGBM API for early stopping can vary by version; current LightGBM releases commonly support callbacks such as lightgbm.early_stopping().

Example:

import lightgbm as lgb
from lightgbm import LGBMClassifier
model = LGBMClassifier(
n_estimators=2000,
learning_rate=0.03,
num_leaves=31,
random_state=42
)
model.fit(
X_train,
y_train,
eval_set=[(X_valid, y_valid)],
callbacks=[
lgb.early_stopping(
100
)
]
)

The model stops if the validation metric does not improve for the specified number of rounds.

7.22.30 LightGBM vs Random Forest

Random Forest LightGBM
Bagging-style Boosting
Trees are largely independent Trees built sequentially
Primarily reduces variance Sequentially optimizes loss
Usually easier to tune initially Often requires more tuning
Strong general-purpose baseline Often very strong on large tabular data
Naturally robust Can overfit if leaf complexity is excessive

7.22.31 LightGBM vs XGBoost

Both are excellent gradient boosting algorithms.

LightGBM XGBoost
Leaf-wise tree growth Commonly level-wise/depth-wise growth
Histogram-based Histogram-based algorithms
Often very fast on large datasets Very strong general-purpose boosting
Can be memory efficient Can have strong regularization controls
Native categorical support Modern versions also support categorical data under suitable configuration
num_leaves is especially important max_depth is often a major complexity control

Performance depends heavily on the dataset and tuning.

7.22.32 LightGBM vs CatBoost

LightGBM CatBoost
Excellent for large tabular datasets Particularly convenient with categorical features
Leaf-wise growth Uses its own ordered boosting techniques
Very fast in many workloads Strong categorical handling
Requires careful tuning of leaves Often strong with relatively convenient defaults

Again, benchmark on the actual dataset rather than assuming one is always superior.

7.22.33 LightGBM Hyperparameter Tuning

Because LightGBM has many hyperparameters, tuning is important.

Example:

from sklearn.model_selection import RandomizedSearchCV
from lightgbm import LGBMClassifier
model = LGBMClassifier(
objective="binary",
random_state=42
)
param_distributions = {
"n_estimators": [100, 200, 500, 1000],
"learning_rate": [0.01, 0.03, 0.05, 0.1],
"num_leaves": [15, 31, 63, 127],
"max_depth": [-1, 5, 10, 15],
"min_child_samples": [10, 20, 50, 100],
"subsample": [0.7, 0.8, 1.0],
"colsample_bytree": [0.7, 0.8, 1.0]
}
search = RandomizedSearchCV(
model,
param_distributions,
n_iter=30,
cv=5,
scoring="f1",
random_state=42,
n_jobs=-1
)
search.fit(
X_train,
y_train
)
print(
search.best_params_
)
print(
search.best_score_
)

7.22.34 LightGBM and Cross Validation

A typical workflow is:

Training Data

↓
5-Fold Cross Validation
↓
Try LightGBM Parameters
↓
Calculate Validation Scores
↓
Compare Configurations
↓
Best Configuration

For classification, use stratified cross-validation when appropriate.

7.22.35 LightGBM and Feature Scaling

Like other tree-based models:

LightGBM generally does not require feature scaling.

For example, you normally do not need:

StandardScaler()

just because one feature is:

Age → 20–80

and another is:

Income → 20,000–2,000,000

Tree split decisions are based on thresholds rather than distance or coefficient magnitude.

7.22.36 Complete LightGBM Classification Example

from lightgbm import LGBMClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import (
    accuracy_score,
    classification_report,
    roc_auc_score
)
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)
model = LGBMClassifier(
    n_estimators=500,
    learning_rate=0.05,
    num_leaves=31,
    max_depth=-1,
    min_child_samples=20,
    subsample=0.8,
    colsample_bytree=0.8,
    random_state=42
)
model.fit(
    X_train,
    y_train
)
y_pred = model.predict(
    X_test
)
y_prob = model.predict_proba(
    X_test
)[:, 1]
print(
    "Accuracy:",
    accuracy_score(
        y_test,
        y_pred
    )
)
print(
    "ROC-AUC:",
    roc_auc_score(
        y_test,
        y_prob
    )
)
print(
    classification_report(
        y_test,
        y_pred
    )
)

7.22.37 LightGBM Regression Example

from lightgbm import LGBMRegressor
from sklearn.metrics import mean_squared_error
import numpy as np
model = LGBMRegressor(
    n_estimators=500,
    learning_rate=0.05,
    num_leaves=31,
    max_depth=-1,
    random_state=42
)
model.fit(
    X_train,
    y_train
)
predictions = model.predict(
    X_test
)
rmse = np.sqrt(
    mean_squared_error(
        y_test,
        predictions
    )
)
print(
    "RMSE:",
    rmse
)

7.22.38 LightGBM Ranking

LightGBM can also be used for learning-to-rank problems.

Examples:

Conceptually:

Query

↓
Candidate Items
↓
LightGBM Ranking Model
↓
Relevance Scores
↓
Ranked Results

This is one area where gradient boosting can be especially useful.

7.22.39 LightGBM and Imbalanced Classification

Suppose:

Normal → 99%
Fraud → 1%

)

For binary classification, parameters such as scale_pos_weight can also be considered.

The appropriate strategy depends on the class distribution, metric, and business cost of errors.

7.22.40 LightGBM and SHAP

↓
SHAP
↓
Feature Contributions

Example:

This helps explain why a particular prediction was made.

7.22.41 Advantages of LightGBM

1. Fast Training

Designed for efficient gradient boosting.

2. Good Scalability

Can handle large tabular datasets effectively.

3. Memory Efficiency

Histogram-based learning can reduce memory requirements.

4. Strong Predictive Performance

Often performs very well on structured data.

5. Categorical Features

Supports categorical features in suitable configurations.

6. Missing Values

Supports missing-value handling in standard tree workflows.

7. Flexible

Supports classification, regression, and ranking.

7.22.42 Limitations of LightGBM

1. Can Overfit

Leaf-wise growth can create highly complex trees.

2. Hyperparameter Tuning

Important parameters such as num_leaves require careful tuning.

3. Less Interpretable

Hundreds of trees are harder to explain than a simple linear model.

4. Small Datasets

On very small datasets, LightGBM's flexibility can sometimes increase overfitting risk.

5. Parameter Complexity

There are many parameters and interactions to understand.

7.22.43 Real-World Example — Customer Churn

↓
Data Cleaning
↓
Feature Engineering
↓
LightGBM
↓
Churn Probability

Output:

Customer A → 0.82
Customer B → 0.14
Customer C → 0.67

We could classify customers as high-risk using a threshold chosen according to the business objective.

7.22.44 LightGBM Production Workflow

A production workflow could be:

Raw Data

↓
Data Quality
↓
Feature Engineering
↓
Train/Test Split
↓
Cross Validation
↓
Hyperparameter Tuning
↓
LightGBM Training
↓
Model Evaluation
↓
SHAP / Feature Analysis
↓
Final Test
↓
Model Registry
↓
Deployment
↓
Monitoring

7.22.45 Interview Questions

Q1. What is LightGBM?

LightGBM is an efficient gradient boosting framework based on decision trees.

Q2. What does LightGBM stand for?

Light Gradient Boosting Machine.

Q3. Is LightGBM bagging or boosting?

Boosting.

Q4. What is the major difference between LightGBM and traditional tree growth?

LightGBM uses leaf-wise tree growth, selecting the leaf that gives the greatest objective improvement.

Q5. What is num_leaves?

It controls the maximum number of leaves in a tree and is one of LightGBM's most important complexity parameters.

Q6. Why can LightGBM overfit?

Because leaf-wise tree growth can create very complex trees, particularly when num_leaves is large and leaf-size constraints are weak.

Q7. What is learning_rate?

It controls how much each new tree contributes to the ensemble.

Q8. What is n_estimators?

It controls the number of boosting iterations/trees.

Q9. What is min_child_samples?

It controls the minimum number of observations required in a leaf.

Q10. Does LightGBM require feature scaling?

Generally, no, because it is tree-based.

Q11. What is histogram-based learning?

It groups continuous feature values into bins, allowing split calculations to be performed more efficiently.

Q12. How can you reduce LightGBM overfitting?

You can:

Q13. What is the difference between LightGBM and XGBoost?

Both are gradient boosting algorithms, but LightGBM uses leaf-wise tree growth and is heavily optimized for efficient large-scale training.

Q14. Can LightGBM handle categorical features?

Yes, LightGBM supports categorical features when configured and represented appropriately.

Q15. Can LightGBM perform regression?

Yes. LGBMRegressor can be used for regression.

7.22.46 Key Takeaways

Module 7 · Lesson 7.23

CatBoost

7.23.1 Introduction

CatBoost is a gradient boosting machine learning algorithm developed by Yandex. The name comes from Categorical Boosting.

It is particularly designed to work well with categorical features while maintaining strong performance on structured/tabular data.

Like XGBoost and LightGBM, CatBoost builds an ensemble of decision trees sequentially:

Training Data

↓
Tree 1
↓
Calculate Errors
↓
Tree 2
↓
Improve Predictions
↓
Tree 3
↓

...

↓
Final CatBoost Model

CatBoost can be used for:

7.23.2 Why CatBoost?

With high-cardinality variables, this can create thousands of columns.

CatBoost provides specialized handling for categorical features.

7.23.3 Main Characteristics of CatBoost

Important characteristics include:

7.23.4 CatBoost vs XGBoost vs LightGBM

All three are gradient boosting algorithms:

Gradient Boosting

│
┌──────────────┼──────────────┐
↓ ↓ ↓
XGBoost LightGBM CatBoost

But they have different strengths.

XGBoost LightGBM CatBoost
General-purpose gradient boosting Strong focus on efficient large-scale training Strong focus on categorical data
Excellent tabular performance Leaf-wise growth Ordered boosting
Extensive tuning options Very fast in many workloads Often convenient preprocessing
Strong regularization Histogram-based Ordered categorical encoding
Categorical support in modern versions Native categorical support Particularly strong categorical workflow

The best choice depends on the dataset.

7.23.5 What Are Categorical Features?

These are categorical values.

7.23.6 The Problem with Target Encoding

We could replace the city with its historical target average.

7.23.7 Ordered Target Statistics

↓
Create an ordering
↓
For each observation
use information from
earlier observations
↓
Calculate category statistics
↓
Use encoded representation

Instead of simply calculating:

Category → Average target using ALL rows

CatBoost uses an ordered approach so that the target of the current observation is not improperly used to construct its own encoding.

7.23.8 Example of Ordered Encoding

A naive target encoding might calculate the overall average for each city using every observation.

CatBoost's ordered approach uses a permutation and historical/earlier observations when constructing the statistics.

The exact calculation includes smoothing/prior information, but the key idea is:

Avoid using the current observation's target directly when generating its categorical representation.

7.23.9 Ordered Boosting

↓
Random Ordering
↓
Build predictions using
appropriate preceding information
↓
Calculate gradients
↓
Build next tree

This is one of CatBoost's key algorithmic ideas.

7.23.10 CatBoost Training Process

A simplified workflow:

Input Data

↓
Identify Categorical Features
↓
Create Ordered Statistics
↓
Build Initial Model
↓
Calculate Gradients
↓
Build Tree
↓
Update Predictions
↓
Repeat
↓
Final CatBoost Model

7.23.11 CatBoostClassifier

For classification, use:

from catboost import CatBoostClassifier
model = CatBoostClassifier(
iterations=500,
learning_rate=0.05,
depth=6,
random_seed=42,
verbose=False
)
model.fit(
X_train,
y_train
)

Predictions:

predictions = model.predict(
X_test
)

7.23.12 CatBoostRegressor

For regression:

from catboost import CatBoostRegressor
model = CatBoostRegressor(
iterations=500,
learning_rate=0.05,
depth=6,
random_seed=42,
verbose=False
)
model.fit(
X_train,
y_train
)
predictions = model.predict(
X_test
)

Common regression metrics include:

7.23.13 Important CatBoost Hyperparameters

7.23.14 iterations

iterations controls the number of boosting iterations.

Example:

↓
Underfitting
Too Many Iterations
↓
Potential Overfitting

Early stopping can be used to determine a suitable number of iterations.

7.23.15 learning_rate

The learning rate controls how much each tree contributes.

Example:

learning_rate=0.05

Generally:

Learning Rate ↓
↓
Smaller Updates
↓
More Iterations Often Needed

A smaller learning rate can provide more gradual learning, but usually increases training time because more iterations may be required.

7.23.16 depth

depth controls the depth of the trees.

Example:

depth=6

Increasing depth:

depth ↑
↓
More complex trees
↓
Potentially lower bias
↓
Potentially higher overfitting

Reducing depth can make the model more conservative.

7.23.17 l2_leaf_reg

l2_leaf_reg controls L2 regularization.

Example:

l2_leaf_reg=5

Increasing regularization generally makes the model less flexible.

Regularization ↑
↓
Model Complexity ↓
↓
Overfitting Risk ↓

The exact optimal value depends on the data.

7.23.18 random_strength

Randomness ↑
↓
More diversity
↓
Potentially less overfitting

7.23.19 bagging_temperature

↓
Regularization
↓
Generalization

7.23.20 Handling Categorical Features

We can identify categorical columns:

]

Then:

model.fit(
X_train,
y_train,
cat_features=categorical_features
)

This allows CatBoost to apply its categorical-feature handling.

7.23.21 Complete Categorical Example

from catboost import CatBoostClassifier
categorical_features = [
    "City",
    "PaymentType",
    "CustomerSegment"
]
model = CatBoostClassifier(
iterations=500,
learning_rate=0.05,
depth=6,
loss_function="Logloss",
random_seed=42,
verbose=False
)
model.fit(
X_train,
y_train,
cat_features=categorical_features
)
predictions = model.predict(
X_test
)

7.23.22 Why CatBoost Can Be Convenient

Without CatBoost:

Categorical Data

↓
Encoding
↓
Large Feature Matrix
↓
Model

With CatBoost:

Categorical Data

↓
CatBoost
↓
Categorical Handling
↓
Model

This can simplify preprocessing pipelines, especially when there are many categorical variables.

7.23.23 CatBoost and Missing Values

CatBoost can handle missing numerical values in its tree-based learning process.

Example:

However, categorical missing values should be represented appropriately according to the CatBoost API and data-processing workflow.

Always investigate why values are missing rather than blindly relying on automatic handling.

7.23.24 CatBoost and Numerical Features

Unlike KNN or SVM, CatBoost generally does not require standardization.

No need for:

StandardScaler
MinMaxScaler

in a typical CatBoost tree-based workflow.

7.23.25 CatBoost and Feature Scaling

Age → 18–80
Income → 20,000–2,000,000

The different numerical scales do not normally create the same issues they would for distance-based or coefficient-based models.

7.23.26 CatBoost Classification

Output:

Customer A → 0.83
Customer B → 0.14
Customer C → 0.71

These are estimated churn probabilities.

7.23.27 CatBoost Probability Prediction

probabilities = model.predict_proba(
X_test
)[:, 1]

Example:

The classification threshold can then be selected based on business requirements.

7.23.28 Multi-Class Classification

CatBoost supports multiple classes.

Example:

0 → Electronics
1 → Furniture
2 → Clothing
3 → Food
from catboost import CatBoostClassifier
model = CatBoostClassifier(
loss_function="MultiClass",
iterations=500,
depth=6,
learning_rate=0.05,
random_seed=42,
verbose=False
)

7.23.29 CatBoost Regression

CatBoost can predict continuous values.

Example:

from catboost import CatBoostRegressor
model = CatBoostRegressor(
iterations=500,
depth=6,
learning_rate=0.05,
loss_function="RMSE",
random_seed=42,
verbose=False
)
model.fit(
X_train,
y_train
)

7.23.30 CatBoost Ranking

CatBoost also supports ranking problems.

Examples:

Conceptually:

Search Query

↓
Candidate Items
↓
CatBoost Ranking Model
↓
Relevance Scores
↓
Ranked Results

This makes CatBoost useful beyond ordinary classification and regression.

7.23.31 Early Stopping

CatBoost supports early stopping using a validation dataset.

Example:

model = CatBoostClassifier(
iterations=2000,
learning_rate=0.03,
depth=6,
loss_function="Logloss",
random_seed=42,
verbose=False
)
model.fit(
X_train,
y_train,
eval_set=(X_valid, y_valid),
early_stopping_rounds=100
)

Conceptually:

Iteration

↓
100 → Improving
200 → Improving
300 → Improving
400 → No improvement
500 → No improvement
↓
Stop

This can prevent unnecessary iterations and help control overfitting.

7.23.32 CatBoost Hyperparameter Tuning

Example:

from sklearn.model_selection import RandomizedSearchCV
from catboost import CatBoostClassifier
model = CatBoostClassifier(
verbose=False,
random_seed=42
)
param_distributions = {
"depth": [4, 5, 6, 8, 10],
"learning_rate": [
0.01,
0.03,
0.05,
0.1
],
"iterations": [
200,
500,
1000
],
"l2_leaf_reg": [
1,
3,
5,
10
]
}
search = RandomizedSearchCV(
model,
param_distributions,
n_iter=20,
cv=5,
scoring="f1",
random_state=42,
n_jobs=-1
)
search.fit(
X_train,
y_train
)
print(search.best_params_)
print(search.best_score_)

When categorical features are involved, make sure the search/training workflow passes cat_features correctly.

7.23.33 CatBoost and Cross Validation

Cross-validation can be used to compare CatBoost configurations.

Training Data

↓
5-Fold CV
↓
CatBoost Configuration 1
↓
Score
CatBoost Configuration 2
↓
Score
CatBoost Configuration 3
↓
Score
↓
Best Configuration

For classification, stratified folds are commonly appropriate.

7.23.34 CatBoost Feature Importance

CatBoost provides feature importance.

importance = model.get_feature_importance()
print(importance)

Example:

These values indicate how the model uses the features, not causal effects.

7.23.35 CatBoost Feature Importance Visualization

CatBoost provides built-in plotting functionality.

model.get_feature_importance(
prettified=True
)

This can produce a ranked feature-importance table.

7.23.36 CatBoost and SHAP

↓
SHAP
↓
Feature Contributions

Example:

7.23.37 CatBoost vs One-Hot Encoding

CatBoost's categorical handling can be much more compact and can exploit category-target relationships.

However, this does not mean CatBoost is always better than one-hot encoding. The correct approach should be validated on the actual problem.

7.23.38 CatBoost and High-Cardinality Features

may have almost one unique value per customer.

Although an algorithm can technically process such features, they may provide little generalizable information and can create leakage or memorization risks.

Therefore:

Not every categorical column should automatically be passed to CatBoost.

7.23.39 Data Leakage with CatBoost

CatBoost's ordered target statistics help reduce leakage from categorical encoding, but they do not magically eliminate all forms of data leakage.

For example, this is still problematic:

Future Information

↓
Feature
↓
CatBoost

If a feature contains information that would not be available at prediction time, the model can still leak future information.

Always ensure:

Training Features

=

Information Available at Prediction Time

7.23.40 CatBoost and Imbalanced Data

Suppose:

Normal → 98%
Fraud → 2%

Accuracy may not be an appropriate optimization metric.

CatBoost provides class-weighting mechanisms.

Example:

)

The correct weights depend on the problem and should be validated.

Other metrics such as:

may be more useful than accuracy.

7.23.41 Complete CatBoost Classification Example

from catboost import CatBoostClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import (
    accuracy_score,
    roc_auc_score,
    classification_report
)
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)
categorical_features = [
    "City",
    "ContractType",
    "PaymentMethod"
]
model = CatBoostClassifier(
iterations=500,
depth=6,
learning_rate=0.05,
l2_leaf_reg=5,
loss_function="Logloss",
random_seed=42,
verbose=False
)
model.fit(
X_train,
y_train,
cat_features=categorical_features
)
y_pred = model.predict(
X_test
)
y_prob = model.predict_proba(
X_test
)[:, 1]
print(

"Accuracy:",

accuracy_score(
y_test,
y_pred
)
)
print(

"ROC-AUC:",

roc_auc_score(
y_test,
y_prob
)
)
print(
classification_report(
y_test,
y_pred
)
)

7.23.42 CatBoost vs XGBoost vs LightGBM

A practical comparison:

Feature XGBoost LightGBM CatBoost
Boosting Yes Yes Yes
Tree-based Yes Yes Yes
Large tabular data Excellent Excellent Excellent
Categorical handling Supported in modern versions Supported Excellent
Leaf-wise growth No, traditionally level-wise Yes Uses symmetric trees by default
Ordered boosting No No Yes
Fast training Yes Often very fast Yes
GPU support Yes Yes Yes
Ranking Yes Yes Yes
Easy categorical workflow Moderate Good Excellent

The exact performance depends on the data, feature types, implementation, and tuning.

7.23.43 CatBoost's Symmetric Trees

/ \

Yes No

/ \

Feature B < 5? Feature B < 5?

The same condition is applied at corresponding levels.

This structure can make prediction efficient and contributes to CatBoost's design.

7.23.44 Comparison of Tree Growth

XGBoost

↓
Traditionally level-wise/depth-wise
LightGBM
↓
Leaf-wise
CatBoost
↓
Symmetric / Oblivious Trees

This is a useful interview distinction.

7.23.45 CatBoost Advantages

1. Excellent Categorical Handling

This is CatBoost's most recognizable strength.

2. Reduced Target-Encoding Leakage

Ordered statistics are designed to avoid directly using an observation's own target when constructing its categorical representation.

3. Strong Tabular Performance

Often performs very well on structured datasets.

4. Good Default Settings

CatBoost can provide strong results without an extremely large amount of manual tuning.

5. Missing-Value Support

Supports missing numerical values in standard workflows.

6. GPU Support

Can accelerate training for suitable workloads.

7. Classification, Regression, Ranking

Supports several major supervised learning tasks.

7.23.46 CatBoost Limitations

1. Training Can Still Be Expensive

Large datasets and many iterations can require significant resources.

2. Model Complexity

Hundreds or thousands of trees are difficult to interpret directly.

3. Hyperparameter Tuning

Performance can still benefit from careful tuning.

4. Categorical Features Need Proper Handling

The model needs to know which columns are categorical.

5. Not Always the Fastest

LightGBM may be faster on some large numerical datasets.

6. Not Always the Most Accurate

XGBoost, LightGBM, CatBoost, or another model may win depending on the dataset.

7.23.47 Real-World Example — E-Commerce Churn

+

Categorical Features

↓
CatBoost
↓
Churn Probability

This is one of the scenarios where CatBoost can be particularly attractive.

7.23.48 Production Workflow

A production workflow could be:

Raw Data

↓
Data Quality Checks
↓
Identify Feature Types
↓
Remove Leakage
↓
Train/Test Split
↓
CatBoost
↓
Cross Validation
↓
Hyperparameter Tuning
↓
Model Evaluation
↓
SHAP / Feature Analysis
↓
Final Test
↓
Deployment
↓
Model Monitoring

7.23.49 Interview Questions

Q1. What is CatBoost?

CatBoost is a gradient boosting algorithm designed particularly to handle categorical features effectively.

Q2. What does CatBoost stand for?

Categorical Boosting.

Q3. Is CatBoost bagging or boosting?

Boosting.

Q4. What is CatBoost's major advantage?

Its strong and convenient handling of categorical features using ordered statistical techniques.

Q5. What are ordered target statistics?

They are a way of converting categorical information into useful numerical statistics while reducing target leakage by using an ordering mechanism.

Q6. What is ordered boosting?

A boosting technique designed to reduce prediction-shift/target-leakage-related issues during training.

Q7. Does CatBoost require one-hot encoding?

Not necessarily. CatBoost can directly handle categorical features when they are correctly specified.

Q8. Does CatBoost require feature scaling?

Generally no, because it is tree-based.

Q9. What is depth?

It controls the depth of the trees.

Q10. What is iterations?

It controls the number of boosting iterations.

Q11. What is learning_rate?

It controls how much each tree contributes to the ensemble.

Q12. How can CatBoost overfitting be reduced?

Possible approaches include:

Q13. What is the difference between CatBoost and LightGBM?

LightGBM is known for leaf-wise tree growth and efficient large-scale training, while CatBoost is particularly designed around effective categorical handling and ordered boosting.

Q14. What is the difference between CatBoost and XGBoost?

Both are gradient boosting methods, but CatBoost emphasizes categorical features and ordered boosting, while XGBoost is a highly optimized general-purpose gradient boosting framework.

Q15. Can CatBoost perform regression?

Yes. CatBoostRegressor supports regression.

7.23.50 Key Takeaways

Data

↓
Identify Numerical + Categorical Features
↓
Remove Leakage
↓
Train/Test Split
↓
CatBoost
↓
Cross Validation
↓
Hyperparameter Tuning
↓
Early Stopping
↓
Final Test Evaluation
↓
Explainability
↓
Deployment
Module 7 · Lesson 7.24

Model Evaluation

7.24 Model Evaluation

7.24.1 Introduction

Model Evaluation is the process of measuring how well a machine learning model performs on data that it has not seen during training.

Training Accuracy → 99%
Test Accuracy → 72%
↓
Train Model
↓
Validation Data
↓
Tune Model
↓
Test Data
↓
Final Evaluation

7.24.2 Why Model Evaluation Is Important

Model evaluation helps us:

7.24.3 Training, Validation and Test Data

A common dataset split is:

Complete Dataset

│
┌─────────┴─────────┐
↓ ↓
Training Data Test Data
│
↓
Model Training
│
↓
Validation Data

A more practical representation is:

Dataset

│
├── Training Set → Train model
│
├── Validation Set → Tune/select model
│
└── Test Set → Final unbiased evaluation

7.24.4 Training Set

The training set is used to learn the model parameters.

For example:

X_train

+

y_train
↓
Model.fit()

The model learns relationships between features and target values.

7.24.5 Validation Set

The validation set is used during model development.

It can be used for:

Example:

Model A → Validation Score = 0.84
Model B → Validation Score = 0.89
Model C → Validation Score = 0.86

Model B may be selected.

7.24.6 Test Set

The test set should ideally be kept untouched until the final evaluation.

Example:

Final Model

↓
Test Data
↓
Final Performance

The test set provides an estimate of how the finalized model may perform on unseen data.

7.24.7 Data Leakage

One of the biggest evaluation problems is data leakage.

Data leakage occurs when information that should not be available during training influences the model.

Example:

Test Data

↓
Preprocessing
↓
Training Model

This can make the evaluation score artificially high.

7.24.8 Correct Evaluation Workflow

Instead of:

Complete Dataset

↓
Scaling
↓
Train/Test Split

prefer:

Complete Dataset

↓
Train/Test Split
↓
Training Data → Fit preprocessing
↓
Test Data → Transform using fitted preprocessing

For complex preprocessing, a pipeline is often the safest approach.

7.24.9 Classification Metrics

For classification problems, common evaluation metrics include:

Different metrics answer different questions.

7.24.10 Accuracy

Accuracy measures the proportion of predictions that are correct.

\[Accuracy = \frac{TP+TN} {TP+TN+FP+FN}\]

where:

Example:

= 90%

7.24.11 When Accuracy Is Useful

Accuracy works well when:

Example:

Class A → 50%
Class B → 50%

Accuracy can be informative here.

But accuracy can be misleading for highly imbalanced datasets.

7.24.12 Accuracy Problem with Imbalanced Data

Suppose:

Normal Transactions → 99%
Fraud Transactions → 1%

A model that predicts:

Every transaction → Normal

gets:

\[Accuracy=99%\]

But:

Fraud Detection Performance → Terrible

Therefore, accuracy alone is inappropriate.

7.24.13 Confusion Matrix

A confusion matrix summarizes classification predictions.

For binary classification:

Predicted Positive Predicted Negative
Actual Positive TP FN
Actual Negative FP TN

Example:

This gives the foundation for many classification metrics.

7.24.14 True Positive

A True Positive (TP) occurs when:

Actual → Positive
Predicted → Positive

Example:

7.24.15 True Negative

A True Negative (TN) occurs when:

Actual → Negative
Predicted → Negative

Example:

7.24.16 False Positive

A False Positive (FP) occurs when:

Actual → Negative
Predicted → Positive

Example:

Actual: Normal

Prediction: Fraud

This is sometimes called a Type I error.

7.24.17 False Negative

A False Negative (FN) occurs when:

Actual → Positive
Predicted → Negative

Example:

Actual: Fraud

Prediction: Normal

This is sometimes called a Type II error.

7.24.18 Precision

Precision answers:

Of all observations predicted as positive, how many were actually positive?

\[\boxed{ Precision = \frac{TP}{TP+FP} }\]

Example:

= 80%

High precision means relatively few false positives.

7.24.19 Recall

Recall answers:

Of all actual positive observations, how many did the model correctly identify?

\[\boxed{ Recall = \frac{TP}{TP+FN} }\]

Example:

= 90%

High recall means relatively few false negatives.

7.24.20 Precision vs Recall

Useful when missing fraud is very expensive.

7.24.21 Precision-Recall Tradeoff

↑
│\
│ \
│ \
│ \
│ \
└──────────→ Recall

The best balance depends on the business problem.

7.24.22 F1 Score

The F1 score is the harmonic mean of precision and recall.

\[\boxed{ F1 = 2 \frac{Precision \times Recall} {Precision+Recall} }\]

Example:

\[F1 2\frac{0.8\times0.6}{0.8+0.6}\]

\[F1 \approx 0.686\]

7.24.23 Why Harmonic Mean?

Therefore:

A high F1 score requires both precision and recall to be reasonably strong.

7.24.24 ROC Curve

The ROC curve plots:

\[TPR\]

against:

\[FPR\]

where:

\[TPR = \frac{TP}{TP+FN}\]

and:

\[FPR = \frac{FP}{FP+TN}\]

Conceptually:

TPR

↑
1│ ______
│ /
│ /
│ /
│ /
│ /
0└──────────────→ FPR
0 1

The closer the curve is to the top-left corner, the better the ranking performance generally is.

7.24.25 ROC-AUC

ROC-AUC represents the area under the ROC curve.

It is commonly interpreted as the probability that a randomly chosen positive example receives a higher model score than a randomly chosen negative example.

Approximate interpretation:

AUC = 0.5 → Random ranking
AUC > 0.5 → Better than random
AUC = 1.0 → Perfect ranking

ROC-AUC is covered in detail in Section 7.25.

7.24.26 Precision-Recall Curve

For highly imbalanced classification problems, the Precision-Recall curve can be more informative than ROC analysis.

It plots:

Precision

↑
│\
│ \
│ \
│ \
└────────→ Recall

Example:

These are situations where the positive class may be rare.

7.24.27 PR-AUC / Average Precision

The area under the Precision-Recall relationship summarizes performance across thresholds.

In scikit-learn, Average Precision is commonly used as a summary metric for precision-recall performance.

For highly imbalanced classification:

ROC-AUC

+

Average Precision

+

Precision/Recall

can provide a more complete picture than accuracy alone.

7.24.28 Threshold Selection

Many classification models produce probabilities.

Example:

Customer A → 0.91
Customer B → 0.72
Customer C → 0.31
Customer D → 0.18

A common threshold is:

\[0.5\]

So:

Probability >= 0.5 → Positive
Probability < 0.5 → Negative

But 0.5 is not always the optimal threshold.

The threshold should depend on:

7.24.29 Regression Metrics

For regression problems, common metrics include:

7.24.30 Mean Absolute Error

MAE measures the average absolute difference between actual and predicted values.

\[\boxed{ MAE= \frac{1}{n} \sum_{i=1}^{n} |y_i-\hat y_i| }\]

Example:

\[\frac{10+20+20}{3} 16.67\]

7.24.31 Mean Squared Error

MSE calculates the average squared error.

\[\boxed{ MSE= \frac{1}{n} \sum_{i=1}^{n} (y_i-\hat y_i)^2 }\]

Large errors are penalized more heavily because errors are squared.

7.24.32 Root Mean Squared Error

RMSE is:

\[\boxed{ RMSE=\sqrt{MSE} }\]

It has the same units as the target variable.

For example:

Actual Target → ₹
RMSE → ₹

This makes RMSE easier to interpret than MSE in many cases.

7.24.33 MAE vs RMSE

MAE RMSE
Uses absolute errors Uses squared errors
Less sensitive to outliers More sensitive to large errors
Easy to interpret Penalizes large errors strongly
Same units as target Same units as target

Example:

Error:

1, 2, 3, 20

RMSE will be strongly influenced by the 20-unit error.

7.24.34 (R^2) Score

(R^2) measures the proportion of variance in the target explained by the model relative to a baseline that predicts the training mean.

\[\boxed{ R^2 = 1- \frac{\sum(y_i-\hat y_i)^2} {\sum(y_i-\bar y)^2} }\]

where:

7.24.35 Interpretation of (R^2)

A simplified interpretation:

R² = 1.0 → Perfect predictions
R² = 0.0 → No improvement over mean baseline
R² < 0 → Worse than mean baseline

An (R^2) value should not automatically be interpreted as "percentage of reality explained" in every context; its interpretation depends on the modeling setup.

7.24.36 Example of Regression Evaluation

Model A appears better on all three metrics, assuming the metrics are computed on the same test set.

7.24.37 Cross Validation

Instead of relying on one train/validation split, we can use cross-validation.

Example:

Dataset

↓
Fold 1
Fold 2
Fold 3
Fold 4
Fold 5
↓
Train/Evaluate repeatedly
↓
Average Performance

Example:

Fold 1 → 0.88
Fold 2 → 0.91
Fold 3 → 0.89
Fold 4 → 0.90
Fold 5 → 0.92
Mean → 0.90

Cross-validation is covered in detail in Section 7.17.

7.24.38 Stratified Cross Validation

For classification, especially with imbalanced classes, Stratified K-Fold can preserve approximately similar class proportions across folds.

Example:

Original:

Positive → 20%
Negative → 80%

Each fold:

Positive → approximately 20%
Negative → approximately 80%

This can produce more representative validation splits.

7.24.39 Time-Series Evaluation

Randomly splitting time-series data can cause leakage.

Incorrect:

2024 → Training
2025 → Training
2023 → Test

The model may learn from future information.

Better:

Past ───────────────→ Future

Training:

2023 ── 2024

Time-series models should generally respect temporal order.

7.24.40 Model Evaluation Example

Suppose we compare three classification models.

Model Accuracy Precision Recall F1
Logistic Regression 0.86 0.81 0.76 0.78
Random Forest 0.89 0.86 0.82 0.84
XGBoost 0.91 0.88 0.86 0.87

XGBoost appears strongest based on these metrics.

But we should also examine:

before selecting it for production.

7.24.41 Model Evaluation in Python

For classification:

from sklearn.metrics import (
    accuracy_score,
    precision_score,
    recall_score,
    f1_score,
    confusion_matrix,
    roc_auc_score
)
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]
print(
    "Accuracy:",
    accuracy_score(y_test, y_pred)
)
print(
    "Precision:",
    precision_score(y_test, y_pred)
)
print(
    "Recall:",
    recall_score(y_test, y_pred)
)
print(
    "F1:",
    f1_score(y_test, y_pred)
)
print(
    "ROC-AUC:",
    roc_auc_score(y_test, y_prob)
)
print(
    confusion_matrix(y_test, y_pred)
)

7.24.42 Classification Report

Scikit-learn provides a convenient summary:

from sklearn.metrics import classification_report
print(
classification_report(
y_test,
y_pred
)
)

Example:

This is especially useful for multi-class classification.

7.24.43 Regression Evaluation in Python

from sklearn.metrics import (
mean_absolute_error,
mean_squared_error,
r2_score
)
import numpy as np
predictions = model.predict(
X_test
)
mae = mean_absolute_error(
y_test,
predictions
)
mse = mean_squared_error(
y_test,
predictions
)
rmse = np.sqrt(mse)
r2 = r2_score(
y_test,
predictions
)
print("MAE:", mae)
print("MSE:", mse)
print("RMSE:", rmse)
print("R²:", r2)

7.24.44 Choosing the Right Metric

7.24.45 Business Metrics vs ML Metrics

A model can have excellent ML metrics but poor business results.

Example:

The model might still be economically unattractive.

Therefore:

ML Metrics

+

Business Metrics

↓
Production Decision

7.24.46 Calibration

A classification model may produce probabilities.

For example:

Customer A → 0.80
Customer B → 0.60
Customer C → 0.20

A model is well calibrated if predictions around 0.80 correspond to approximately 80% positive outcomes over many comparable cases.

Calibration is different from discrimination.

A model can rank positives above negatives well but still produce poorly calibrated probabilities.

7.24.47 Model Evaluation and Overfitting

Suppose:

Training Accuracy → 99%
Validation Accuracy → 90%
Test Accuracy → 89%
Training Accuracy → 92%
Validation Accuracy → 91%
Test Accuracy → 90%

may generalize better despite having lower training accuracy.

Therefore:

The goal is generalization, not memorization.

7.24.48 Evaluation Workflow

A complete model evaluation process:

1. Define Business Objective
2. Select Appropriate Metric
3. Split Data Correctly
4. Train Model
5. Cross Validation
6. Hyperparameter Tuning
7. Validation Evaluation
8. Finalize Model
9. Evaluate Once on Test Data
10. Business Validation
11. Deployment

12. Monitor Performance

7.24.49 Model Evaluation Checklist

Before deploying a model, check:

Data

Model

Metrics

Business

7.24.50 Interview Questions

Q1. What is model evaluation?

It is the process of measuring how well a machine learning model performs, especially on unseen data.

Q2. Why shouldn't we evaluate only on training data?

Because training performance can be artificially high due to overfitting.

Q3. What is accuracy?

\[\frac{TP+TN}{TP+TN+FP+FN}\]

It measures the proportion of correct predictions.

Q4. What is precision?

\[\frac{TP}{TP+FP}\]

It measures how many predicted positives are actually positive.

Q5. What is recall?

\[\frac{TP}{TP+FN}\]

It measures how many actual positives are correctly detected.

Q6. What is F1 score?

The harmonic mean of precision and recall.

Q7. When is accuracy misleading?

When the dataset is highly imbalanced or when different error types have very different costs.

Q8. What is ROC-AUC?

A threshold-independent measure of how well a model ranks positive examples above negative examples.

Q9. What is MAE?

Mean Absolute Error:

\[MAE=\frac{1}{n}\sum|y-\hat y|\]

Q10. What is RMSE?

The square root of Mean Squared Error:

\[RMSE=\sqrt{MSE}\]

Q11. What is (R^2)?

A regression metric comparing the model's squared prediction error with a mean-prediction baseline.

Q12. What is a confusion matrix?

A table containing TP, TN, FP, and FN counts.

Q13. What is data leakage?

When information that should not be available during training influences the model, causing overly optimistic evaluation.

Q14. What is cross-validation?

A method of repeatedly splitting training data into training and validation portions to estimate model performance more reliably.

Q15. Should the test set be used for hyperparameter tuning?

Ideally, no. The test set should be reserved for final evaluation after model selection.

7.24.51 Key Takeaways

Accuracy is useful for many balanced classification problems but can be misleading for imbalanced datasets.

A strong ML model should demonstrate good generalization, stability, and business usefulness, not merely high training accuracy.

Module 7 · Lesson 7.25

ROC-AUC

7.25.1 Introduction

ROC-AUC is one of the most commonly used evaluation metrics for binary classification models.

It helps answer:

7.25.2 ROC and AUC

ROC-AUC consists of two concepts:

ROC

Receiver Operating Characteristic curve.

It plots:

\[TPR\]

against:

\[FPR\]

It summarizes the ROC curve into a single number.

ROC Curve

↓
Calculate Area
↓
AUC

7.25.3 Basic Idea

Suppose a model predicts fraud probabilities:

Transaction A → 0.95
Transaction B → 0.82
Transaction C → 0.61
Transaction D → 0.32
Transaction E → 0.10

We can choose different thresholds:

The ROC curve plots all these operating points.

7.25.4 Binary Classification

Suppose we predict:

Positive → Fraud
Negative → Normal

We need to convert probabilities into classes using a threshold.

For example:

\[Threshold=0.5\]

Then:

Probability ≥ 0.5 → Fraud
Probability < 0.5 → Normal

But ROC evaluates model performance over many possible thresholds, not just 0.5.

7.25.5 True Positive Rate

The True Positive Rate (TPR) is also called:

\[\boxed{ TPR = \frac{TP}{TP+FN} }\]

It answers:

Of all actual positive cases, how many did the model correctly identify?

Example:

\[TPR=90%\]

7.25.6 False Positive Rate

The False Positive Rate (FPR) is:

\[\boxed{ FPR = \frac{FP}{FP+TN} }\]

It answers:

Of all actual negative cases, how many did the model incorrectly classify as positive?

Example:

Therefore:

\[FPR=5%\]

7.25.7 ROC Curve

The ROC curve plots:

\[FPR\]

on the X-axis and:

\[TPR\]

on the Y-axis.

TPR

1.0 │ ●●●●
│ ●●
│ ●
│ ●
│ ●
│ ●
0.0 │●────────────────────────
0.0 1.0
FPR

A good model generally has a curve closer to the top-left corner.

7.25.8 Random Classifier

A random classifier has:

\[AUC \approx 0.5\]

Its ROC curve approximately follows the diagonal:

TPR

1.0 │ /
│ /
│ /
│ /
│ /
│ /
0.0 │ /────────────────────
0.0 1.0
FPR

Therefore:

AUC = 0.5

↓
Random Ranking

7.25.9 Perfect Classifier

A perfect classifier has:

\[AUC=1.0\]

Conceptually:

TPR

1.0 │───────────────●
│ │
│ │
│ │
0.0 ●───────────────┴────────
0.0 1.0
FPR

7.25.10 AUC Interpretation

A simplified interpretation is:

AUC Interpretation
0.50 Approximately random
0.50–0.60 Very weak
0.60–0.70 Poor
0.70–0.80 Fair
0.80–0.90 Good
0.90–1.00 Excellent
1.00 Perfect

These ranges are rules of thumb, not universal standards.

What counts as a good AUC depends on the application and consequences of errors.

7.25.11 AUC as Ranking Ability

One of the most useful interpretations is:

+

\[\boxed{ AUC = P(score_{positive}>score_{negative}) }\]

with appropriate handling of ties.

7.25.12 Example

Every positive score is greater than every negative score.

Therefore:

\[AUC=1.0\]

The model perfectly ranks the positive observations above the negative observations.

7.25.13 Another Example

Some positive examples receive higher scores than negatives, while others do not.

Therefore:

AUC < 1

The exact value depends on all positive-negative pairs.

7.25.14 Threshold and ROC

Consider a fraud model.
Threshold = 0.9

Very strict

Few transactions classified as fraud

TPR → Lower
FPR → Lower
Threshold = 0.5
Moderate
TPR → Higher
FPR → Higher
Threshold = 0.1
Very sensitive
TPR → Very High
FPR → High

The ROC curve shows these tradeoffs.

7.25.15 ROC-AUC Is Threshold Independent

↓
Accuracy = 90%

ROC-AUC evaluates performance across many thresholds.

Therefore:

Accuracy

↓
One threshold
ROC-AUC
↓
Many thresholds

This is one reason ROC-AUC is useful for comparing models before selecting a final operating threshold.

7.25.16 ROC-AUC Example

Suppose we compare:

Model ROC-AUC
Logistic Regression 0.82
Random Forest 0.88
XGBoost 0.93
CatBoost 0.91
However, this does not automatically mean XGBoost is the best production model.

7.25.17 ROC-AUC with Scikit-learn

Example:

from sklearn.metrics import roc_auc_score
y_prob = model.predict_proba(
    X_test
)[:, 1]
auc = roc_auc_score(
    y_test,
    y_prob
)
print(
    "ROC-AUC:",
    auc
)

Example output:

ROC-AUC: 0.91

7.25.18 Plotting ROC Curve

Scikit-learn provides a convenient function:

from sklearn.metrics import (
RocCurveDisplay
)
import matplotlib.pyplot as plt
RocCurveDisplay.from_predictions(
y_test,
y_prob
)
plt.show()

This displays:

TPR

↑
│ ROC Curve
│ /
│ /
│ /
│ /
└────────────→ FPR

7.25.19 ROC-AUC for Multiple Models

We can compare models visually.

from sklearn.metrics import (
RocCurveDisplay
)
import matplotlib.pyplot as plt
RocCurveDisplay.from_predictions(
y_test,
model1.predict_proba(X_test)[:, 1],
name="Logistic Regression"
)
RocCurveDisplay.from_predictions(
y_test,
model2.predict_proba(X_test)[:, 1],
name="Random Forest"
)
RocCurveDisplay.from_predictions(
y_test,
model3.predict_proba(X_test)[:, 1],
name="XGBoost"
)
plt.show()

The curves can be compared to understand which model provides better ranking across thresholds.

7.25.20 ROC-AUC and Class Imbalance

ROC-AUC is often useful for imbalanced classification, but there is an important caveat.

Suppose:

Normal → 99.9%
Fraud → 0.1%

The False Positive Rate is calculated using:

\[FP/(FP+TN)\]

Since there are enormous numbers of negative examples, the FPR can appear small even when the number of false positives is operationally large.

Therefore:

For highly imbalanced problems, Precision-Recall analysis and Average Precision/PR-AUC should also be examined.

7.25.21 ROC-AUC vs PR-AUC

ROC-AUC PR-AUC / Average Precision
Uses TPR and FPR Uses precision and recall
FPR considers all negatives Precision directly reflects false positives among predicted positives
Useful for general discrimination Often more informative for rare positive classes
Threshold-independent ranking summary Threshold-independent curve-based summary

For highly imbalanced fraud detection:

ROC-AUC

+

PR-AUC

+

Precision

+

Recall

provides a more complete evaluation.

7.25.22 Example — Fraud Detection

But at the selected threshold, it might produce:

\[Recall= \frac{4500}{5000} =90%\]

But precision is:

\[Precision= \frac{4500}{4500+20000} \approx18.4%\]

So despite excellent ROC-AUC, the operational precision may be poor.

This demonstrates why:

ROC-AUC should not be used as the only evaluation metric.

7.25.23 ROC-AUC and Threshold Selection

7.25.24 Youden's J Statistic

One traditional threshold-selection method uses:

\[\boxed{ J=TPR-FPR }\]

The threshold that maximizes (J) provides a balance between sensitivity and specificity.

Since:

\[Specificity=1-FPR\]

we can also write:

\[J=Sensitivity+Specificity-1\]

However, this assumes a particular cost structure and is not necessarily optimal for every business problem.

7.25.25 Specificity

Specificity measures how well the model identifies negative cases.

\[\boxed{ Specificity= \frac{TN}{TN+FP} }\]

\[\boxed{ FPR=1-Specificity }\]

7.25.26 ROC Curve and Specificity

The ROC curve can also be described as:

Y-axis → Sensitivity / TPR
X-axis → 1 - Specificity / FPR

7.25.27 ROC-AUC in Medical Screening

Suppose we predict whether a patient has a disease.

A high recall may be important because missing a disease case can be costly.

The ROC curve allows us to examine:

The final threshold should be chosen based on clinical and operational requirements rather than AUC alone.

7.25.28 ROC-AUC in Customer Churn

Suppose:

Positive → Customer will churn
Negative → Customer will stay

Model scores:

Customer A → 0.91
Customer B → 0.80
Customer C → 0.74
Customer D → 0.21
Customer E → 0.08

A high ROC-AUC indicates that churners tend to receive higher scores than non-churners.

The company can then select a threshold based on:

Retention Budget

+

Expected Customer Value

+

Intervention Cost

7.25.29 ROC-AUC and Calibration

ROC-AUC measures discrimination/ranking, not whether predicted probabilities are numerically accurate.

0.80 probability → approximately 80% actually positive

Model B:

0.80 probability → only 45% actually positive

Model B is poorly calibrated despite having the same AUC.

Therefore:

Discrimination → ROC-AUC
Calibration → Calibration metrics/plots

Both can matter.

7.25.30 ROC-AUC Limitations

ROC-AUC has several limitations.

1. Doesn't Choose the Threshold

It summarizes all thresholds but doesn't tell you the final operating threshold.

2. Doesn't Reflect Business Costs

A false positive and false negative may have very different costs.

3. Can Be Misleading for Extreme Imbalance

PR-AUC/average precision may provide more useful information.

4. Doesn't Measure Calibration

A high AUC doesn't guarantee accurate probabilities.

5. Doesn't Guarantee Production Performance

A model can have high test AUC but degrade after deployment because the data distribution changes.

7.25.31 ROC-AUC and Cross Validation

We can calculate ROC-AUC across multiple folds.

Fold 1 → 0.90
Fold 2 → 0.93
Fold 3 → 0.91
Fold 4 → 0.89
Fold 5 → 0.92

Mean:

\[\frac{0.90+0.93+0.91+0.89+0.92}{5} =0.91\]

We can report:

Mean ROC-AUC = 0.91

and ideally also its variability, such as standard deviation or confidence interval.

7.25.32 Cross-Validated ROC-AUC in Python

from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=200,
random_state=42
)
scores = cross_val_score(
model,
X,
y,
cv=5,
scoring="roc_auc"
)
print("Scores:", scores)
print("Mean AUC:", scores.mean())
print("Std:", scores.std())

Example:

Scores:

\[0.89 0.92 0.91 0.90 0.93\]

Mean AUC: 0.91

Std: 0.014

7.25.33 ROC-AUC for Multi-Class Problems

Example:

from sklearn.metrics import roc_auc_score
auc = roc_auc_score(
y_test,
y_probability,
multi_class="ovr"
)

7.25.34 Macro vs Weighted AUC

For multi-class classification, aggregation methods matter.

Macro

Calculates the metric for each class and gives each class equal importance.

Weighted

Weights each class according to its support.

For imbalanced multi-class problems, macro and weighted AUC can tell different stories.

7.25.35 ROC-AUC Example with XGBoost

from xgboost import XGBClassifier
from sklearn.metrics import roc_auc_score
model = XGBClassifier(
    n_estimators=300,
    learning_rate=0.05,
    max_depth=5,
    random_state=42,
    eval_metric="logloss"
)
model.fit(
    X_train,
    y_train
)
y_prob = model.predict_proba(
    X_test
)[:, 1]
auc = roc_auc_score(
    y_test,
    y_prob
)
print(
    "ROC-AUC:",
    auc
)

7.25.36 ROC-AUC Example with LightGBM

from lightgbm import LGBMClassifier
from sklearn.metrics import roc_auc_score
model = LGBMClassifier(
    n_estimators=300,
    learning_rate=0.05,
    num_leaves=31,
    random_state=42
)
model.fit(
    X_train,
    y_train
)
y_prob = model.predict_proba(
    X_test
)[:, 1]
auc = roc_auc_score(
    y_test,
    y_prob
)
print(
    "ROC-AUC:",
    auc
)

7.25.37 ROC-AUC Example with CatBoost

from catboost import CatBoostClassifier
from sklearn.metrics import roc_auc_score
model = CatBoostClassifier(
    iterations=500,
    depth=6,
    learning_rate=0.05,
    verbose=False,
    random_seed=42
)
model.fit(
    X_train,
    y_train
)
y_prob = model.predict_proba(
    X_test
)[:, 1]
auc = roc_auc_score(
    y_test,
    y_prob
)
print(
    "ROC-AUC:",
    auc
)

7.25.38 Comparing Models

Suppose:

Model ROC-AUC PR-AUC
Logistic Regression 0.84 0.42
Random Forest 0.89 0.51
XGBoost 0.93 0.65
LightGBM 0.94 0.67
CatBoost 0.95 0.70

CatBoost appears strongest on both ranking metrics.

But the final decision should also consider:

7.25.39 Practical Evaluation Strategy

For a binary classification problem, a strong evaluation approach is:

Model

↓
Cross Validation
↓
┌─────────┴─────────┐
↓ ↓
ROC-AUC PR-AUC
↓ ↓
Ranking Rare-class
Quality Performance
└─────────┬─────────┘
↓
Choose Threshold
↓
Precision / Recall / F1
↓
Business Metrics
↓
Deployment

7.25.40 Interview Questions

Q1. What is ROC-AUC?

ROC-AUC is the area under the Receiver Operating Characteristic curve and measures how well a binary classifier separates/ranks positive and negative examples across thresholds.

Q2. What is the ROC curve?

A plot of:

\[TPR\]

against:

\[FPR\]

across different classification thresholds.

Q3. What is TPR?

\[TPR=\frac{TP}{TP+FN}\]

It is also called recall or sensitivity.

Q4. What is FPR?

\[FPR=\frac{FP}{FP+TN}\]

It is one minus specificity.

Q5. What does AUC = 0.5 mean?

The model has approximately random ranking ability.

Q6. What does AUC = 1.0 mean?

The model can perfectly rank positives above negatives, assuming the evaluation data supports that conclusion.

Q7. Is ROC-AUC threshold dependent?

No. ROC-AUC summarizes performance across classification thresholds.

Q8. Does ROC-AUC choose the classification threshold?

No. The threshold must be selected separately.

Q9. What is the relationship between ROC-AUC and ranking?

AUC can be interpreted as the probability that a randomly selected positive receives a higher score than a randomly selected negative, with ties handled appropriately.

Q10. Is ROC-AUC always the best metric for imbalanced data?

No. For highly imbalanced problems, Precision-Recall curves and Average Precision/PR-AUC may provide more informative insight.

Q11. Can ROC-AUC be used for multi-class classification?

Yes, using strategies such as One-vs-Rest or One-vs-One.

Q12. Does high ROC-AUC mean probabilities are well calibrated?

No. ROC-AUC measures discrimination/ranking, not calibration.

7.25.41 Key Takeaways

AUC can be interpreted as the probability that a randomly chosen positive receives a higher score than a randomly chosen negative.

Always consider precision, recall, F1, confusion matrix, calibration, and business costs alongside ROC-AUC.

A practical evaluation is:

ROC-AUC

+

PR-AUC

+

Precision / Recall

+

F1

+

Confusion Matrix

+

Calibration

+

Business Cost

Together, these provide a much more complete picture of classification model performance.

Module 7 · Lesson 7.26

Precision & Recall

7.26.1 Introduction

Precision and Recall are two of the most important evaluation metrics for classification models.

7.26.2 Confusion Matrix Foundation

Precision and Recall are calculated from the confusion matrix.

For binary classification:

Predicted Positive Predicted Negative
Actual Positive TP FN
Actual Negative FP TN

7.26.3 True Positive

A True Positive occurs when:

Actual → Positive
Prediction → Positive

Example:

Actual: Fraud

Prediction: Fraud

The model correctly identified the positive case.

7.26.4 True Negative

A True Negative occurs when:

Actual → Negative
Prediction → Negative

Example:

Actual: Normal

Prediction: Normal

The model correctly identified the negative case.

7.26.5 False Positive

A False Positive occurs when:

Actual → Negative
Prediction → Positive

Example:

False positives are sometimes called Type I errors.

7.26.6 False Negative

A False Negative occurs when:

Actual → Positive
Prediction → Negative

Example:

False negatives are sometimes called Type II errors.

7.26.7 Precision

Precision measures the correctness of positive predictions.

The formula is:

\[\boxed{ Precision = \frac{TP}{TP+FP} }\]

In simple words:

Of everything the model predicted as positive, how much was actually positive?

7.26.8 Precision Example

Suppose a fraud model predicts:

100 transactions → Fraud

Among them:

80 → Actually Fraud
20 → Actually Normal

Therefore:

\[Precision = \frac{80}{80+20}\]

\[Precision=0.80\]

Therefore:

\[\boxed{Precision=80%}\]

7.26.9 High Precision

High precision means:

Predicted Positive

↓
Usually Actually Positive

There are relatively few false positives.

Example:

Precision = 95%

This means that approximately 95% of positive predictions were actually positive, under the evaluated conditions.

7.26.10 Recall

Recall measures how many actual positive cases the model successfully detects.

The formula is:

\[\boxed{ Recall = \frac{TP}{TP+FN} }\]

7.26.11 Recall Example

Therefore:

\[Recall = \frac{90}{90+10}\]

\[Recall=0.90\]

Therefore:

\[\boxed{Recall=90%}\]

7.26.12 High Recall

High recall means:

Actual Positive Cases

↓
Most Are Detected

There are relatively few false negatives.

Example:

Recall = 95%

means the model detected approximately 95% of actual positive cases.

7.26.13 Precision vs Recall

The key difference:

Precision Recall
Focuses on predicted positives Focuses on actual positives
Sensitive to FP Sensitive to FN
"Can I trust positive predictions?" "Did I find most positives?"
Formula: TP/(TP+FP) Formula: TP/(TP+FN)

Remember:

Precision → Predicted Positive
Recall → Actual Positive

7.26.14 Easy Way to Remember

7.26.15 Example — Spam Detection

Suppose an email system predicts:

100 emails → Spam

Actual result:

80 → Spam
20 → Not Spam

Precision:

\[\frac{80}{80+20}=80%\]

Now suppose there are actually:

\[\frac{80}{80+20}=80%\]

7.26.16 Why Precision Matters in Spam Detection

↓
Incorrectly marked as spam

That creates many false positives.

For an email system, high precision may be important because users don't want legitimate messages incorrectly classified as spam.

7.26.17 Why Recall Matters in Fraud Detection

\[Recall=50%\]

It missed half the fraud cases.

If missing fraud is expensive, we may want higher recall.

7.26.18 Precision-Recall Tradeoff

Usually, there is a tradeoff between precision and recall.

Suppose a fraud model produces probabilities:

Transaction A → 0.95
Transaction B → 0.87
Transaction C → 0.72
Transaction D → 0.51
Transaction E → 0.30
Threshold = 0.80
A → Fraud
B → Fraud
C → Normal
D → Normal
E → Normal

7.26.19 Threshold Example

Conceptually:

Threshold

↓
Higher
↓
Fewer Positive Predictions
↓
Usually ↑ Precision
Usually ↓ Recall

Conversely:

Threshold

↓
Lower
↓
More Positive Predictions
↓
Usually ↓ Precision
Usually ↑ Recall

This is a general tendency, not an absolute mathematical guarantee for every finite dataset.

7.26.20 Precision-Recall Curve

A Precision-Recall curve shows the relationship between precision and recall across different thresholds.

Precision

↑
1.0│●
│ \
│ \
│ ●
│ \
│ ●
0.0└──────────────→ Recall
0.0 1.0

Each point corresponds to a different classification threshold.

7.26.21 Precision-Recall Tradeoff

Suppose:

Threshold Precision Recall
0.90 0.98 0.45
0.80 0.94 0.60
0.70 0.89 0.72
0.50 0.80 0.85
0.30 0.65 0.94

As the threshold decreases:

Recall ↑
Precision ↓

This gives us options for selecting a threshold based on business requirements.

7.26.22 Precision-Recall Tradeoff in Real Life

Therefore:

False Negative Cost

↓
Very High
↓
Prioritize Recall

The model may accept more false positives to detect more actual cases.

7.26.23 High Precision Use Cases

↓
Important email marked spam
Fraud Investigation
False Positive
↓
Legitimate customer investigated
Automatic Account Blocking
False Positive
↓
Legitimate user blocked

In these cases, precision may be prioritized.

7.26.24 High Recall Use Cases

↓
Disease not detected
Fraud Detection
False Negative
↓
Fraud goes undetected
Security Intrusion Detection
False Negative
↓
Attack not detected

Here, recall may be prioritized.

7.26.25 Precision = Purity of Positive Predictions

Another way to understand precision:

All Predicted Positives

↓
┌─────────────┐
│ TP │
│ │
│ FP │
└─────────────┘

Precision tells us how "pure" the predicted-positive group is.

\[Precision = \frac{TP}{Predicted\ Positives}\]

7.26.26 Recall = Coverage of Actual Positives

Recall looks at all actual positive cases:

All Actual Positives

↓
┌─────────────┐
│ TP │
│ │
│ FN │
└─────────────┘

Recall tells us how much of the positive population we captured.

\[Recall = \frac{TP}{Actual\ Positives}\]

7.26.27 Precision and Recall Example

\[Precision= \frac{80}{80+40}\]

\[=\frac{80}{120}\]

\[=0.667\]

So:

\[\boxed{Precision=66.7%}\]

Recall

\[Recall= \frac{80}{80+20}\]

\[=\frac{80}{100}\]

\[=0.80\]

So:

\[\boxed{Recall=80%}\]

7.26.28 F1 Score

When we want a single metric that balances precision and recall, we can use F1 score.

\[\boxed{ F1 = 2 \frac{Precision \times Recall} {Precision+Recall} }\]

\[F1\approx0.727\]

So:

F1 ≈ 72.7%

F1 is covered in detail in Section 7.27.

7.26.29 Precision, Recall and F1

Classification Model

↓
┌──────────┴──────────┐
↓ ↓
Precision Recall
│ │
└──────────┬──────────┘
↓
F1

Think of them as:

Precision → Avoid false positives
Recall → Avoid false negatives
F1 → Balance both

7.26.30 Precision vs Recall vs Accuracy

These metrics are different.

Metric Main Question
Accuracy How many total predictions are correct?
Precision How many predicted positives are correct?
Recall How many actual positives were found?

Example:

Accuracy

↓
All predictions
Precision
↓
Predicted positives
Recall
↓
Actual positives

7.26.31 Why Accuracy Can Be Misleading

Every transaction → Normal

\[99%\]

Therefore:

\[Recall=0%\]

This is a terrible fraud detector despite 99% accuracy.

7.26.32 Precision and Recall for Imbalanced Data

For imbalanced classification:

Accuracy

↓
Can be misleading

This gives a much more complete picture.

7.26.33 Precision-Recall Curve vs ROC Curve

Precision-Recall ROC
Precision vs Recall TPR vs FPR
Focuses on positive predictions Considers positive and negative rates
Useful for rare positive classes General discrimination measure
Often more informative for severe imbalance Can look optimistic under extreme imbalance

For rare-event detection:

PR Curve

+

ROC Curve

is often better than relying on ROC alone.

7.26.34 Average Precision

The Average Precision (AP) score summarizes the precision-recall relationship over thresholds.

In scikit-learn:

from sklearn.metrics import average_precision_score
y_prob = model.predict_proba(
    X_test
)[:, 1]
ap = average_precision_score(
    y_test,
    y_prob
)
print(
    "Average Precision:",
    ap
)

AP is particularly useful for imbalanced classification.

7.26.35 Precision in Python

from sklearn.metrics import precision_score
precision = precision_score(
    y_test,
    y_pred
)
print(
    "Precision:",
    precision
)

7.26.36 Recall in Python

from sklearn.metrics import recall_score
recall = recall_score(
    y_test,
    y_pred
)
print(
    "Recall:",
    recall
)

7.26.37 Precision and Recall Together

from sklearn.metrics import (
    precision_score,
    recall_score
)
precision = precision_score(
    y_test,
    y_pred
)
recall = recall_score(
    y_test,
    y_pred
)
print(
    "Precision:",
    precision
)
print(
    "Recall:",
    recall
)

7.26.38 Precision-Recall Curve in Python

from sklearn.metrics import (
    PrecisionRecallDisplay
)
import matplotlib.pyplot as plt
PrecisionRecallDisplay.from_predictions(
    y_test,
    y_prob
)
plt.show()

The curve helps determine whether a particular threshold provides a suitable precision-recall tradeoff.

7.26.39 Choosing a Threshold

+

Cost of False Negative

+

Business Capacity

+

Customer Impact

7.26.40 Cost-Based Threshold Selection

A false negative is much more expensive.

Therefore, we may prefer:

7.26.41 Precision and Recall in Machine Learning Models

Precision and recall can be used with:

They are evaluation metrics, not specific machine-learning algorithms.

7.26.42 Precision and Recall for Multi-Class Classification

For multiple classes, precision and recall can be calculated per class.

Example:

You can calculate:

Then aggregate them using:

7.26.43 Macro Average

Macro averaging calculates the metric independently for each class and then takes the simple average.

Example:

\[\frac{0.90+0.80+0.70}{3} =0.80\]

Every class receives equal importance.

7.26.44 Weighted Average

Weighted averaging considers the number of examples in each class.

For example:

Class A → 80%
Class B → 15%
Class C → 5%

The metric for Class A contributes more because it has more observations.

Weighted averaging can therefore hide poor performance on minority classes.

7.26.45 Micro Average

7.26.46 Scikit-learn Classification Report

A convenient way to inspect these metrics:

from sklearn.metrics import classification_report
print(
classification_report(
y_test,
y_pred
)
)

Example:

This is particularly useful when class distributions are uneven.

7.26.47 Practical Example — Medical Screening

Suppose:

Positive → Disease
Negative → Healthy

This means many people predicted positive may actually be healthy.

This may be acceptable during an initial screening stage because:

Screening

↓
High Recall
↓
Follow-up diagnostic test

The correct balance depends on the clinical workflow.

7.26.48 Practical Example — Spam Detection

The model is highly accurate when it says an email is spam, but it misses 30% of actual spam.

This could be acceptable if avoiding false positives is more important.

7.26.49 Practical Example — Fraud Detection

The model catches most fraud but also generates some false alerts.

If fraud losses are extremely expensive, this may be preferable to:

Precision = 95%

Recall = 60%

The correct choice depends on the organization's fraud-review capacity and costs.

7.26.50 Common Mistakes

7.26.51 Interview Questions

Q1. What is precision?

\[Precision=\frac{TP}{TP+FP}\]

It measures how many predicted positive cases are actually positive.

Q2. What is recall?

\[Recall=\frac{TP}{TP+FN}\]

It measures how many actual positive cases the model detects.

Q3. What is another name for recall?

Sensitivity or True Positive Rate (TPR).

Q4. What does high precision mean?

The model generates relatively few false positives among its positive predictions.

Q5. What does high recall mean?

The model misses relatively few actual positive cases.

Q6. When should you prioritize precision?

When false positives are particularly costly.

Q7. When should you prioritize recall?

When false negatives are particularly costly.

Q8. What is the precision-recall tradeoff?

Changing the classification threshold often increases one while decreasing the other.

Q9. Why is accuracy sometimes misleading?

Because a model can achieve high accuracy by simply predicting the majority class in an imbalanced dataset.

Q10. What is F1 score?

The harmonic mean of precision and recall.

Q11. What is the difference between precision and recall?

Precision focuses on predicted positives, while recall focuses on actual positives.

Q12. What is PR-AUC?

It summarizes the model's precision-recall behavior across thresholds and is particularly useful for evaluating rare positive classes.

Q13. Can precision and recall be used for multi-class classification?

Yes. They can be calculated per class and aggregated using macro, weighted, or micro averaging.

7.26.52 Key Takeaways

Precision answers:

"When the model predicts positive, how often is it correct?"

\[\boxed{ Precision=\frac{TP}{TP+FP} }\]

Recall answers:

"Of all actual positives, how many did the model find?"

\[\boxed{ Recall=\frac{TP}{TP+FN} }\]

Precision focuses on FP.

Recall focuses on FN.

High precision → fewer false positives.
High recall → fewer false negatives.

+

Recall

+

F1

+

PR-AUC

+

ROC-AUC

+

Confusion Matrix

+

Business Cost

rather than relying on a single metric.

Module 7 · Lesson 7.27

F1 Score

7.27.1 Introduction

The F1 Score is a classification evaluation metric that combines Precision and Recall into a single value.

The F1 Score is the harmonic mean of precision and recall.

\[\boxed{ F1 = 2\times \frac{Precision\times Recall} {Precision+Recall} }\]

7.27.2 Why F1 Score?

7.27.3 F1 Score Formula

Precision:

\[Precision = \frac{TP}{TP+FP}\]

Recall:

\[Recall = \frac{TP}{TP+FN}\]

F1:

\[\boxed{ F1 = 2\frac{Precision\times Recall} {Precision+Recall} }\]

7.27.4 Why Harmonic Mean?

\[\frac{1.0+0.1}{2}=0.55\]

But F1:

\[F1= 2\frac{1.0\times0.1}{1.0+0.1} \approx0.182\]

So F1 correctly indicates that the model's overall balance is poor.

7.27.5 F1 Score Range

For the standard binary F1 score:

\[\boxed{0\leq F1\leq1}\]

Interpretation:

F1 = 1.0 → Perfect precision and recall
F1 = 0.9 → Very strong balance
F1 = 0.7 → Moderate
F1 = 0.5 → Weak/moderate
F1 = 0.0 → No successful positive prediction

These labels are only rough guidelines; whether an F1 score is "good" depends on the application.

7.27.6 Example

\[Precision= \frac{80}{80+20} =0.80\]

Recall

\[Recall= \frac{80}{80+10} =0.889\]

F1

\[F1= 2\frac{0.80\times0.889} {0.80+0.889}\]

\[F1\approx0.842\]

Therefore:

\[\boxed{F1\approx84.2%}\]

7.27.7 F1 Score and Confusion Matrix

Notice that:

F1 does not directly use TN.

This makes F1 particularly useful when the negative class is very large and accuracy could be misleading.

7.27.8 F1 vs Accuracy

Consider:

1,000 transactions

990 → Normal
10 → Fraud

Suppose a model predicts every transaction as normal.

Accuracy:

\[\frac{990}{1000}=99%\]

Therefore:

\[Recall=0\]

and the positive-class F1 score is:

\[F1=0\]

This demonstrates why F1 can be much more informative than accuracy for imbalanced classification.

7.27.9 F1 vs Precision

\[F1= 2\frac{0.95\times0.20} {0.95+0.20} \approx0.33\]

Despite excellent precision, the F1 score is low because recall is poor.

7.27.10 F1 vs Recall

\[F1= 2\frac{0.40\times0.95} {0.40+0.95} \approx0.563\]

Again, very high recall does not guarantee a high F1 score.

7.27.11 Precision-Recall-F1 Relationship

Think of it as:

F1 Score

/ \

/ \

Precision Recall

↓ ↓
FP FN

Where:

Precision → Controls false positives
Recall → Controls false negatives
F1 → Balances both

7.27.12 When Should We Use F1?

F1 is particularly useful when:

1. Classes Are Imbalanced

2. Both FP and FN Matter

Neither type of error can be ignored.

3. We Need One Summary Metric

Instead of reporting both precision and recall separately, F1 gives a single balanced metric.

7.27.13 When F1 May Not Be Appropriate

Then false negatives are 100 times more expensive.

A simple F1 score treats precision and recall symmetrically and does not know these business costs.

In such a situation, you may want to prioritize:

Recall

or use a cost-sensitive objective.

7.27.14 F1 Does Not Use True Negatives

This is an important interview point.

Therefore:

Accuracy → Uses TP, TN, FP, FN
F1 → Uses TP, FP, FN

7.27.15 F1 and Threshold Selection

Suppose a model outputs probabilities:

Customer A → 0.91
Customer B → 0.72
Customer C → 0.61
Customer D → 0.44
Customer E → 0.20

Different thresholds produce different precision and recall.

Threshold Precision Recall F1
0.80 0.95 0.55 0.70
0.70 0.90 0.68 0.77
0.50 0.82 0.80 0.81
0.30 0.68 0.92 0.78

However, the threshold that maximizes F1 is not necessarily the threshold that maximizes business value.

7.27.16 F1 and Model Comparison

Suppose:

Model Precision Recall F1
Logistic Regression 0.80 0.72 0.76
Random Forest 0.84 0.78 0.81
XGBoost 0.88 0.84 0.86
LightGBM 0.90 0.81 0.85
CatBoost 0.87 0.86 0.86

XGBoost and CatBoost have the highest F1 in this example.

But before selecting a production model, we should also examine:

7.27.17 F1 Score in Python

Using scikit-learn:

from sklearn.metrics import f1_score
f1 = f1_score(
y_test,
y_pred
)
print(
"F1 Score:",
f1
)

Example:

F1 Score: 0.86

7.27.18 Precision, Recall and F1 Together

from sklearn.metrics import (
precision_score,
recall_score,
f1_score
)
precision = precision_score(
y_test,
y_pred
)
recall = recall_score(
y_test,
y_pred
)
f1 = f1_score(
y_test,
y_pred
)
print("Precision:", precision)
print("Recall:", recall)
print("F1:", f1)

7.27.19 Classification Report

Scikit-learn provides all three metrics together:

from sklearn.metrics import classification_report
print(
classification_report(
y_test,
y_pred
)
)

Example:

7.27.20 Binary F1

For binary classification, F1 is usually calculated for the positive class.

Example:

f1_score(
y_test,
y_pred,
pos_label=1
)

If the positive class is represented by a different label, specify the appropriate pos_label.

7.27.21 Multi-Class F1

7.27.22 Macro F1

Macro F1 calculates F1 independently for each class and then takes the average.

Suppose:

Class A → F1 = 0.90
Class B → F1 = 0.70
Class C → F1 = 0.50

Macro F1:

\[\frac{0.90+0.70+0.50}{3} =0.70\]

Every class receives equal importance.

7.27.23 Why Macro F1 Is Useful

Suppose:

Class A → 90%
Class B → 9%
Class C → 1%

A weighted metric may be dominated by Class A.

Macro F1 treats all classes equally:

Class A → Equal importance
Class B → Equal importance
Class C → Equal importance

This is useful when minority-class performance matters.

7.27.24 Weighted F1

Weighted F1 calculates F1 for each class and weights each class by its number of true samples.

Example:

Class A → 90% of data
Class B → 9%
Class C → 1%

Class A contributes much more to weighted F1.

This can better reflect overall instance-level performance, but it may hide poor minority-class performance.

7.27.25 Micro F1

↓
Combine TP/FP/FN
↓
Calculate F1

For standard single-label multi-class classification, micro F1 is closely related to overall accuracy.

7.27.26 Macro vs Weighted vs Micro

Average Main Idea Useful When
Macro F1 Equal weight to every class Minority classes matter equally
Weighted F1 Weight by class size Want performance reflecting class distribution
Micro F1 Aggregate all decisions Overall instance-level performance matters

7.27.27 Python — Macro F1

from sklearn.metrics import f1_score
macro_f1 = f1_score(
y_test,
y_pred,
average="macro"
)
print(
"Macro F1:",
macro_f1
)

7.27.28 Python — Weighted F1

weighted_f1 = f1_score(
y_test,
y_pred,
average="weighted"
)
print(
"Weighted F1:",
weighted_f1
)

7.27.29 Python — Micro F1

micro_f1 = f1_score(
y_test,
y_pred,
average="micro"
)
print(
"Micro F1:",
micro_f1
)

7.27.30 F1 with Cross Validation

F1 can be used during cross-validation.

from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=200,
random_state=42
)
scores = cross_val_score(
model,
X,
y,
cv=5,
scoring="f1"
)
print("F1 Scores:", scores)
print("Mean F1:", scores.mean())

Example:

F1 Scores:

\[0.82 0.85 0.84 0.81 0.86\]

Mean F1 = 0.836

This gives a more robust estimate than relying on a single split.

7.27.31 F1 with XGBoost

from xgboost import XGBClassifier
from sklearn.metrics import f1_score
model = XGBClassifier(
n_estimators=300,
learning_rate=0.05,
max_depth=5,
random_state=42,
eval_metric="logloss"
)
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)
f1 = f1_score(
y_test,
y_pred
)
print(
"XGBoost F1:",
f1
)

7.27.32 F1 with LightGBM

from lightgbm import LGBMClassifier
from sklearn.metrics import f1_score
model = LGBMClassifier(
n_estimators=300,
learning_rate=0.05,
num_leaves=31,
random_state=42
)
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)
f1 = f1_score(
y_test,
y_pred
)
print(
"LightGBM F1:",
f1
)

7.27.33 F1 with CatBoost

from catboost import CatBoostClassifier
from sklearn.metrics import f1_score
model = CatBoostClassifier(
iterations=500,
depth=6,
learning_rate=0.05,
random_seed=42,
verbose=False
)
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)
f1 = f1_score(
y_test,
y_pred
)
print(
"CatBoost F1:",
f1
)

7.27.34 F1 vs ROC-AUC

These metrics answer different questions.

F1 ROC-AUC
Requires predicted classes/threshold Uses prediction scores across thresholds
Balances precision and recall Measures ranking/discrimination
Threshold-dependent Threshold-independent
Useful for selecting an operating point Useful for comparing ranking ability
Does not directly use TN Uses TPR and FPR

A good evaluation might report both:

ROC-AUC → 0.93
F1 → 0.86

7.27.35 F1 vs PR-AUC

F1 PR-AUC / Average Precision
Evaluates one selected threshold Summarizes behavior across thresholds
Single value Curve-based summary
Balances precision and recall Measures precision-recall performance over thresholds
Useful for operating-point evaluation Useful for model comparison

7.27.36 F1 and Imbalanced Classification

F1 is often useful for imbalanced datasets, but it does not solve every imbalance problem.

Suppose:

Normal → 99.9%
Fraud → 0.1%

7.27.37 F1 and Business Requirements

F1 gives equal conceptual importance to precision and recall.

But your business may strongly prefer recall.

Therefore:

The F1-maximizing threshold is not automatically the business-optimal threshold.

A cost-sensitive evaluation may be more appropriate.

7.27.38 F-Beta Score

If we want to give different importance to precision and recall, we can use the F-beta score.

\[\boxed{ F_\beta = (1+\beta^2) \frac{Precision\times Recall} {\beta^2Precision+Recall} }\]

When:

\[\beta=1\]

we get:

\[F_1\]

7.27.39 F2 Score

When recall is more important:

\[\beta=2\]

Then:

\[F_2\]

↓
Precision = Recall importance
F2
↓
Recall is more important
F0.5
↓
Precision is more important

7.27.40 Python F2 Score

from sklearn.metrics import fbeta_score
f2 = fbeta_score(
y_test,
y_pred,
beta=2
)
print(
"F2 Score:",
f2
)

7.27.41 Choosing Between F1 and F-Beta

Use F1 when:

Precision and Recall

↓
Approximately equal importance

Use F2 when:

Recall

↓
More important

Use F0.5 when:

Precision

↓
More important

7.27.42 Example — Fraud Detection

\[F1= 2\frac{0.85\times0.95} {0.85+0.95} \approx0.897\]

So:

\[\boxed{F1\approx89.7%}\]

If recall is more important, F2 may be a better evaluation metric.

7.27.43 Example — Spam Filtering

Suppose false positives are extremely problematic:

Important email → Incorrectly classified as spam

We may want to prioritize precision.

An F0.5 score can give more weight to precision than recall.

7.27.44 F1 Evaluation Workflow

A practical classification workflow:

Training Data

↓
Train Model
↓
Validation Data
↓
Generate Probabilities
↓
Select Threshold
↓
Predicted Classes
↓
Precision
↓
Recall
↓
F1
↓
Final Test Evaluation

7.27.45 Common Mistakes

For multi-class problems, specify whether you're using:

F1 depends on the selected classification threshold.

7.27.46 Interview Questions

Q1. What is F1 Score?

F1 is the harmonic mean of precision and recall.

\[F1= 2\frac{Precision\times Recall} {Precision+Recall}\]

Q2. Why use F1 instead of accuracy?

F1 is often more informative when classes are imbalanced and both false positives and false negatives matter.

Q3. What is the range of F1?

\[0\leq F1\leq1\]

Q4. What does F1 = 1 mean?

Perfect precision and recall.

Q5. What happens if precision is high but recall is low?

F1 will generally be low because the harmonic mean penalizes the imbalance.

Q6. Does F1 use true negatives?

No. Standard F1 uses TP, FP, and FN.

Q7. Is F1 threshold dependent?

Yes. The predicted classes, and therefore precision, recall, and F1, depend on the classification threshold.

Q8. What is macro F1?

The unweighted average of the F1 scores calculated independently for each class.

Q9. What is weighted F1?

The average of per-class F1 scores weighted by the number of true samples in each class.

Q10. What is micro F1?

F1 calculated after aggregating TP, FP, and FN across classes.

Q11. When should you use F2 instead of F1?

When recall is more important than precision.

Q12. What is the relationship between F1 and F-beta?

F1 is the special case of F-beta where:

\[\beta=1\]

7.27.47 Key Takeaways

F1 Score combines Precision and Recall.

Formula:

\[\boxed{ F1 = 2\frac{Precision\times Recall} {Precision+Recall} }\]

Do not select a model using F1 alone; also consider:

One-line interview definition

F1 Score is the harmonic mean of precision and recall, used to evaluate the balance between false positives and false negatives, particularly in imbalanced classification problems.

Module 7 · Lesson 7.28

Confusion Matrix

7.28.1 Introduction

A Confusion Matrix is a table used to evaluate the performance of a classification model.

It compares:

Actual class vs Predicted class

The confusion matrix is the foundation for several important metrics:

It is especially useful because it doesn't just tell us whether predictions were correct; it shows what type of mistakes the model made.

7.28.2 Basic Confusion Matrix

For binary classification:

Predicted Positive Predicted Negative
Actual Positive TP FN
Actual Negative FP TN

Where:

TP → True Positive
TN → True Negative
FP → False Positive
FN → False Negative

7.28.3 Understanding the Four Values

Consider a fraud detection model.
Positive → Fraud
Negative → Normal
True Positive — TP

7.28.4 Visual Representation

PREDICTED

Positive Negative

┌──────────┬──────────┐
Positive │ TP │ FN │
ACTUAL ├──────────┼──────────┤
Negative │ FP │ TN │
└──────────┴──────────┘

7.28.5 Example

Predicted Fraud Predicted Normal
Actual Fraud 80 20
Actual Normal 40 860

Total:

\[80+20+40+860=1000\]

7.28.6 Accuracy from Confusion Matrix

Accuracy measures the percentage of all predictions that are correct.

\[\boxed{ Accuracy= \frac{TP+TN} {TP+TN+FP+FN} }\]

Using the example:

\[Accuracy= \frac{80+860}{1000}\]

\[=0.94\]

Therefore:

\[\boxed{Accuracy=94%}\]

7.28.7 Precision from Confusion Matrix

Precision measures how many predicted positives were actually positive.

\[\boxed{ Precision= \frac{TP}{TP+FP} }\]

Example:

\[Precision= \frac{80}{80+40}\]

\[=0.667\]

Therefore:

\[\boxed{Precision=66.7%}\]

7.28.8 Recall from Confusion Matrix

Recall measures how many actual positives were detected.

\[\boxed{ Recall= \frac{TP}{TP+FN} }\]

Example:

\[Recall= \frac{80}{80+20}\]

\[=0.80\]

Therefore:

\[\boxed{Recall=80%}\]

7.28.9 Specificity

Specificity measures how well the model identifies negative cases.

\[\boxed{ Specificity= \frac{TN}{TN+FP} }\]

Using our example:

\[Specificity= \frac{860}{860+40}\]

\[=0.956\]

Therefore:

\[\boxed{Specificity\approx95.6%}\]

7.28.10 False Positive Rate

The False Positive Rate (FPR) is:

\[\boxed{ FPR= \frac{FP}{FP+TN} }\]

Example:

\[FPR= \frac{40}{40+860}\]

\[=0.0444\]

Therefore:

\[\boxed{FPR\approx4.44%}\]

Notice:

\[\boxed{FPR=1-Specificity}\]

7.28.11 False Negative Rate

The False Negative Rate (FNR) is:

\[\boxed{ FNR= \frac{FN}{FN+TP} }\]

Example:

\[FNR= \frac{20}{20+80}\]

\[=0.20\]

Therefore:

\[\boxed{FNR=20%}\]

And:

\[\boxed{FNR=1-Recall}\]

7.28.12 Complete Metric Summary

Metric Formula Result
Accuracy (TP+TN)/Total 94.0%
Precision TP/(TP+FP) 66.7%
Recall TP/(TP+FN) 80.0%
Specificity TN/(TN+FP) 95.6%
FPR FP/(FP+TN) 4.4%
FNR FN/(FN+TP) 20.0%

This demonstrates why a confusion matrix is so useful: one table gives us the building blocks for many evaluation metrics.

7.28.13 Confusion Matrix and F1 Score

F1 is calculated from precision and recall:

\[F1= 2\frac{Precision\times Recall} {Precision+Recall}\]

\[F1\approx0.727\]

Therefore:

\[\boxed{F1\approx72.7%}\]

7.28.14 Why Is It Called "Confusion" Matrix?

The name comes from the fact that the matrix shows where the classifier is confusing one class with another.

For example:

Actual Fraud

↓
Predicted Normal
↓
False Negative

or:

Actual Normal

↓
Predicted Fraud
↓
False Positive

7.28.15 Confusion Matrix for Medical Diagnosis

Suppose:

Positive → Disease
Negative → Healthy

The matrix becomes:

Predicted Disease Predicted Healthy
Actual Disease TP FN
Actual Healthy FP TN

Interpretation:

TP → Disease correctly detected
TN → Healthy correctly identified
FP → Healthy person incorrectly flagged
FN → Disease missed

For medical screening, FN can be particularly serious, so recall/sensitivity may be prioritized.

7.28.16 Confusion Matrix for Spam Detection

Positive → Spam
Negative → Legitimate
Predicted Spam Predicted Legitimate
Actual Spam TP FN
Actual Legitimate FP TN

Here, a false positive means:

Legitimate Email

↓
Incorrectly classified as Spam

This can be highly undesirable.

Therefore, spam filtering often needs to balance precision and recall carefully.

7.28.17 Confusion Matrix for Customer Churn

Positive → Customer will churn
Negative → Customer will stay
Predicted Churn Predicted Stay
Actual Churn TP FN
Actual Stay FP TN

A false negative means:

Customer will churn

↓
Model predicts Stay
↓
Retention team may not intervene

7.28.18 Confusion Matrix for Fraud Detection

Positive → Fraud
Negative → Normal
Predicted Fraud Predicted Normal
Actual Fraud TP FN
Actual Normal FP TN

Business interpretation:

TP → Fraud caught
FN → Fraud missed
FP → Legitimate customer flagged
TN → Legitimate transaction accepted

This makes the confusion matrix particularly useful for discussing business impact.

7.28.19 Confusion Matrix in Python

Scikit-learn provides:

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(
y_test,
y_pred
)
print(cm)

Example output:

\[[860 40\]

\[20 80]\]

Depending on the class label ordering, this corresponds to:

7.28.20 Plotting a Confusion Matrix

Scikit-learn provides a convenient visualization:

from sklearn.metrics import ConfusionMatrixDisplay
import matplotlib.pyplot as plt
ConfusionMatrixDisplay.from_predictions(
y_test,
y_pred
)
plt.show()
┌────────┬────────┐
Actual 0 │ 860 │ 40 │
├────────┼────────┤
Actual 1 │ 20 │ 80 │
└────────┴────────┘

7.28.21 Normalized Confusion Matrix

Sometimes raw counts are difficult to compare, especially when classes have different sizes.

We can normalize the matrix.

from sklearn.metrics import ConfusionMatrixDisplay
import matplotlib.pyplot as plt
ConfusionMatrixDisplay.from_predictions(
y_test,
y_pred,
normalize="true"
)
plt.show()

With normalize="true", each actual-class row is normalized.

Example:

Actual Class 0:

95% → predicted 0
5% → predicted 1

Actual Class 1:

20% → predicted 0
80% → predicted 1

This makes class-specific recall easier to visualize.

7.28.22 Row vs Column Interpretation

A common source of confusion is matrix orientation.

Usually, scikit-learn uses:

Rows → Actual
Columns → Predicted

So:

cm[i][j]

means:

Actual class i was predicted as class j.

Always verify the class ordering and documentation when working with another library or visualization tool.

7.28.23 Multi-Class Confusion Matrix

Actual / Predicted Cat Dog Horse
Cat 90 7 3
Dog 5 88 7
Horse 2 8 90

= 7

7.28.24 Multi-Class Interpretation

The confusion matrix can reveal patterns that overall accuracy hides.

Suppose:

Cat → frequently confused with Dog
Dog → frequently confused with Horse
Horse → rarely confused

7.28.25 One-vs-Rest Metrics

Dog → Positive
Cat → Negative
Horse → Negative

Then calculate:

7.28.26 Confusion Matrix and Class Imbalance

So recall is:

\[Recall=70%\]

This is much more informative than simply saying:

Accuracy = 99.2%

7.28.27 Cost-Sensitive Confusion Matrix

\[10\times ₹10,000 ₹100,000\]

\[10\times ₹100 ₹1,000\]

Therefore, simply minimizing the total number of errors may not be optimal.

7.28.28 Confusion Matrix and Threshold

The confusion matrix depends on the classification threshold.

Suppose the model predicts:

Customer A → 0.80
Customer B → 0.65
Customer C → 0.45
Customer D → 0.20

Therefore:

Probability

↓
Threshold
↓
Predicted Class
↓
Confusion Matrix
↓
Precision / Recall / F1

7.28.29 Threshold Tradeoff

Increasing the threshold usually results in:

Positive Predictions ↓
Precision → often ↑
Recall → often ↓

Decreasing the threshold usually results in:

Positive Predictions ↑
Precision → often ↓
Recall → often ↑

The exact behavior depends on the data and score distribution.

7.28.30 Confusion Matrix vs ROC-AUC

These provide different information.

Confusion Matrix ROC-AUC
Shows actual prediction counts Measures ranking across thresholds
Threshold-dependent Threshold-independent
Shows TP, TN, FP, FN Uses TPR and FPR
Excellent for error analysis Excellent for overall discrimination
Helps understand business errors Doesn't show exact operating-point counts

A strong evaluation should often use both.

7.28.31 Confusion Matrix vs F1

Confusion Matrix F1
Shows TP, TN, FP, FN Summarizes precision and recall
Detailed Single number
Helps diagnose errors Helps compare models
Threshold-dependent Threshold-dependent

Use the confusion matrix to understand why a model performs the way it does.

Use F1 to summarize the precision-recall balance.

7.28.32 Complete Python Example

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import (
    confusion_matrix,
    accuracy_score,
    precision_score,
    recall_score,
    f1_score,
    classification_report
)
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)
model = RandomForestClassifier(
    n_estimators=200,
    random_state=42
)
model.fit(
    X_train,
    y_train
)
y_pred = model.predict(
    X_test
)
cm = confusion_matrix(
    y_test,
    y_pred
)
print("Confusion Matrix:")
print(cm)
print(
    "Accuracy:",
    accuracy_score(y_test, y_pred)
)
print(
    "Precision:",
    precision_score(y_test, y_pred)
)
print(
    "Recall:",
    recall_score(y_test, y_pred)
)
print(
    "F1:",
    f1_score(y_test, y_pred)
)
print(
    classification_report(
        y_test,
        y_pred
    )
)

7.28.33 Reading the Output

Suppose the output is:

Confusion Matrix:

\[[860 40\]

\[20 80]\]

Therefore:

\[940/1000=94%\]

7.28.34 Complete Evaluation Flow

Dataset

↓
Train/Test Split
↓
Train Model
↓
Make Predictions
↓
┌────────┴────────┐
↓ ↓
Confusion Matrix Scores
↓ ↓
┌──────┼──────┐ Accuracy
↓ ↓ ↓ Precision
TP FP FN Recall
│ │ │ F1
└──────┴──────┘
↓
Error Analysis
↓
Model Improvement

7.28.35 Interview Questions

Q1. What is a confusion matrix?

A confusion matrix is a table comparing actual and predicted classes to show correct and incorrect classification results.

Q2. What are TP, TN, FP and FN?

Q3. What is precision?

\[Precision=\frac{TP}{TP+FP}\]

Q4. What is recall?

\[Recall=\frac{TP}{TP+FN}\]

Q5. What is specificity?

\[Specificity=\frac{TN}{TN+FP}\]

Q6. What is accuracy?

\[Accuracy=\frac{TP+TN}{TP+TN+FP+FN}\]

Q7. Which cells represent errors?

FP

FN

Q8. Which cells represent correct predictions?

TP

TN

Q9. Does F1 use TN?

No. Standard F1 uses TP, FP and FN through precision and recall.

Q10. Can confusion matrices be used for multi-class classification?

Yes. An (N)-class classification problem produces an (N\times N) confusion matrix.

Q11. Why is a confusion matrix useful for imbalanced data?

It shows exactly how many minority-class examples were correctly detected or missed, rather than hiding the problem behind a high overall accuracy.

Q12. Does the confusion matrix depend on the classification threshold?

Yes. Changing the threshold can change TP, TN, FP and FN.

7.28.36 Key Takeaways

The confusion matrix is the foundation of classification evaluation:

Predicted

Positive Negative

┌──────────┬──────────┐
Actual Positive│ TP │ FN │
├──────────┼──────────┤
Actual Negative│ FP │ TN │
└──────────┴──────────┘

Remember:

TP → Correct Positive
TN → Correct Negative
FP → False Alarm
FN → Missed Positive

From these four values we derive:

\[Accuracy=\frac{TP+TN}{TP+TN+FP+FN}\]

\[Precision=\frac{TP}{TP+FP}\]

\[Recall=\frac{TP}{TP+FN}\]

\[Specificity=\frac{TN}{TN+FP}\]

\[F1=2\frac{Precision\times Recall}{Precision+Recall}\]

Most important interview point

A confusion matrix does not merely tell us how many predictions are correct; it shows exactly what types of classification errors the model is making.

For real-world ML evaluation, inspect the confusion matrix together with Precision, Recall, F1, ROC-AUC and PR-AUC rather than relying on accuracy alone.

Module 7 · Lesson 7.29

Model Deployment Basics

7.29.1 Introduction

Model Deployment is the process of making a trained machine learning model available so that it can make predictions on new, real-world data.

↓
Data Preparation
↓
Model Training
↓
Model Evaluation
↓
Model Saving
↓
Model Deployment
↓
Prediction
↓
Monitoring
↓
Retraining

The goal of deployment is to move a model from an experimental environment into a system where applications, users, or automated processes can use it.

7.29.2 Simple Example

Suppose we build a customer churn model.

During development:

Customer Data

↓
Python
↓
Scikit-learn
↓
Random Forest
↓
Churn Model

After deployment:

Customer Application

↓
Customer Data
↓
ML API
↓
Trained Model
↓
Churn Probability
↓
Application

7.29.3 Why Model Deployment Is Important

7.29.4 Model Deployment Lifecycle

A typical lifecycle is:

Development

↓
Train Model
↓
Evaluate Model
↓
Save Model
↓
Package Model
↓
Deploy
↓
Serve Predictions
↓
Monitor
↓
Detect Drift
↓
Retrain Model
↓
Redeploy

This is often called the ML lifecycle or part of MLOps.

7.29.5 Training vs Deployment

There is an important difference.

Training

The model learns from historical data.

X_train + y_train
↓
ML Algorithm
↓
Trained Model
Deployment

The trained model receives new data.

New X

↓
Trained Model
↓
Prediction

Once deployed, the model usually does not learn from every prediction request automatically.

7.29.6 Batch Prediction

In batch deployment, predictions are generated for many records at once.

Example:

10 million customers

↓
Batch Job
↓
ML Model
↓
Churn Predictions
↓
Database / Data Warehouse

7.29.7 Real-Time Prediction

In real-time deployment, an application sends a request and receives a prediction immediately.

Application

↓
HTTP Request
↓
ML API
↓
Model
↓
Prediction
↓
HTTP Response

Example:

POST /predict

{

}

Response:

{

"churn_probability": 0.82,

"prediction": 1

}

7.29.8 Batch vs Real-Time Deployment

Batch Real-Time
Processes many records Processes individual requests
Scheduled On demand
Seconds/minutes/hours acceptable Low latency often required
Easier to operate More infrastructure required
Daily churn prediction Fraud transaction prediction

Choose the architecture based on business requirements.

7.29.9 Model as an API

One common deployment method is to expose the model through a REST API.

Architecture:

┌─────────────┐
│ Application │
└──────┬──────┘
│
HTTP
↓
┌─────────────┐
│ ML API │
└──────┬──────┘
│
↓
┌─────────────┐
│ ML Model │
└──────┬──────┘
│
↓
Prediction

For ML inference APIs, FastAPI is a common lightweight choice.

7.29.10 Saving a Scikit-Learn Model

After training:

from joblib import dump
dump(
model,
"model.joblib"
)

Load it later:

from joblib import load
model = load(
"model.joblib"
)

Now the application can use:

prediction = model.predict(
X_new
)

7.29.11 Why Save the Model?

Without saving the trained model:

Application starts

↓
Train model again
↓
Make prediction

This is inefficient.

Instead:

Training Environment

↓
Train Model
↓
Save Model
↓
model.joblib
↓
Production Server
↓
Load Model
↓
Predict

7.29.12 Saving Preprocessing

A critical deployment concept is:

Save the preprocessing logic together with the model.

Suppose training uses:

Missing-value imputation

↓
StandardScaler
↓
Logistic Regression

If production only receives the Logistic Regression model:

New Data

???

↓
Model
↓
Imputation
↓
Scaling
↓
Model
↓
Prediction

7.29.13 Scikit-Learn Pipeline

Example:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
pipeline = Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression())
])
pipeline.fit(
X_train,
y_train
)

Save the entire pipeline:

from joblib import dump
dump(
pipeline,
"churn_pipeline.joblib"
)

Production can then simply execute:

pipeline.predict(
X_new
)

This helps ensure that training and inference use the same preprocessing.

7.29.14 Model Serialization

Model serialization means converting a trained model into a format that can be stored and loaded later.

Other ML ecosystems may use formats such as:

The appropriate format depends on the framework and deployment environment.

7.29.15 Pickle

Python's pickle can serialize many Python objects.

Example:

import pickle
with open(
    "model.pkl",
    "wb"
) as file:
    pickle.dump(
        model,
        file
    )

Load:

with open(
    "model.pkl",
    "rb"
) as file:
    model = pickle.load(
        file
    )

Security Warning

7.29.16 FastAPI Deployment

A simple FastAPI application could look like:

from fastapi import FastAPI
from joblib import load
app = FastAPI()
model = load(
"model.joblib"
)

@app.post("/predict")

def predict(data: dict):
features = [[
data["age"],
data["income"],
data["tenure"]
]]
prediction = model.predict(
features
)
probability = model.predict_proba(
features
)[:, 1]
return {
"prediction": int(prediction[0]),
"probability": float(probability[0])
}

Conceptually:

POST /predict

↓
Input JSON
↓
Feature Preparation
↓
ML Model
↓
Prediction
↓
JSON Response

7.29.17 API Request and Response

Request:

{

}

Response:

{

"prediction": 1,

"probability": 0.82

}

The application does not need to know how the model works internally.

It only needs to know:

Input → API → Prediction

7.29.18 Docker Deployment

A common approach is to package the model application into a Docker container.

Architecture:

┌───────────────────────────┐
│ Docker Container │
│ │
│ FastAPI │
│ ↓ │
│ ML Pipeline │
│ ↓ │
│ Trained Model │
│ │
└───────────────────────────┘

7.29.19 Basic Dockerfile

"--host",

"0.0.0.0",

"--port",

"8000"

]

The exact production configuration depends on the application and hosting platform.

7.29.20 Cloud Deployment

↓
API Endpoint
↓
Cloud Inference Service
↓
ML Model
↓
Prediction

7.29.21 Model Registry

A model registry stores and manages model versions.

Example:

Model: customer_churn

v1.0 → Accuracy 0.84
v1.1 → Accuracy 0.87
v2.0 → Accuracy 0.90
↓
Validation
↓
Staging
↓
Production

7.29.22 Model Versioning

Example:

v3 deployed

↓
Production issue
↓
Rollback
↓
v2

Model versioning is essential for reliable ML systems.

7.29.23 Staging Environment

Before production:

Development

↓
Testing
↓
Staging
↓
Production

7.29.24 Canary Deployment

A canary deployment sends a small percentage of traffic to the new model.

Example:

Traffic

│
├── 95% → Model V1
│
└── 5% → Model V2

If V2 performs well:

5%

↓
20%
↓
50%
↓
100%

If problems occur:

V2

↓
Rollback
↓
V1

7.29.25 Blue-Green Deployment

Another deployment strategy is blue-green deployment.

Blue → Current Production
Green → New Model

Example:

Users

↓
Traffic Router
├── Blue → Model V1
└── Green → Model V2

After validation:

Traffic

↓
Green

If a problem occurs:

Traffic

↓
Blue

7.29.26 Shadow Deployment

In shadow deployment, the new model receives production inputs but its predictions are not used to make real decisions.

Production Request

↓
┌───┴────┐
↓ ↓
Model V1 Model V2
↓ ↓
Used Logged only

This is useful for testing a new model safely against real traffic.

7.29.27 Model Monitoring

↓
┌─────────┴─────────┐
↓ ↓
Predictions Metrics
↓ ↓
Monitoring Dashboard
↓
Alerts

7.29.28 Data Drift

↓
Model
↓
Production Distribution
↓
Potential Performance Change

7.29.29 Concept Drift

Concept drift occurs when the relationship between input features and target changes.

Example:

Before:

High Support Calls → High Churn

Later:

High Support Calls → Low Churn

The relationship learned by the model has changed.

This can cause model performance to degrade even if input distributions have not changed dramatically.

7.29.30 Model Performance Monitoring

7.29.31 Prediction Monitoring

Low Risk → 60%
Medium Risk → 30%
High Risk → 10%

If suddenly:

High Risk → 65%

something may have changed.

This doesn't prove model failure, but it is an important monitoring signal.

7.29.32 Input Validation

Production systems should validate inputs before sending them to the model.

Invalid data should be rejected or handled appropriately.

7.29.33 Schema Validation

Suppose the model expects:

{

}

But the application sends:

{

"age": "thirty-five",

"income": "unknown"

}

The API should detect the invalid schema rather than allowing the model to fail unpredictably.

Frameworks such as FastAPI can use structured request models for validation.

7.29.34 Logging

Production inference should typically record appropriate operational information such as:

7.29.35 Latency

For real-time systems, prediction speed matters.

Example:

Request

↓
API
↓
Model
↓
Response
Latency = 80 ms

The tail latencies can be particularly important for user-facing systems.

7.29.36 Scalability

A single server may not be enough.

We can scale horizontally:

Load Balancer

↓
┌─────────────┼─────────────┐
↓ ↓ ↓
Model API Model API Model API
↓ ↓ ↓
Model Model Model

Containers and orchestration systems can help implement this architecture.

7.29.37 Security

Never expose a production prediction endpoint without appropriate access controls.

7.29.38 Model Explainability

The required level of explainability depends on the application and regulatory environment.

7.29.39 Model Retraining

A model may need to be retrained periodically.

Example:

Every Month

↓
Collect New Data
↓
Validate Data
↓
Train New Model
↓
Evaluate
↓
Compare with Current Model
↓
Deploy if Better

This creates a continuous ML lifecycle.

7.29.40 MLOps

+

Software Engineering

+

Data Engineering

+

↓
Training
↓
Evaluation
↓
Model Registry
↓
Deployment
↓
Monitoring
↓
Retraining
↓
Deployment

7.29.41 CI/CD for ML

Traditional CI/CD:

Code

↓
Test
↓
Build
↓
Deploy

ML CI/CD may include:

Code

↓
Data Validation
↓
Training
↓
Model Evaluation
↓
Model Validation
↓
Register Model
↓
Deploy

The additional model/data checks are important because ML behavior depends on more than source code.

7.29.42 Model Deployment Architecture

A typical production architecture:

┌───────────────┐
│ Client/App │
└───────┬───────┘
│
↓
┌───────────────┐
│ API Gateway │
└───────┬───────┘
│
↓
┌───────────────┐
│ ML Inference │
│ Service │
└───────┬───────┘
│
↓
┌───────────────┐
│ Model Artifact│
└───────┬───────┘
│
↓
┌───────────────┐
│ Prediction │
└───────────────┘
│
┌───────────┴───────────┐
↓ ↓
Monitoring Logging

7.29.43 End-to-End Deployment Example

Suppose we built a customer churn model.

Step 1 — Train

model.fit(
X_train,
y_train
)

Step 2 — Evaluate

f1_score(
y_test,
model.predict(X_test)
)

Step 3 — Save

from joblib import dump
dump(
model,
"churn_model.joblib"
)
model = load(
"churn_model.joblib"
)

Step 6 — Receive New Customer

{

}

{

"churn_probability": 0.83,

"prediction": 1

}

7.29.44 Production Checklist

7.29.45 Common Deployment Mistakes

You cannot easily determine which model generated a prediction.

7.29.46 Interview Questions

Q1. What is model deployment?

Model deployment is the process of making a trained ML model available to generate predictions on new data in a production or operational environment.

Q2. What is the difference between batch and real-time inference?

Batch: predictions are generated for many records at scheduled intervals.

Real-time: predictions are generated in response to individual requests.

Q3. How do you deploy a Python ML model?

A common approach is:

Train

↓
Save Model
↓
Create API
↓
Containerize
↓
Deploy
↓
Monitor

Q4. Why should preprocessing be saved with the model?

To ensure production data is transformed exactly as it was during training.

Q5. What is model serialization?

Converting a trained model into a storable format so it can later be loaded for inference.

Q6. What is model drift?

A change in data or relationships that causes model performance to degrade over time. More specifically, data drift concerns changes in input distributions, while concept drift concerns changes in the relationship between inputs and targets.

Q7. What is a model registry?

A system for storing, versioning, tracking, and managing ML model artifacts and their metadata.

Q8. What is canary deployment?

Deploying a new model to a small percentage of traffic before gradually increasing its traffic.

Q9. What is shadow deployment?

Running a new model alongside the production model using real inputs while not using the new model's predictions for actual decisions.

Q10. What is MLOps?

MLOps is the set of engineering and operational practices used to reliably develop, deploy, monitor, and maintain machine learning systems.

Q11. Why is Docker useful for ML deployment?

It packages the application, model, and dependencies into a reproducible environment.

Q12. What should you monitor after deployment?

7.29.47 Key Takeaways

Model deployment moves ML from:

Notebook

↓
Experiment
↓
Train
↓
Evaluate
↓
Save
↓
Package
↓
Deploy
↓
Predict
↓
Monitor
↓
Retrain

Model deployment is the process of taking a trained and validated machine learning model and integrating it into a production system so that it can reliably generate predictions on new data.

Module 7 · Lesson 7.30

ML Pipelines

7.30.1 Introduction

An ML Pipeline (Machine Learning Pipeline) is a sequence of connected steps that automates the process of preparing data, training a model, and generating predictions.

Instead of manually performing:

Load Data

↓
Clean Data
↓
Encode Data
↓
Scale Data
↓
Train Model
↓
Predict

we can combine these operations into a single reproducible workflow.

Raw Data

↓
Preprocessing
↓
Feature Engineering
↓
ML Model
↓
Prediction

ML pipelines are important because they make machine learning workflows:

7.30.2 Why Do We Need ML Pipelines?

Suppose we train a classification model.

During training:

Training Data

↓
Missing Value Imputation
↓
One-Hot Encoding
↓
Feature Scaling
↓
Model

But during production, someone might accidentally do:

Production Data

↓
One-Hot Encoding
↓
Model

A pipeline ensures that the same transformations are applied consistently.

7.30.3 Basic ML Pipeline

A simple pipeline looks like:

ML Pipeline

│
┌───────────┴───────────┐
↓ ↓
Data Preprocessing Feature Engineering
│ │
└───────────┬───────────┘
↓
ML Model
↓
Prediction

7.30.4 Typical ML Workflow

A complete machine learning workflow can be:

Raw Data

↓
Data Validation
↓
Data Cleaning
↓
Feature Engineering
↓
Train/Test Split
↓
Preprocessing
↓
Model Training
↓
Model Evaluation
↓
Hyperparameter Tuning
↓
Model Selection
↓
Model Deployment
↓
Monitoring

Not every step needs to be implemented as a single software pipeline object, but the overall workflow can be automated.

7.30.5 Training Pipeline vs Prediction Pipeline

↓
Preprocessing
↓
Feature Engineering
↓
Model Training
↓
Evaluation
↓
Model Artifact
Prediction Pipeline
New Data
↓
Same Preprocessing
↓
Same Feature Engineering
↓
Trained Model
↓
Prediction

The preprocessing logic must remain consistent between the two.

7.30.6 Scikit-Learn Pipeline

Scikit-learn provides:

from sklearn.pipeline import Pipeline

A simple pipeline:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
pipeline = Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression())
])

Train:

pipeline.fit(
X_train,
y_train
)

Predict:

predictions = pipeline.predict(
X_test
)

The pipeline automatically applies:

StandardScaler
↓
LogisticRegression

7.30.7 Pipeline Structure

The pipeline:

Pipeline([
("step1", transformer1),
("step2", transformer2),
("model", estimator)
])

Each step has:

name

+

object

For example:

Pipeline([
("scaler", StandardScaler()),
("classifier", LogisticRegression())
])

7.30.8 Transformer vs Estimator

StandardScaler
MinMaxScaler
SimpleImputer
OneHotEncoder
PCA
Estimator
LogisticRegression
RandomForestClassifier
XGBClassifier
LinearRegression

7.30.9 Example with Missing Values

from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
pipeline = Pipeline([
    (
        "imputer",
        SimpleImputer(strategy="median")
    ),
    (
        "scaler",
        StandardScaler()
    ),
    (
        "model",
        LogisticRegression()
    )
])

Then:

pipeline.fit(
X_train,
y_train
)

7.30.10 Pipeline Execution

Internally, conceptually:

X_train
↓
SimpleImputer
↓
StandardScaler
↓
LogisticRegression
↓
Trained Pipeline

When predicting:

X_new

↓
SimpleImputer
↓
StandardScaler
↓
LogisticRegression
↓
Prediction

You don't need to manually call every transformation.

7.30.11 Why Pipelines Prevent Data Leakage

This is one of the most important reasons to use pipelines.

Suppose we scale the entire dataset before splitting:

Entire Dataset

↓
StandardScaler.fit()
↓
Train/Test Split
↓
Train/Test Split
↓
Training Data
↓
Pipeline.fit()
↓
Scaler learns only from training data

Then:

Test Data

↓
Scaler.transform()
↓
Model.predict()

The test set remains unseen during fitting.

7.30.12 Pipeline with Train/Test Split

from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)
pipeline = Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression())
])
pipeline.fit(
X_train,
y_train
)
y_pred = pipeline.predict(
X_test
)

7.30.13 ColumnTransformer

Real datasets usually contain both numerical and categorical columns.

Example:

Age → Numerical
Income → Numerical
City → Categorical
PaymentMethod → Categorical

We need different preprocessing for different columns.

Scikit-learn provides:

from sklearn.compose import ColumnTransformer

7.30.14 Numerical Pipeline

For numerical columns:

from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
numeric_pipeline = Pipeline([
    (
        "imputer",
        SimpleImputer(strategy="median")
    ),
    (
        "scaler",
        StandardScaler()
    )
])

7.30.15 Categorical Pipeline

For categorical columns:

from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder
categorical_pipeline = Pipeline([
    (
        "imputer",
        SimpleImputer(
            strategy="most_frequent"
        )
    ),
    (
        "encoder",
        OneHotEncoder(
            handle_unknown="ignore"
        )
    )
])

7.30.16 Combining Them with ColumnTransformer

from sklearn.compose import ColumnTransformer
numeric_features = [
    "age",
    "income",
    "tenure"
]

]

preprocessor = ColumnTransformer([

(

),

(

)

])

Now we have:

Numerical Columns

↓
Impute
↓
Scale
Categorical Columns
↓
Impute
↓
One-Hot Encode

7.30.17 Complete ML Pipeline

Now combine preprocessing and model:

from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
model_pipeline = Pipeline([
    (
        "preprocessor",
        preprocessor
    ),
    (
        "model",
        LogisticRegression(
            max_iter=1000
        )
    )
])

Train:

model_pipeline.fit(
X_train,
y_train
)

Predict:

y_pred = model_pipeline.predict(
X_test
)

7.30.18 Complete Example

from sklearn.model_selection import train_test_split
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import (
    StandardScaler,
    OneHotEncoder
)
from sklearn.linear_model import LogisticRegression
numeric_features = [
    "age",
    "income",
    "tenure"
]

categorical_features = [

"city",

"payment_method"
]
numeric_pipeline = Pipeline([
    (
        "imputer",
        SimpleImputer(strategy="median")
    ),
    (
        "scaler",
        StandardScaler()
    )
])
categorical_pipeline = Pipeline([
    (
        "imputer",
        SimpleImputer(
            strategy="most_frequent"
        )
    ),
    (
        "encoder",
        OneHotEncoder(
            handle_unknown="ignore"
        )
    )
])

preprocessor = ColumnTransformer([

(

),

(

"categorical",

categorical_pipeline,
categorical_features
)
])
pipeline = Pipeline([
(

"preprocessor",

preprocessor

),

(

"model",

LogisticRegression(
max_iter=1000
)
)
])
pipeline.fit(
X_train,
y_train
)
predictions = pipeline.predict(
X_test
)

7.30.19 Pipeline for Regression

Pipelines are not limited to classification.

Example:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
pipeline = Pipeline([
("scaler", StandardScaler()),
("model", LinearRegression())
])
pipeline.fit(
X_train,
y_train
)
predictions = pipeline.predict(
X_test
)

7.30.20 Pipeline with Random Forest

Tree-based models generally don't require scaling.

For example:

from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestClassifier
pipeline = Pipeline([
    (
        "imputer",
        SimpleImputer(strategy="median")
    ),
    (
        "model",
        RandomForestClassifier(
            n_estimators=200,
            random_state=42
        )
    )
])

7.30.21 Pipeline with PCA

PCA is usually applied after scaling.

Example:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
pipeline = Pipeline([
("scaler", StandardScaler()),
("pca", PCA(n_components=10)),
("model", LogisticRegression())
])

The order is important:

Data

↓
Scaling
↓
PCA
↓
Logistic Regression

7.30.22 Pipeline with Feature Selection

Feature selection can also be included.

from sklearn.feature_selection import SelectKBest
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    (
        "selection",
        SelectKBest(k=20)
    ),
    ("model", LogisticRegression())
])

Workflow:

Data

↓
Scale
↓
Select 20 Features
↓
Model

7.30.23 Pipelines and Cross Validation

Pipelines are extremely useful with cross-validation.

from sklearn.model_selection import cross_val_score
scores = cross_val_score(
pipeline,
X,
y,
cv=5,
scoring="f1"
)
print(scores)
print(scores.mean())

Why is this important?

Each fold gets its own fitting process:

Fold 1

Fit preprocessing on Fold 1 training data

↓
Transform Fold 1 validation data
↓
Train model
↓
Evaluate

This helps prevent preprocessing leakage across folds.

7.30.24 Pipelines and Hyperparameter Tuning

Pipeline parameters can be tuned using GridSearchCV or RandomizedSearchCV.

Example:

from sklearn.model_selection import GridSearchCV
param_grid = {
"model__C": [
0.01,
0.1,
1,
10
]
}
search = GridSearchCV(
pipeline,
param_grid,
cv=5,
scoring="f1"
)
search.fit(
X_train,
y_train
)
print(
search.best_params_
)
Pipeline step → Parameter

Here:

model

↓
C

7.30.25 Tuning Preprocessing Parameters

You can also tune preprocessing.

],

"model__C": [

0.1,

1,

10

]

}

This allows the entire workflow to be optimized together.

7.30.26 Pipeline and Model Persistence

Save the entire pipeline:

import joblib
joblib.dump(
pipeline,
"customer_churn_pipeline.joblib"
)

)

Then:

prediction = pipeline.predict(
new_data
)

This is much safer than separately managing:

7.30.27 Pipeline Deployment

A production architecture might look like:

Client

↓
API
↓
Saved ML Pipeline
│
┌──────────┴──────────┐
↓ ↓
Preprocessing Model
│ │
└──────────┬──────────┘
↓
Prediction

The API doesn't need to manually execute preprocessing.

7.30.28 ML Pipeline vs Data Pipeline

These are related but different concepts.

↓
Preprocessing
↓
Feature Engineering
↓
Model
↓
Prediction
Data Pipeline

Focuses primarily on moving and transforming data:

Source

↓
Extract
↓
Transform
↓
Load
↓
Data Warehouse

For example:

ADF / ETL

↓
Data Warehouse
↓
ML Pipeline
↓
Model

7.30.29 ML Pipeline vs MLOps Pipeline

ML Pipeline

Usually refers to the ML processing workflow:

Data

↓
Preprocessing
↓
Training
↓
Evaluation
MLOps Pipeline

Includes the broader lifecycle:

Data

↓
Validation
↓
Training
↓
Evaluation
↓
Model Registry
↓
Deployment
↓
Monitoring
↓
Retraining

MLOps pipelines therefore include operational and deployment activities in addition to model training.

7.30.30 Training Pipeline

A production training pipeline may look like:

Data Source

↓
Data Validation
↓
Data Cleaning
↓
Feature Engineering
↓
Train/Validation Split
↓
Model Training
↓
Evaluation
↓
Model Validation
↓
Register Model

If the model meets quality requirements:

Register Model

↓
Deploy

Otherwise:

Reject Model

↓
Investigate

7.30.31 Inference Pipeline

An inference pipeline:

New Data

↓
Schema Validation
↓
Preprocessing
↓
Feature Transformation
↓
Model
↓
Prediction
↓
Business Rules
↓
Application

Example:

Customer Data

↓
Validate
↓
Transform
↓
Churn Model
↓
0.82
↓
High Risk

7.30.32 Batch ML Pipeline

Example:

Daily 2 AM

↓
Extract Customer Data
↓
Validate Data
↓
Load ML Pipeline
↓
Generate Predictions
↓
Store Results
↓
Power BI Dashboard

This architecture is common for enterprise analytics.

7.30.33 Real-Time ML Pipeline

Example:

Online Transaction

↓
API Gateway
↓
Validation
↓
Feature Processing
↓
Fraud Model
↓
Fraud Probability
↓
Transaction Decision

For example:

Transaction

↓
0.96 fraud probability
↓
Block / Review

7.30.34 Feature Engineering in Pipelines

Feature engineering should ideally be part of the reproducible workflow.

Example:

Transaction Date
Extract:
↓
Model

Another example:

Order Amount

+

Previous Orders

↓
Average Order Value
↓
Model

If these transformations are performed manually, production consistency becomes difficult.

7.30.35 Feature Store

↓
Feature Engineering
↓
Feature Store
├── Training Features
└── Serving Features

The goal is to make features consistently available for both training and inference.

7.30.36 Pipeline Reproducibility

A good ML pipeline should allow us to reproduce a model.

+

Same Code

+

Same Configuration

↓
Reproducible Model

7.30.37 Pipeline Monitoring

7.30.38 Pipeline Failure Handling

↓
FAILURE
↓
Retry
↓
If still fails
↓
Alert

7.30.39 Data Quality Gates

Before training:

Data

↓
Quality Checks
↓
Pass? ── No ──→ Stop Pipeline
↓
Yes
↓
Training
This prevents poor-quality data from silently producing a bad model.

7.30.40 ML Pipeline Example — Customer Churn

Complete architecture:

Customer Database

↓
Data Extraction
↓
Data Validation
↓
Feature Engineering
↓
Train/Test Split
↓
Preprocessing
↓
CatBoost / XGBoost
↓
Model Evaluation
↓
Model Registry
↓
Production Deployment
↓
Churn API
↓
Predictions
↓
Monitoring
↓
Retraining

7.30.41 ML Pipeline Example — Fraud Detection

Transaction Stream

↓
Data Validation
↓
Feature Generation
↓
Fraud Model
↓
Fraud Probability
↓
Decision Threshold
↓
Approve / Review / Block
↓
Log Prediction
↓
Monitor

This is a real-time inference pipeline.

7.30.42 ML Pipeline Best Practices

1. Automate preprocessing

Avoid manually transforming production data.

2. Version everything

3. Prevent data leakage

Fit preprocessing only on appropriate training data.

4. Validate inputs

Don't trust production data blindly.

5. Monitor the pipeline

Track both ML and infrastructure metrics.

6. Make pipelines reproducible

A model should be reproducible from known artifacts.

7. Test before deployment

Use unit, integration, data-quality, and model-performance tests as appropriate.

8. Maintain rollback capability

Always retain a known-good model version.

7.30.43 Interview Questions

Q1. What is an ML Pipeline?

An ML pipeline is a sequence of automated steps that performs data transformation, feature engineering, model training, or inference in a consistent and reproducible manner.

Q2. Why use an ML pipeline?

To ensure preprocessing and model operations are consistent, reproducible, maintainable, and less prone to leakage.

Q3. What is the difference between a transformer and an estimator?

A transformer generally performs data transformations using fit() and transform(), while an estimator learns a model and typically provides fit() and predict().

Q4. What is ColumnTransformer?

It applies different preprocessing pipelines to different groups of columns.

Q5. Why are pipelines useful for cross-validation?

They ensure preprocessing is fitted separately inside each training fold rather than leaking information from validation folds.

Q6. How do you save an ML pipeline?

For scikit-learn, you can commonly use joblib:

joblib.dump(
pipeline,
"model.joblib"
)

Q7. What is the difference between an ML pipeline and a data pipeline?

An ML pipeline focuses on machine learning transformations and modeling, while a data pipeline primarily focuses on extracting, transforming, and moving data.

Q8. What is an inference pipeline?

A workflow that takes new data, validates and transforms it, applies the trained model, and produces predictions.

Q9. What is a training pipeline?

A workflow that prepares training data, trains models, evaluates them, and potentially registers/deploys the selected model.

Q10. How do pipelines help prevent data leakage?

Transformations such as scaling and imputation are fitted only on the training portion within the pipeline and then applied to validation/test data.

Q11. What is an MLOps pipeline?

A broader automated lifecycle covering data validation, training, evaluation, model registration, deployment, monitoring, and potentially retraining.

7.30.44 Key Takeaways

↓
Data Validation
↓
Preprocessing
↓
Feature Engineering
↓
Model
↓
Prediction

A training pipeline extends this:

Data

↓
Validation
↓
Preprocessing
↓
Training
↓
Evaluation
↓
Model Registry
↓
Deployment

And a production MLOps lifecycle becomes:

Data

↓
Validation
↓
Training
↓
Evaluation
↓
Registration
↓
Deployment
↓
Monitoring
↓
Drift Detection
↓
Retraining
↓
Redeployment
Most important interview definition

An ML pipeline is a reproducible sequence of data-processing, feature-engineering, model-training, and prediction steps that ensures the same transformation and modeling logic is consistently applied during development and production.

For scikit-learn, the most important concepts to remember are:

GridSearchCV
RandomizedSearchCV

Model Persistence

These concepts form the foundation for building reliable end-to-end machine learning workflows.

Module 7 · Lesson 7.31

Scikit-learn

7.31.1 Introduction

Scikit-learn is commonly used for traditional machine learning problems involving structured or tabular data.

7.31.2 Why Scikit-learn?

Without a machine-learning library, implementing algorithms such as:

from scratch would require significant mathematical and programming effort.

Scikit-learn provides consistent APIs:

model.fit(X_train, y_train)
predictions = model.predict(X_test)

This makes experimenting with different algorithms much easier.

7.31.3 Installation

import sklearn
print(sklearn.__version__)

7.31.4 Scikit-learn Ecosystem

A simplified view:

Scikit-learn

│
┌───────────────┼────────────────┐
↓ ↓ ↓
Preprocessing Models Evaluation
│ │ │
↓ ↓ ↓
Scaling Regression Accuracy
Encoding Classification Precision
Imputation Clustering Recall
Dimensionality F1
Reduction ROC-AUC

7.31.5 Basic Scikit-learn Workflow

A typical workflow is:

Load Data

↓
Explore Data
↓
Split Data
↓
Preprocess
↓
Train Model
↓
Predict
↓
Evaluate
↓
Tune
↓
Save Model

Example:

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
model = LogisticRegression()
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)
accuracy = accuracy_score(
y_test,
y_pred
)
print("Accuracy:", accuracy)

7.31.6 Scikit-learn API

One of the biggest advantages of Scikit-learn is its consistent API.

Most estimators follow:

model.fit(X, y)

for training.

Prediction:

model.predict(X)

Probability prediction, when supported:

model.predict_proba(X)

Transformation:

transformer.fit(X)
transformer.transform(X)

7.31.7 fit()

fit() trains or learns parameters from the data.

Example:

from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(
X_train,
y_train
)

Conceptually:

Training Data

↓
fit()
↓
Learn Parameters
↓
Trained Model

7.31.8 predict()

After training:

y_pred = model.predict(
X_test
)

Conceptually:

New Data

↓
predict()
↓
Prediction

7.31.9 predict_proba()

Some classifiers provide probability estimates.

Example:

probabilities = model.predict_proba(
X_test
)

Output might look like:

\[[0.80, 0.20], [0.15, 0.85], [0.65, 0.35]\]

For binary classification:

Column 0 → Probability of class 0
Column 1 → Probability of class 1

Usually:

positive_probability = model.predict_proba(
X_test
)[:, 1]

is used for the positive class.

7.31.10 Supervised Learning

7.31.11 Linear Regression

Import:

from sklearn.linear_model import LinearRegression
model.fit(
X_train,
y_train
)

Predict:

y_pred = model.predict(
X_test
)

7.31.12 Logistic Regression

from sklearn.linear_model import LogisticRegression
model = LogisticRegression(
max_iter=1000
)
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)

For probabilities:

y_prob = model.predict_proba(
X_test
)[:, 1]

7.31.13 Decision Tree

from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(
max_depth=5,
random_state=42
)
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)

7.31.14 Random Forest

from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=200,
random_state=42
)
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)

7.31.15 Support Vector Machine

from sklearn.svm import SVC
model = SVC(
probability=True,
random_state=42
)
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)

For many SVM workflows, scaling features is important.

7.31.16 K-Nearest Neighbors

from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier(
n_neighbors=5
)
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)

KNN is distance-based, so feature scaling is generally important when features have different scales.

7.31.17 Naive Bayes

For Gaussian-distributed numerical features:

from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(
X_train,
y_train
)
y_pred = model.predict(
X_test
)

7.31.18 K-Means

Scikit-learn also supports unsupervised learning.

from sklearn.cluster import KMeans
model = KMeans(
n_clusters=3,
random_state=42,
n_init="auto"
)
model.fit(X)
labels = model.labels_

Conceptually:

Data

↓
K-Means
↓
Cluster 1
Cluster 2
Cluster 3

7.31.19 PCA

Principal Component Analysis:

from sklearn.decomposition import PCA
pca = PCA(
n_components=2
)
X_reduced = pca.fit_transform(
X
)

Typical workflow:

Original Features

↓
Standardization
↓
PCA
↓
Reduced Features

7.31.20 Data Splitting

A fundamental Scikit-learn function:

from sklearn.model_selection import train_test_split

Example:

X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)

Meaning:

80% → Training
20% → Testing

7.31.21 random_state

random_state controls randomness.

Example:

train_test_split(
X,
y,
test_size=0.2,
random_state=42
)

Using the same value makes the split reproducible.

The value 42 has no special mathematical significance; it's simply a commonly used example.

7.31.22 Stratified Split

For classification, especially imbalanced classification:

X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)

stratify=y attempts to preserve class proportions in the train and test sets.

7.31.23 Preprocessing

Scikit-learn provides many preprocessing tools.

StandardScaler
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(
X_train
)
X_test_scaled = scaler.transform(
X_test
)

Important:

Training → fit_transform()
Test → transform()

Do not fit the scaler separately on test data.

7.31.24 MinMaxScaler

Scales features to a specified range, commonly 0 to 1.

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(
X_train
)
X_test_scaled = scaler.transform(
X_test
)

7.31.25 One-Hot Encoding

For categorical data:

from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(
handle_unknown="ignore"
)

Example:

7.31.26 Missing Value Imputation

Scikit-learn provides:

from sklearn.impute import SimpleImputer

Example:

imputer = SimpleImputer(
strategy="median"
)
X_train_imputed = imputer.fit_transform(
X_train
)
X_test_imputed = imputer.transform(
X_test
)

7.31.27 Feature Selection

Scikit-learn provides feature selection tools.

Example:

from sklearn.feature_selection import SelectKBest
selector = SelectKBest(
k=10
)
X_selected = selector.fit_transform(
X_train,
y_train
)

7.31.28 Pipelines

Scikit-learn pipelines combine transformations and models.

from sklearn.pipeline import Pipeline
pipeline = Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression())
])

Then:

pipeline.fit(
X_train,
y_train
)
y_pred = pipeline.predict(
X_test
)

This avoids manually managing each transformation.

7.31.29 ColumnTransformer

When numerical and categorical columns require different preprocessing:

from sklearn.compose import ColumnTransformer
preprocessor = ColumnTransformer([
    (
        "num",
        numeric_pipeline,
        numeric_features
    ),
    (
        "cat",
        categorical_pipeline,
        categorical_features
    )
])

This is extremely useful for real-world tabular datasets.

7.31.30 Model Evaluation

Scikit-learn provides many metrics.

Classification
from sklearn.metrics import (
accuracy_score,
precision_score,
recall_score,
f1_score,
roc_auc_score
)
Regression
from sklearn.metrics import (
mean_absolute_error,
mean_squared_error,
r2_score
)

7.31.31 Classification Evaluation Example

from sklearn.metrics import (
    accuracy_score,
    precision_score,
    recall_score,
    f1_score
)
print(
    "Accuracy:",
    accuracy_score(y_test, y_pred)
)
print(
    "Precision:",
    precision_score(y_test, y_pred)
)
print(
    "Recall:",
    recall_score(y_test, y_pred)
)
print(
    "F1:",
    f1_score(y_test, y_pred)
)

7.31.32 Confusion Matrix

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(
y_test,
y_pred
)
print(cm)

You can visualize it:

from sklearn.metrics import ConfusionMatrixDisplay
import matplotlib.pyplot as plt
ConfusionMatrixDisplay.from_predictions(
y_test,
y_pred
)
plt.show()

7.31.33 Classification Report

One of the most useful evaluation functions:

from sklearn.metrics import classification_report
print(
classification_report(
y_test,
y_pred
)
)

Example:

7.31.34 Regression Metrics

MAE

Mean Absolute Error:

\[MAE = \frac{1}{n} \sum |y_i-\hat y_i|\]

Python:

from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(
y_test,
y_pred
)
MSE
from sklearn.metrics import mean_squared_error
mse = mean_squared_error(
y_test,
y_pred
)
RMSE
import numpy as np
from sklearn.metrics import mean_squared_error
rmse = np.sqrt(
mean_squared_error(
y_test,
y_pred
)
)

from sklearn.metrics import r2_score
r2 = r2_score(
y_test,
y_pred
)

7.31.35 Cross Validation

Scikit-learn makes cross-validation easy.

from sklearn.model_selection import cross_val_score
scores = cross_val_score(
model,
X,
y,
cv=5,
scoring="f1"
)
print(scores)
print(scores.mean())

Conceptually:

Dataset

↓
┌────┬────┬────┬────┬────┐
│ F1 │ F2 │ F3 │ F4 │ F5 │
└────┴────┴────┴────┴────┘
↓
5 validation scores
↓
Average score

7.31.36 K-Fold Cross Validation

from sklearn.model_selection import KFold
kf = KFold(
n_splits=5,
shuffle=True,
random_state=42
)

For classification, StratifiedKFold is often preferable when preserving class proportions matters:

from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(
n_splits=5,
shuffle=True,
random_state=42
)

7.31.37 Hyperparameter Tuning

Scikit-learn provides:

GridSearchCV
RandomizedSearchCV
GridSearchCV
from sklearn.model_selection import GridSearchCV
param_grid = {
"max_depth": [3, 5, 10],
"n_estimators": [100, 200]
}
search = GridSearchCV(
RandomForestClassifier(
random_state=42
),
param_grid,
cv=5,
scoring="f1"
)
search.fit(
X_train,
y_train
)

Get the best model:

best_model = search.best_estimator_

7.31.38 RandomizedSearchCV

When the parameter space is large:

from sklearn.model_selection import RandomizedSearchCV
search = RandomizedSearchCV(
model,
param_distributions,
n_iter=20,
cv=5,
scoring="f1",
random_state=42
)
search.fit(
X_train,
y_train
)

This evaluates a selected number of parameter combinations rather than every combination.

7.31.39 GridSearchCV vs RandomizedSearchCV

GridSearchCV RandomizedSearchCV
Tests specified combinations Samples combinations
Can be expensive Usually more efficient for large spaces
Exhaustive over provided grid Does not test every possible combination
Good for small search spaces Good for large search spaces

7.31.40 Feature Importance

Some models provide feature importance.

For Random Forest:

model.feature_importances_

Example:

importance = model.feature_importances_
for feature, score in zip(
feature_names,
importance
):
print(
feature,
score
)

This can help identify influential features, though feature importance should be interpreted carefully.

7.31.41 Scikit-learn Model Selection

Then select an appropriate model based on both technical and business requirements.

7.31.42 Complete Scikit-learn Example

Let's create a simple classification workflow.

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import (
    train_test_split
)
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (
    accuracy_score,
    precision_score,
    recall_score,
    f1_score,
    confusion_matrix
)
data = load_breast_cancer()
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y
)
pipeline = Pipeline([
    (
        "scaler",
        StandardScaler()
    ),
    (
        "model",
        LogisticRegression(
            max_iter=2000
        )
    )
])
pipeline.fit(
    X_train,
    y_train
)
y_pred = pipeline.predict(
    X_test
)
print(
    "Accuracy:",
    accuracy_score(y_test, y_pred)
)
print(
    "Precision:",
    precision_score(y_test, y_pred)
)
print(
    "Recall:",
    recall_score(y_test, y_pred)
)
print(
    "F1:",
    f1_score(y_test, y_pred)
)
print(
    "Confusion Matrix:"
)
print(
    confusion_matrix(
        y_test,
        y_pred
    )
)

7.31.43 Scikit-learn Project Structure

A production-oriented project might look like:

ml_project/

│
├── data/
│ ├── raw/
│ └── processed/
│
├── notebooks/
│ └── exploration.ipynb
│
├── src/
│ ├── preprocessing.py
│ ├── features.py
│ ├── train.py
│ └── predict.py
│
├── models/
│ └── model.joblib
│
├── tests/
│ └── test_model.py
│
├── requirements.txt
└── README.md

For larger production projects, the structure can be expanded around configuration, pipelines, APIs, monitoring, and deployment.

7.31.44 Scikit-learn and MLOps

Scikit-learn handles the ML modeling layer:

Data

↓
Preprocessing
↓
Model
↓
Evaluation

MLOps adds:

Versioning

↓
Experiment Tracking
↓
Model Registry
↓
Deployment
↓
Monitoring
↓
Retraining

Therefore:

Scikit-learn

+

MLOps Tools

=

Production ML System

7.31.45 Important Scikit-learn Modules

Module Purpose
sklearn.model_selection Splitting, CV, hyperparameter tuning
sklearn.preprocessing Scaling, encoding, transformations
sklearn.impute Missing-value handling
sklearn.pipeline ML pipelines
sklearn.compose ColumnTransformer
sklearn.linear_model Linear/Logistic Regression
sklearn.tree Decision Trees
sklearn.ensemble Random Forest, Gradient Boosting
sklearn.svm Support Vector Machines
sklearn.neighbors KNN
sklearn.naive_bayes Naive Bayes
sklearn.cluster Clustering
sklearn.decomposition PCA and related methods
sklearn.feature_selection Feature selection
sklearn.metrics Model evaluation

7.31.46 Scikit-learn API Design

One major advantage is consistency.

For example:

model.fit(X, y)
model.predict(X)

You can often replace:

LogisticRegression()

with:

RandomForestClassifier()

without completely rewriting the workflow.

7.31.47 Common Mistakes

Mistake 1: Scaling Before Train/Test Split

Incorrect:

scaler.fit_transform(X)
train_test_split(...)

Better:

Split

↓
Fit preprocessing on training data
↓
Transform test data

Distance- and margin-based models such as KNN and many SVM workflows are sensitive to feature scale.

7.31.48 Interview Questions

Q1. What is Scikit-learn?

Scikit-learn is a Python machine-learning library providing algorithms and tools for preprocessing, model training, evaluation, feature selection, cross-validation, and hyperparameter tuning.

Q2. What is the basic Scikit-learn workflow?

Split

↓
Preprocess
↓
Fit
↓
Predict
↓
Evaluate

Q3. What does fit() do?

It learns parameters from the provided training data.

Q4. What does predict() do?

It generates predictions using a fitted model.

Q5. What is predict_proba()?

It returns class probability estimates for classifiers that support them.

Q6. Why use Pipeline?

To combine preprocessing and modeling into one reproducible workflow and reduce leakage/inconsistency risks.

Q7. What is ColumnTransformer?

It allows different transformations to be applied to different groups of columns.

Q8. What is GridSearchCV?

It systematically evaluates specified hyperparameter combinations using cross-validation.

Q9. What is RandomizedSearchCV?

It evaluates a specified number of randomly sampled parameter combinations.

Q10. What is random_state?

It controls pseudo-randomness for reproducibility in algorithms and data splitting where applicable.

Q11. Why use stratify=y?

To approximately preserve class proportions when splitting classification data.

Q12. What is the difference between fit_transform() and transform()?

fit_transform() learns transformation parameters from data and transforms it. transform() applies already-learned parameters without refitting.

Q13. Why should we not call fit_transform() on the test set?

Because the test set should remain unseen during fitting. Doing so can leak information from the test distribution into the preprocessing.

7.31.49 Key Takeaways

Scikit-learn provides a complete toolkit for traditional machine learning:

Scikit-learn

│
┌─────────────────┼─────────────────┐
↓ ↓ ↓
Preprocessing Algorithms Evaluation
↓ ↓ ↓
Scaling Regression Accuracy
Encoding Classification Precision
Imputation Clustering Recall
Feature Selection PCA F1
│ │ ROC-AUC
└─────────────────┼─────────────────┘
↓
Model Selection
↓
Cross Validation
↓
Hyperparameter Tuning
↓
Pipeline

And the most important tools to remember are:

train_test_split
Pipeline
ColumnTransformer
StandardScaler
OneHotEncoder
SimpleImputer
cross_val_score
GridSearchCV
RandomizedSearchCV
classification_report
confusion_matrix

One-line interview definition

Scikit-learn is a Python machine-learning library that provides a consistent and practical API for data preprocessing, supervised and unsupervised learning, model evaluation, cross-validation, hyperparameter tuning, feature selection, and ML pipelines.

Module 7 · Lesson 7.32

ML Case Study

7.32.1 Introduction

A Machine Learning Case Study demonstrates how ML concepts are applied to a real-world business problem from beginning to end.

In this case study, we will build a Customer Churn Prediction System.

Business Problem

A telecom company wants to identify customers who are likely to leave the company.

The company can use these predictions to:

↓
Data Collection
↓
Data Understanding
↓
Data Cleaning
↓
EDA
↓
Feature Engineering
↓
Train/Test Split
↓
Preprocessing
↓
Model Training
↓
Model Evaluation
↓
Model Selection
↓
Deployment
↓
Monitoring

7.32.2 Business Objective

↓
Churn Probability
↓
Risk Category

Example:

7.32.3 Machine Learning Problem

This is a supervised binary classification problem.

0 → Customer stays
1 → Customer churns

Therefore:

Input Features

↓
Classification Model
↓
Churn = 0 or 1

7.32.4 Example Dataset

Suppose the company has the following data:

Customer Age Tenure Monthly Charges Contract Support Calls Churn
C001 25 4 80 Monthly 5 1
C002 42 36 45 Annual 1 0
C003 31 8 95 Monthly 4 1
C004 55 60 40 Annual 0 0
C005 29 12 75 Monthly 3 1

7.32.5 Feature Types

This matters because different preprocessing is required.

Numerical

↓
Imputation
↓
Scaling
Categorical
↓
Imputation
↓
One-Hot Encoding

7.32.6 Business Understanding Before Modeling

7.32.7 Data Collection

Data could come from:

CRM

+

Billing System

+

Customer Support

+

Product Usage

+

Contracts

↓
Customer ML Dataset

7.32.8 Data Exploration

Load the data:

import pandas as pd
df = pd.read_csv(
"customer_churn.csv"
)
print(
df.head()
)

Check dimensions:

print(
df.shape
)

Check data types:

print(
df.dtypes
)

Check missing values:

print(
df.isnull().sum()
)

7.32.9 Example Dataset Inspection

print(
df.info()
)
print(
df.describe()
)

Categorical columns:

print(
df.select_dtypes(
include="object"
).columns
)

Numerical columns:

print(
df.select_dtypes(
include="number"
).columns
)

7.32.10 Check Target Distribution

One of the first things we should check is class balance.

print(
df["Churn"].value_counts()
)
print(
df["Churn"].value_counts(
normalize=True
)
)

This is an imbalanced classification problem.

7.32.11 Why Class Imbalance Matters

Suppose:

90% → Stay
10% → Churn

A model predicting:

Everyone → Stay

Therefore, accuracy alone isn't sufficient.

7.32.12 Exploratory Data Analysis

We can investigate relationships such as:

↓
Higher Churn
Annual Contract
↓
Lower Churn

Or:

More Support Calls

↓
Higher Churn Risk

These observations can guide feature engineering and business understanding, but correlation does not automatically imply causation.

7.32.13 Data Cleaning

Example:

df = df.drop_duplicates()

7.32.14 Missing Values

Suppose:

Monthly Charges

----------------

We can use median imputation:

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(
strategy="median"
)

For categorical data:

SimpleImputer(
strategy="most_frequent"
)

In production, fit these transformations only on the appropriate training data, preferably within a pipeline.

7.32.15 Feature Engineering

We can derive:

Average Monthly Spend

=

Feature engineering should be based on information that would actually be available at prediction time.

7.32.16 Avoiding Data Leakage

↓
Features
↓
ML Model
↓
Future Churn

Incorrect:

Future Information

↓
Features
↓
Model

7.32.17 Train/Test Split

Separate features and target:

X = df.drop(
    "Churn",
    axis=1
)
y = df["Churn"]

Split:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)

Result:

80% → Training
20% → Testing

7.32.18 Preprocessing

from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
numeric_pipeline = Pipeline([
    (
        "imputer",
        SimpleImputer(
            strategy="median"
        )
    ),
    (
        "scaler",
        StandardScaler()
    )
])

Categorical preprocessing:

from sklearn.preprocessing import OneHotEncoder
categorical_pipeline = Pipeline([
    (
        "imputer",
        SimpleImputer(
            strategy="most_frequent"
        )
    ),
    (
        "encoder",
        OneHotEncoder(
            handle_unknown="ignore"
        )
    )
])

7.32.19 ColumnTransformer

from sklearn.compose import ColumnTransformer
numeric_features = [
    "Age",
    "Tenure",
    "Monthly Charges",
    "Support Calls"
]

categorical_features = [

"Contract"

]

preprocessor = ColumnTransformer([

(

),

(

)

])

7.32.20 Model Selection

We can start with a baseline model:

Logistic Regression

Then compare:

↓
Experiment
↓
Compare
↓
Select

7.32.21 Baseline — Logistic Regression

from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
logistic_pipeline = Pipeline([
    (
        "preprocessor",
        preprocessor
    ),
    (
        "model",
        LogisticRegression(
            max_iter=1000
        )
    )
])

Train:

logistic_pipeline.fit(
X_train,
y_train
)

Predict:

y_pred = logistic_pipeline.predict(
X_test
)

7.32.22 Evaluate the Baseline

from sklearn.metrics import (
    accuracy_score,
    precision_score,
    recall_score,
    f1_score,
    roc_auc_score
)
y_prob = logistic_pipeline.predict_proba(
    X_test
)[:, 1]
print(
    "Accuracy:",
    accuracy_score(
        y_test,
        y_pred
    )
)
print(
    "Precision:",
    precision_score(
        y_test,
        y_pred
    )
)
print(
    "Recall:",
    recall_score(
        y_test,
        y_pred
    )
)
print(
    "F1:",
    f1_score(
        y_test,
        y_pred
    )
)
print(
    "ROC-AUC:",
    roc_auc_score(
        y_test,
        y_prob
    )
)

7.32.23 Confusion Matrix

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(
y_test,
y_pred
)
print(cm)

Suppose:

\[[150 10\]

\[20 20]\]

7.32.24 Model Comparison

Suppose we test several models:

Model Precision Recall F1 ROC-AUC
Logistic Regression 0.70 0.72 0.71 0.82
Decision Tree 0.68 0.69 0.68 0.76
Random Forest 0.78 0.74 0.76 0.86
XGBoost 0.81 0.79 0.80 0.89
CatBoost 0.80 0.82 0.81 0.90

In this example:

CatBoost

↓
Highest F1
+
High Recall
+
High ROC-AUC

So CatBoost might be selected for further evaluation.

But the actual choice should depend on validation performance and business costs, not just these hypothetical numbers.

7.32.25 Cross Validation

Instead of relying on one split:

from sklearn.model_selection import cross_val_score
scores = cross_val_score(
logistic_pipeline,
X_train,
y_train,
cv=5,
scoring="f1"
)
print(
"F1 Scores:",
scores
)
print(
"Mean F1:",
scores.mean()
)

Example:

F1 Scores:

\[0.78, 0.81, 0.79, 0.83, 0.80\]

Mean F1:

0.802

7.32.26 Hyperparameter Tuning

For Random Forest:

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
rf_pipeline = Pipeline([
    (
        "preprocessor",
        preprocessor
    ),
    (
        "model",
        RandomForestClassifier(
            random_state=42
        )
    )
])

],

"model__max_depth": [

5,

10,

None

],

"model__min_samples_split": [

2,

5,

10

]

}

Search:

grid_search = GridSearchCV(
rf_pipeline,
param_grid,
cv=5,
scoring="f1",
n_jobs=-1
)
grid_search.fit(
X_train,
y_train
)

Best model:

best_model = grid_search.best_estimator_
print(
grid_search.best_params_
)

7.32.27 Final Evaluation

After model selection, evaluate once on the untouched test set.

final_pred = best_model.predict(
X_test
)
final_prob = best_model.predict_proba(
X_test
)[:, 1]

Then:

print(
classification_report(
y_test,
final_pred
)
)

And:

print(
    "ROC-AUC:",
    roc_auc_score(
        y_test,
        final_prob
    )
)

7.32.28 Threshold Selection

If the business wants to catch more churners:

Threshold ↓
↓
Recall ↑
↓
More customers flagged

A lower threshold may be appropriate, provided the retention team can handle the increased number of alerts.

7.32.29 Business Decision

Suppose:

Customer Churn Probability = 0.87

The ML model should not necessarily decide:

↓
Churn Probability
↓
Business Rules
↓
Customer Segment
↓
Retention Action

For example:

Probability < 0.30

→ No action
0.30–0.70
→ Low-cost engagement
> 0.70
→ Retention campaign

The thresholds and actions should be based on business economics and experimentation.

7.32.30 Model Deployment

Save the complete pipeline:

import joblib
joblib.dump(
best_model,
"customer_churn_pipeline.joblib"
)

)

New customer:

prediction = model.predict(
new_customer
)
probability = model.predict_proba(
new_customer
)[:, 1]

7.32.31 Production Architecture

A real production solution might look like:

Customer Data

↓
Data Warehouse
↓
Feature Pipeline
↓
ML Model
↓
Churn Probability
↓
Business Rules
↓
┌────────────┴────────────┐
↓ ↓
Retention Campaign Customer Dashboard

For real-time use:

Customer Application

↓
API
↓
ML Prediction Service
↓
Churn Model
↓
Probability

7.32.32 Monitoring

7.32.33 Model Drift

7.32.34 Retraining Pipeline

A mature system could run:

New Customer Data

↓
Data Validation
↓
Retraining
↓
Evaluation
↓
Compare with Model
↓
┌──────────┴──────────┐
↓ ↓

Better? Worse?

↓ ↓
Deploy Reject

7.32.35 End-to-End Architecture

The complete solution:

┌─────────────────────────────────────────────┐
│ DATA SOURCES │
│ CRM | Billing | Support | Usage | Contracts│
└─────────────────────┬───────────────────────┘
↓
Data Engineering
↓
Data Warehouse
↓
Feature Dataset
↓
Data Validation
↓
Train / Validation
↓
┌─────────────────┐
│ ML Experiments │
└────────┬────────┘
↓
Model Evaluation
↓
Model Selection
↓
Model Registry
↓
Deployment
↓
┌────────┴────────┐
↓ ↓
Batch API Real-Time API
↓ ↓
└────────┬────────┘
↓
Predictions
↓
Business Actions
↓
Monitoring
↓
Retraining

7.32.36 What We Learned

This case study covered nearly every major concept in Module 7:

Introduction to ML

↓
ML Workflow
↓
Supervised Learning
↓
Classification
↓
Feature Engineering
↓
Preprocessing
↓
Logistic Regression
↓
Decision Trees
↓
Random Forest
↓
XGBoost / CatBoost
↓
Cross Validation
↓
Hyperparameter Tuning
↓
Precision
Recall
F1
↓
Confusion Matrix
↓
ROC-AUC
↓
ML Pipeline
↓
Scikit-learn
↓
Model Deployment
↓
Monitoring

7.32.37 Key Lessons from the Case Study

Then compare more complex algorithms.

Lesson 5 — Don't Optimize Accuracy Blindly

For churn, fraud, disease, and similar problems:

+

Feature Engineering

+

+

Validation Data

+

↓
Detect Drift
↓
Evaluate
↓
Retrain
↓
Redeploy

7.32.38 Interview Questions

Q1. How would you approach a customer churn prediction problem?

Business Understanding

→ Data Collection
→ EDA
→ Cleaning
→ Feature Engineering
→ Train/Test Split
→ Preprocessing
→ Baseline Model
→ Evaluation
→ Tuning
→ Deployment
→ Monitoring

Q2. Is churn prediction supervised or unsupervised?

Supervised learning, because historical churn labels are available.

Q3. Is churn prediction classification or regression?

Usually binary classification:

0 → Stay
1 → Churn

Q4. Which metric would you use?

It depends on business costs, but commonly:

If missing churners is particularly expensive, prioritize recall.

Q5. Why not use accuracy?

Because churn is often imbalanced, so a model can have high accuracy while performing poorly on churn detection.

Q6. How would you prevent data leakage?

Q7. How would you deploy the model?

Save the complete pipeline and expose it through a batch process or inference API, depending on latency requirements.

Q8. How would you monitor the model?

Q9. When would you retrain?

When performance degrades, significant drift occurs, business conditions change, or on a defined periodic schedule when appropriate.

Q10. What is the difference between model performance and business performance?

A model can have a strong F1 score but still fail to generate business value if the retention actions are too expensive or ineffective.

7.32.39 Final Case Study Summary

↓
DATA
↓
EDA
↓
DATA CLEANING
↓
FEATURE ENGINEERING
↓
PREPROCESSING
↓
BASELINE MODEL
↓
MODEL EVALUATION
↓
CROSS VALIDATION
↓
HYPERPARAMETER TUNING
↓
MODEL SELECTION
↓
DEPLOYMENT
↓
MONITORING
↓
RETRAINING
One-line interview answer

A machine learning case study demonstrates the complete ML lifecycle—from defining a business problem and preparing data through model training, evaluation, deployment, monitoring, and retraining—to convert a real-world business problem into a measurable ML solution.

Module 7 · Lesson 7.33

End-to-End ML Project

Lesson focus: This lesson is part of Module 7 — Machine Learning. Detailed lesson content can be added here from the corresponding source material.
Module 7 · Lesson 7.34

Interview Questions

Lesson focus: This lesson is part of Module 7 — Machine Learning. Detailed lesson content can be added here from the corresponding source material.
Module 7 · Lesson 7.35

Capstone Project

Lesson focus: This lesson is part of Module 7 — Machine Learning. Detailed lesson content can be added here from the corresponding source material.