Skip to content

About

An end-to-end machine learning project for predicting house prices using the Ames Housing dataset. Built with clean software engineering principles, featuring a modular architecture powered by Strategy, Factory, and Template Method design patterns, and orchestrated end to end with ZenML and MLflow.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

84 Commits

Folders and files

Repository files navigation

🏠 End-to-End House Price Prediction

An end-to-end machine learning project for predicting house prices using the Ames Housing dataset. Built with clean software engineering principles, featuring a modular architecture powered by Strategy, Factory, and Template Method design patterns, and orchestrated end to end with ZenML and MLflow.


πŸ“‹ Table of Contents


Overview

This project predicts residential property sale prices in Ames, Iowa using a Linear Regression model built on top of scikit-learn. The entire ML workflow β€” from raw data ingestion through model evaluation β€” is implemented as modular, swappable components that can be orchestrated via ZenML pipelines.

Key highlights:

  • 🧩 Modular design β€” every processing step is strategy-based and interchangeable at runtime
  • πŸ“Š Comprehensive EDA β€” Jupyter notebook with reusable analysis classes
  • πŸ”§ Production-ready patterns β€” Factory, Strategy, and Template Method design patterns
  • πŸ“ˆ Experiment tracking β€” MLflow integration via ZenML experiment tracker
  • πŸš€ Pipeline orchestration β€” ZenML training, deployment, and inference pipelines

Architecture & Design Patterns

The codebase consistently applies clean design patterns:

Strategy Pattern

Every processing step follows the same structure:

  1. Abstract base class β€” defines the interface (e.g., MissingValueHandlingStrategy)
  2. Concrete strategies β€” implement specific algorithms (e.g., DropMissingValuesStrategy, FillMissingValuesStrategy)
  3. Context class β€” delegates to the chosen strategy (e.g., MissingValueHandler)

Factory Pattern

DataIngestorFactory in ingest_data.py returns the correct data ingestor based on file extension.

Template Method Pattern

Analysis classes like MultiVariateAnalysisTemplate and MissingValueAnalysisTemplate define skeleton algorithms with abstract sub-steps.


Project Structure

End_to_End_Price_Prediction/
β”œβ”€β”€ run_pipeline.py                      # CLI: run the training pipeline
β”œβ”€β”€ run_deployment.py                    # CLI: deploy + inference (--stop-service to tear down)
β”œβ”€β”€ pyproject.toml                       # Project config & dependencies (uv)
β”œβ”€β”€ requirements.txt                     # Pip dependencies
β”œβ”€β”€ .python-version                      # Python version pin (3.10)
β”‚
β”œβ”€β”€ data/
β”‚   └── archive.zip                      # Raw dataset (zipped)
β”‚
β”œβ”€β”€ extracted_data/
β”‚   └── AmesHousing.csv                  # Extracted CSV (~2930 rows, 82 columns)
β”‚
β”œβ”€β”€ analysis/
β”‚   β”œβ”€β”€ EDA.ipynb                        # Exploratory Data Analysis notebook
β”‚   └── analyze_src/                     # Reusable analysis classes
β”‚       β”œβ”€β”€ basic_data_inspection.py     # Data types & summary statistics
β”‚       β”œβ”€β”€ univariate_analysis.py       # Histograms, KDE, count plots
β”‚       β”œβ”€β”€ bivariate_analysis.py        # Scatter plots, box plots
β”‚       β”œβ”€β”€ multivariate_analysis.py     # Correlation heatmaps, pair plots
β”‚       └── missing_values_analysis.py   # Missing value counts & heatmaps
β”‚
β”œβ”€β”€ src/                                 # Core ML logic
β”‚   β”œβ”€β”€ ingest_data.py                   # Data ingestion from zip files
β”‚   β”œβ”€β”€ handle_missing_value.py          # Missing value handling strategies
β”‚   β”œβ”€β”€ outlier_detection.py             # Outlier detection (Z-Score, IQR)
β”‚   β”œβ”€β”€ feature_engineering.py           # Feature transformations & encoding
β”‚   β”œβ”€β”€ data_splitter.py                 # Train/test splitting
β”‚   β”œβ”€β”€ model_building.py               # Model training (Linear Regression)
β”‚   └── model_evaluator.py              # Model evaluation (MSE, RΒ²)
β”‚
β”œβ”€β”€ steps/                               # ZenML step wrappers
β”‚   β”œβ”€β”€ data_ingestion_step.py
β”‚   β”œβ”€β”€ handle_missing_values_step.py
β”‚   β”œβ”€β”€ outlier_detection_step.py
β”‚   β”œβ”€β”€ feature_engineering_step.py
β”‚   β”œβ”€β”€ data_splitter_step.py
β”‚   β”œβ”€β”€ model_building_step.py
β”‚   β”œβ”€β”€ model_evaluator_step.py
β”‚   β”œβ”€β”€ dynamic_importer.py
β”‚   β”œβ”€β”€ model_loader.py
β”‚   β”œβ”€β”€ prediction_service_loader.py
β”‚   └── predictor.py
β”‚
└── pipelines/                           # ZenML pipeline definitions
    β”œβ”€β”€ training_pipeline.py             # ingest β†’ clean β†’ split β†’ train β†’ evaluate
    └── deployment_pipeline.py           # continuous deployment + inference pipelines

Tech Stack

Category Technology
Language Python β‰₯ 3.10
Package Manager uv
ML Framework scikit-learn
Data Processing pandas, numpy
Visualization matplotlib, seaborn
Statistics statsmodels
Pipeline Orchestration ZenML
Experiment Tracking MLflow
CLI click

Setup & Installation

Prerequisites

  • Python 3.10 or higher
  • uv (recommended) or pip

Using uv (recommended)

# Clone the repository
git clone https://github.com/<your-username>/End_to_End_Price_Prediction.git
cd End_to_End_Price_Prediction

# Install dependencies
uv sync

Using pip

# Clone the repository
git clone https://github.com/<your-username>/End_to_End_Price_Prediction.git
cd End_to_End_Price_Prediction

# Create and activate a virtual environment
python -m venv .venv
.venv\Scripts\activate        # Windows
# source .venv/bin/activate   # Linux/macOS

# Install dependencies
pip install -r requirements.txt

Dataset

Detail Value
Name Ames Housing Dataset
Source Kaggle
Rows 2,930 residential home sales
Features ~82 columns (numerical + categorical)
Target SalePrice β€” property sale price in USD
Location Ames, Iowa

The raw data is stored as data/archive.zip and extracted to extracted_data/AmesHousing.csv during the ingestion step.


Pipeline

The ML pipeline follows this data flow:

πŸ“¦ archive.zip
    ↓
πŸ“Š Data Ingestion (extract zip β†’ load CSV)
    ↓
πŸ” Missing Value Handling (drop / fill with mean, median, mode, constant)
    ↓
πŸ“ˆ Outlier Detection & Handling (Z-Score β†’ cap at 1st/99th percentile)
    ↓
βš™οΈ  Feature Engineering (log transform on Gr Liv Area)
    ↓
βœ‚οΈ  Train/Test Split (numeric features only, 75/25)
    ↓
πŸ—οΈ Model Building (StandardScaler + Linear Regression pipeline)
    ↓
πŸ“ Model Evaluation (Mean Squared Error, RΒ² Score)
    ↓
πŸš€ Deployment (MLflow model server) β†’ batch Inference (sample data)

Modules

Source Modules (src/)

ingest_data.py β€” Data Ingestion

  • ZipDataIngestor β€” extracts .zip files, validates a single CSV exists, returns a DataFrame
  • DataIngestorFactory β€” factory that returns the correct ingestor by file extension

handle_missing_value.py β€” Missing Value Handling

  • DropMissingValuesStrategy β€” drops rows/columns based on axis and threshold
  • FillMissingValuesStrategy β€” fills with mean, median, mode, or a constant value

outlier_detection.py β€” Outlier Detection

  • ZScoreOutlierDetection β€” flags values where |z-score| exceeds threshold (default: 3)
  • IQROutlierDetection β€” flags values outside Q1 βˆ’ 1.5Γ—IQR to Q3 + 1.5Γ—IQR
  • OutlierDetector β€” supports remove or cap handling (pipeline default: cap at 1st/99th percentile, preserving all rows), plus boxplot visualization

feature_engineering.py β€” Feature Engineering

  • LogTransformation β€” applies log(1+x) to reduce skewness
  • StandardScaling β€” standardizes to mean=0, std=1
  • MinMaxScaling β€” rescales to [0, 1] or custom range
  • OneHotEncoding β€” converts categorical features to binary vectors

data_splitter.py β€” Data Splitting

  • SimpleTrainTestSplit β€” sklearn's train_test_split with configurable test size and random state; the ZenML step selects numeric features only before splitting

model_building.py β€” Model Training

  • LinearRegressionStrategy β€” builds an sklearn Pipeline with StandardScaler β†’ LinearRegression

model_evaluator.py β€” Model Evaluation

  • RegressionModelEvaluationStrategy β€” computes Mean Squared Error (MSE) and RΒ² Score

Analysis Modules (analysis/)

Module Purpose
EDA.ipynb Full exploratory data analysis notebook
basic_data_inspection.py Data types info and descriptive statistics
univariate_analysis.py Distribution plots (histograms + KDE, count plots)
bivariate_analysis.py Relationship plots (scatter plots, box plots)
multivariate_analysis.py Correlation heatmaps and pair plots
missing_values_analysis.py Missing value identification and heatmap visualization

Pipeline & Steps

The steps/ directory contains ZenML step wrappers around the src/ strategies, and pipelines/ defines:

  • ml_pipeline (training_pipeline.py) β€” ingest β†’ missing values β†’ outliers β†’ feature engineering β†’ split β†’ train β†’ evaluate; registered as the ZenML model prices_predictor
  • continuous_deployment_pipeline (deployment_pipeline.py) β€” runs ml_pipeline, then (re)deploys the trained model using ZenML's built-in mlflow_model_deployer_step
  • inference_pipeline (deployment_pipeline.py) β€” loads sample data (dynamic_importer), fetches the live MLflow prediction service (prediction_service_loader), and runs batch predictions against it (predictor)

This provides:

  • Reproducible pipeline runs β€” every step tracked, versioned, and cached
  • Experiment tracking β€” parameters, metrics, and model artifacts logged to MLflow
  • Model serving β€” prediction service via MLflow deployment

Usage

One-time setup

uv sync          # install all dependencies (includes zenml[local])

# Initialize the ZenML workspace and register the MLflow stack
zenml init
zenml experiment-tracker register mlflow_tracker --flavor=mlflow
zenml model-deployer register mlflow_deployer --flavor=mlflow
zenml stack register local_mlflow -e mlflow_tracker -d mlflow_deployer -a default -o default --set

Running the pipelines

# Required on every new terminal on Windows (console defaults to cp1252; ZenML needs UTF-8)
$env:PYTHONUTF8='1'

# Training only: ingest β†’ clean β†’ split β†’ train β†’ evaluate (~10s)
uv run python run_pipeline.py

# Full deployment: train, deploy the model via MLflow, run batch inference
uv run python run_deployment.py

# Stop the prediction service when done
uv run python run_deployment.py --stop-service

Inspecting results

# MLflow UI β€” run the exact command printed at the end of run_pipeline.py, e.g.:
mlflow ui --backend-store-uri "sqlite:///C:\Users\<user>\AppData\Roaming\zenml\local_stores\<id>\mlflow.db"
# then open http://127.0.0.1:5000

# ZenML dashboard (pipelines, runs, stacks)
zenml login --local

Running the EDA Notebook

jupyter notebook analysis/EDA.ipynb

Windows note: MLflow model serving (the daemon-based prediction server used by run_deployment.py) is not supported on native Windows. Training and experiment tracking work fully; for the live prediction service, run under WSL.


Results

Current prices_predictor model (Linear Regression on numeric features, trained via run_pipeline.py):

Metric Value
Mean Squared Error ~8.0 Γ— 10⁸
RΒ² Score 0.875

Project Status

Component Status
Core ML Logic (src/) βœ… Complete
EDA & Analysis βœ… Complete
Design Patterns βœ… Implemented
ZenML Steps (steps/) βœ… Complete
ZenML Pipeline (pipelines/) βœ… Complete
MLflow Integration βœ… Complete (tracking verified; serving limited on Windows)
Documentation βœ… Complete

License

This project is licensed under the Apache License 2.0 β€” see the LICENSE file for details.

About

An end-to-end machine learning project for predicting house prices using the Ames Housing dataset. Built with clean software engineering principles, featuring a modular architecture powered by Strategy, Factory, and Template Method design patterns, and orchestrated end to end with ZenML and MLflow.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages