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.
- Overview
- Architecture & Design Patterns
- Project Structure
- Tech Stack
- Setup & Installation
- Dataset
- Pipeline
- Modules
- Usage
- Results
- Project Status
- License
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
The codebase consistently applies clean design patterns:
Every processing step follows the same structure:
- Abstract base class β defines the interface (e.g.,
MissingValueHandlingStrategy) - Concrete strategies β implement specific algorithms (e.g.,
DropMissingValuesStrategy,FillMissingValuesStrategy) - Context class β delegates to the chosen strategy (e.g.,
MissingValueHandler)
DataIngestorFactory in ingest_data.py returns the correct data ingestor based on file extension.
Analysis classes like MultiVariateAnalysisTemplate and MissingValueAnalysisTemplate define skeleton algorithms with abstract sub-steps.
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
| 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 |
- Python 3.10 or higher
- uv (recommended) or pip
# 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# 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| 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.
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)
ZipDataIngestorβ extracts.zipfiles, validates a single CSV exists, returns a DataFrameDataIngestorFactoryβ factory that returns the correct ingestor by file extension
DropMissingValuesStrategyβ drops rows/columns based on axis and thresholdFillMissingValuesStrategyβ fills with mean, median, mode, or a constant value
ZScoreOutlierDetectionβ flags values where |z-score| exceeds threshold (default: 3)IQROutlierDetectionβ flags values outside Q1 β 1.5ΓIQR to Q3 + 1.5ΓIQROutlierDetectorβ supports remove or cap handling (pipeline default: cap at 1st/99th percentile, preserving all rows), plus boxplot visualization
LogTransformationβ applieslog(1+x)to reduce skewnessStandardScalingβ standardizes to mean=0, std=1MinMaxScalingβ rescales to [0, 1] or custom rangeOneHotEncodingβ converts categorical features to binary vectors
SimpleTrainTestSplitβ sklearn'strain_test_splitwith configurable test size and random state; the ZenML step selects numeric features only before splitting
LinearRegressionStrategyβ builds an sklearnPipelinewithStandardScalerβLinearRegression
RegressionModelEvaluationStrategyβ computes Mean Squared Error (MSE) and RΒ² Score
| 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 |
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 modelprices_predictorcontinuous_deployment_pipeline(deployment_pipeline.py) β runsml_pipeline, then (re)deploys the trained model using ZenML's built-inmlflow_model_deployer_stepinference_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
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# 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# 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 --localjupyter notebook analysis/EDA.ipynbWindows 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.
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 |
| 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 |
This project is licensed under the Apache License 2.0 β see the LICENSE file for details.