A Kaggle competition entry for Store Sales — Time Series Forecasting, using grocery sales data from a major Ecuadorian retailer. Five data sources (sales, transactions, oil prices, holidays, and store metadata) are loaded, cleaned, and explored. The EDA investigates seasonality in both oil prices and transaction volumes using seasonal plots and periodograms before merging everything into a modeling dataset. The forecasting model is a Linear Regression baseline trained on product family and date features.
Predict 15 days of future sales across 54 stores and 33 product families for an Ecuadorian grocery chain — a large-scale multi-series forecasting problem where external signals (oil prices, national holidays) are known to influence sales patterns in an oil-dependent economy.
Five datasets joined and explored independently before modeling:
holiday feature.scipy.signal.periodogram) to identify dominant frequency components.Feature engineering for modeling:
holiday flag (binary, from cleaned holidays table).dcoilwtico (daily oil price, joined on date, back-filled for missing days).year, month, monthday, weekday.Preprocessing pipeline — A scikit-learn Pipeline with SimpleImputer → OneHotEncoder on the family column (33 product categories). All other features were dropped via remainder='drop', making family the sole categorical predictor in the final model.
Model — Linear Regression trained on the OHE-encoded family features, retrained on the full training set before generating test predictions.
The Linear Regression model established a MAE baseline on the validation set. The model captures average sales levels per product family but cannot model temporal dynamics or cross-feature interactions — by design, as a competition entry baseline. The periodogram analysis of oil prices showed no strong dominant frequency, confirming that oil price variation is largely trend-driven rather than seasonal. Transactions showed a clear weekly seasonality pattern, with lower volumes on weekends — visible in both the seasonal plot and periodogram peaks at 52 cycles/year (weekly frequency).
This project is an honest baseline — and the write-up treats it as such. The most instructive part isn’t the model but the EDA infrastructure: the reusable seasonality() function that combines grouped aggregation, seasonal line plots, and a log-scale periodogram into a single call is a pattern worth carrying forward. Applying it to both oil prices and transactions before touching the sales data revealed that these two external series have fundamentally different temporal structures — oil is trend-dominated, transactions are seasonality-dominated — which informs what features a stronger model would need. The decision to remainder='drop' in the ColumnTransformer rather than pass numeric features through was the main limitation of the final model; including oil price, holiday flag, and date decomposition features alongside the OHE family columns would be the first improvement in a next iteration.