Pharmacy Drug Sales Forecasting

Pharmacy Drug Sales Forecasting

Role: Lead (solo) | Duration: Spring 2026 | Focus: Time Series Forecasting, Feature Engineering, Pharmaceutical Demand Analytics

This project tackled demand forecasting for R03 (drugs for obstructive airway diseases), using the Wellness Pharmacy Sales Analysis dataset from Kaggle, six years (2014–2019) of daily sales across 57 drugs grouped into 8 ATC categories. The starting hypothesis was that R03 sales are seasonal, peaking in respiratory illness season. Exploratory analysis confirmed and refined this: sales spike from November through February, stay moderate through March–April, then decline sharply from May through July. Along the way, the EDA surfaced real data quality issues that shaped everything downstream; 26 undocumented pharmacy closure days, 484 zero-sale days for R03 (a genuine feature of intermittent demand, not missing data), and 84 missing days concentrated at the end of 2019 that required historical-average imputation.

The feature engineering phase went through several iterations. An early linear regression attempt collapsed to an R² of ‑0.94 due to perfect multicollinearity from one-hot-encoded season columns and redundant month/season features; a useful failure that led to a full rebuild with multiple lag windows (1, 7, 14, 28, 52), rolling statistics, cyclical time encoding, and interaction terms. Nine model families were trained and compared: Linear Regression, Random Forest, Gradient Boosting, XGBoost, LightGBM, Prophet, an ensemble of Prophet + LightGBM, Elastic Net, and SARIMA, each evaluated with a chronological train/validation/test split to avoid data leakage.

Rather than relying on standard ML metrics alone, I built a pharmaceutical-specific evaluation framework: WAPE (28%), Forecast Bias (22%), RMSE (18%), MASE (12%), MAE (12%), MedAE (5%), and R² (3%); weighted this way because a model that underpredicts winter demand risks patient stockouts, while overpredicting just wastes shelf space. This framing exposed a critical finding standard metrics missed: Gradient Boosting looked competitive on RMSE but carried a ‑33.57% forecast bias, meaning it was systematically underpredicting demand by a third, a serious stockout risk during peak respiratory season that a generic accuracy score would have hidden.

After hyperparameter tuning (Optuna for tree models, grid search for Prophet, Ridge for the linear baseline) and a final test-set evaluation across 13 models, the simplest model won: log-transformed, scaled Linear Regression outperformed every tree-based ensemble. The reason came down to extrapolation, tree models cap their predictions at the highest leaf value seen in training, and the test years (2018–2019) had a 48% higher mean demand than the training years. Linear regression's hyperplane has no such ceiling, so it scaled naturally with the distribution shift while every tree model hit an artificial cliff. It was a clean demonstration that model sophistication isn't the same as model fitness for the data at hand.

Skills Demonstrated: Python (Pandas, NumPy, scikit-learn, XGBoost, LightGBM, Prophet, Optuna, statsmodels), time series analysis and decomposition, feature engineering, custom evaluation frameworks, hyperparameter tuning (Bayesian optimization and grid search), model interpretability (SHAP, feature importance), handling distribution shift, and domain-specific metric design for pharmaceutical forecasting.

Details of the entire project and the final report can be found here: Google Drive

Category: masters portfolio

Posted by Ruth Selorme on August 23, 2026

6 eye svg

0 thumbs up svg

Comments