Skip to content

sonianayak66/sales-forecasting-ml

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sales Forecasting using Machine Learning

Python 3.9+ scikit-learn XGBoost License: MIT

A comparative study of Linear Regression, Random Forest, and XGBoost on the Rossmann Store Sales dataset — daily sales for 1,115 German drugstores over 2.5 years (Jan 2013 – Jul 2015, ~1M transactions). The tuned XGBoost achieves a 6-week-ahead test-set R² of 0.89 (vs 0.26 for the linear baseline), with time-series cross-validation confirming the result holds across chronological folds.

Monthly sales trend across 1,115 stores (2013–2015)

Headline results

Test set: last 6 weeks of available data (chronologically held out, not random).

Model MAE (€) RMSE (€) R² (test) R² (train)
Linear Regression (baseline) 1,953.82 2,632.51 0.2573 0.2174
Random Forest (default) 718.51 1,044.50 0.8831 0.9875
Random Forest (tuned) 714.91 1,038.23 0.8845 0.9882
XGBoost (default) 981.99 1,339.32 0.8078 0.8632
XGBoost (tuned) 702.53 1,016.45 0.8893 0.9634

Model comparison — MAE / RMSE / R²

5-fold time-series cross-validation (TimeSeriesSplit, not random KFold) on a 200K-row sample:

Model R² (mean ± sd) RMSE (mean ± sd)
Linear Regression 0.2165 ± 0.0059 €2,750.66 ± €14.19
XGBoost (tuned) 0.9020 ± 0.0240 €965.30 ± €109.63

What's interesting in the model

Top 15 feature importances from tuned XGBoost

  • StoreType_b is the single most important feature (~27%). Type-B stores have a categorically different sales profile from the rest — visible directly in the EDA, where their average daily sales dwarf the other types.
  • Promo is #2 (~12%). A simple binary flag, but EDA shows it roughly doubles mean daily sales when active.
  • CompetitionDistance and Promo2 matter — both modulate baseline sales materially.
  • The Linear Regression baseline is fundamentally inadequate (R² ≈ 0.26). Sales effects in this domain are non-linear and interaction-heavy: the impact of a promotion depends on store type, day of week, holiday status, etc. A tree ensemble is the right tool.

Why this dataset / what makes the project credible

  • True time-series forecasting, not transaction-level regression: the test set is 6 weeks of future days the model has never seen — the realistic setting for actual deployment.
  • Three-model benchmarking (LR / RF / XGBoost) with hyperparameter tuning on the two tree models.
  • Time-series cross-validation rather than random KFold — random splits leak future information into training and inflate scores; we don't do that.
  • Customers excluded as a feature to avoid target leakage (in the real Rossmann competition, customer count is also a target).

Project structure

.
├── Sales_Forecasting_ML.ipynb     # Main notebook — open this
├── train.csv, store.csv           # Auto-downloaded via Kaggle API (not in git)
├── images/                        # Generated plots used in this README
├── rossmann_xgb_tuned.joblib      # Saved best model (regenerated by notebook; not in git)
├── requirements.txt               # Python dependencies
├── project_report.md              # Final project report
├── LICENSE                        # MIT License
└── README.md                      # This file

Setup

1. Install dependencies

pip install -r requirements.txt

2. Configure the Kaggle API (one-time)

The notebook auto-downloads the dataset using the Kaggle API. To enable this:

  1. Go to https://www.kaggle.com/settings/api
  2. Click Create New Token — provide any name (e.g., "laptop")
  3. Copy the token shown
  4. Save it to one of:
    • Linux / macOS: ~/.kaggle/access_token
    • Windows: C:\Users\<YourUser>\.kaggle\access_token
  5. Accept the competition rules at https://www.kaggle.com/c/rossmann-store-sales/rules

3. Run the notebook

jupyter notebook Sales_Forecasting_ML.ipynb

Then Cell → Run All. The notebook will auto-download the data on the first run.

Expected runtime

Step Time on a modern laptop
Data loading & EDA < 1 min
Linear Regression ~ 5 sec
Random Forest (default, 50 trees) ~ 30 sec
RF GridSearchCV (12 combos × 3 folds, 200K-row sample) 4–6 min
RF refit on full data ~ 1 min
XGBoost (default + GridSearchCV + refit) ~ 90 sec
Time-series 5-fold CV ~ 1 min
Total **~ 9–12 min**

Tools & technologies

Python 3.9+ · pandas · numpy · scikit-learn · xgboost · matplotlib · seaborn · joblib · Jupyter Notebook

Project history

This project was originally implemented on the Superstore Sales Dataset. That earlier version is preserved as a tagged release: v1.0-superstore. The current main branch uses the Rossmann dataset, which is a true time-series forecasting problem with richer auxiliary features (promotions, holidays, competitor data) — a better fit for both the project name and the task.

License

MIT — submitted as an internship project deliverable, free for educational reuse.

About

End-to-end ML pipeline forecasting daily retail sales on the Rossmann Store Sales dataset (1M records, 1,115 stores). Compares Linear Regression, Random Forest, and XGBoost with time-series cross-validation. Tuned XGBoost achieves R² = 0.89 on a 6-week-ahead test window.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors