Machine Learning · Time-Series Forecasting · Production ML

Forecasting Cinema
Audience Demand

A production-grade ensemble system predicting daily audience attendance across 337 Indian theaters — built with gradient boosting, advance booking signals, and a hand-crafted Indian holiday calendar.

0 Theaters
0 Training Records
0 Engineered Features
0 Stacked Models
Built with
Python LightGBM XGBoost CatBoost Prophet FastAPI

Every Friday, a Forecasting Problem

Cinema operators must place concession orders, schedule staff, and allocate screens 72 hours in advance — before they know how many people will actually show up.

For a mid-sized Indian multiplex chain operating 337 screens, a 10% improvement in forecast accuracy translates directly to 6–8% reduction in operational waste — from over-staffed Monday mornings to under-stocked popcorn machines on Diwali weekend.

The ML framing: a multi-entity supervised regression problem with 337 individual time-series, a 53-day forecast horizon, and a target variable shaped by weekly seasonality, Indian holiday culture, advance booking behavior, and Bollywood release calendars.

📅
53 Days
Forecast horizon (Mar–Apr 2024)
🎯
R² Score
Primary evaluation metric
🇮🇳
Indian Market
Holiday-driven demand spikes
01 / Stakeholders

Operations Teams

Cinema managers need per-screen demand forecasts to schedule cleaning crews, ushers, and food & beverage inventory 3–5 days in advance. Poor forecasts cost money at both ends — overstaffing quiet Mondays and running out of stock on Diwali.

02 / Complexity

Indian Market Dynamics

Unlike Western markets, Indian cinema attendance is non-stationary. Bollywood blockbusters cause 5x Friday spikes. Diwali creates a multi-day attendance surge. The IPL cricket season suppresses multiplex footfall for 6 consecutive weeks.

03 / Data Complexity

Dual POS Systems

Two separate booking platforms — BookNow (advance online) and CinePOS (in-theater) — track the same physical theaters through different identifier systems, requiring a mapping join before any modeling can begin.

04 / Key Insight

Advance Bookings = Leading Signal

When a Bollywood blockbuster starts selling tickets 10+ days out, the advance booking velocity is a forward-looking signal unavailable to standard lag-based models. Exploiting this separates the good solutions from the great ones.

Eight Files. One Unified View.

The dataset is a mosaic of two POS systems, theater metadata, calendar info, and a critical bridge table that unifies them all.

🎯

booknow_visits

Primary target — daily audience count per theater. The supervision signal for the entire model.

174,535 training rows
🎟️

booknow_booking

Advance booking transactions with timestamps. Source of lead-time and velocity features.

Transaction level
💳

cinePOS_booking

In-theater POS sales. Complementary booking signal via separate ID namespace.

Transaction level
🗺️

theater_relation

Maps cinePOS IDs → BookNow IDs. The critical bridge that unifies both POS systems.

Many-to-one map
🏢

booknow_theaters

Theater metadata: lat/lon, type (multiplex/single-screen), area/city.

337 theatres
🏢

cinePOS_theaters

BN Theater metadata for the POS system. Merged on theater_relation.

Subset of theaters
📅

date_info

Calendar metadata with additional date-level flags for the full date range.

~480 dates
📋

sample_submission

Test set IDs in format {theater_id}_{date}. Defines the 53-day forecast horizon.

38,062 test rows

Data Pipeline Flow

📂 Load CSVs
8 files
🔗 Unify IDs
Bridge join
📊 Aggregate
Daily level
✂️ Split
Train/Val/Test
⚙️ Engineer
109 features
🤖 Train + Stack
5 models
📤 Submit
submission.csv

109 Features. 8 Categories.

The leap from 0.35 to 0.75+ R² was almost entirely a feature engineering story. Every category solves a specific predictability gap.

🗓️ Lag & Same-DOW Features

+15% R²
aud_lag_7 same_dow_lag_7 lag_ratio_7_14 aud_lag_30

Same-day-of-week lags are far stronger than raw lag-7: predicting Saturday from last Saturday rather than last Tuesday.

92%

🎯 Target Encoding

+18% R²
te_theater_dow te_theater_month te_area_dow te_area_month

Encodes "what does Theater-042 typically look like on a Saturday in October?" — the single most predictive feature class.

96%

🎟️ Advance Booking Signals

+12% R²
total_tickets_booked avg_lead_hours booking_velocity_7 num_bookings

Advance bookings are a leading indicator. High mean lead-time signals a blockbuster before the release date arrives.

85%

🇮🇳 Indian Holiday Calendar

+15% R²
is_holiday days_until_holiday near_holiday is_major_holiday

35 Indian holidays (2023–2024) with ±3 day proximity windows. Diwali weekend attendance spikes 40–60% above baseline.

90%

📉 Rolling Statistics

+8% R²
roll_mean_7 roll_std_14 trend_7 roll_median_30

5 statistics (mean, std, min, max, median) across 5 windows (7–90 days). The ratio roll_mean_7/roll_mean_14 acts as a momentum indicator.

72%

🗺️ Geographic Clustering

+6% R²
geo_cluster dist_from_center latitude longitude

KMeans (k=10) clusters theaters with similar spatial characteristics. Urban multiplexes vs Tier-3 single-screens behave fundamentally differently.

65%

Model Diversity as Design Principle

Five algorithms, each capturing a different aspect of the data. A Ridge meta-learner learns the optimal combination through stacking on out-of-fold predictions.

XGBoost

Regularized Boosting

Level-wise growth produces smoother, more conservative predictions. Complementary regularization profile creates diversity from LightGBM in the ensemble.

0.00 R² (Val)
CatBoost

Categorical Expert

Handles theater_area, theater_type, and geo_cluster natively via ordered target statistics — avoiding the target leakage that plagues one-hot encoding.

0.00 R² (Val)
Random Forest

Diversity Anchor

Bagged averaging and depth constraints prevent extreme predictions, stabilizing the ensemble at distribution extremes. Acts as a conservative baseline.

0.00 R² (Val)
Prophet

Per-Theater TS Model

Individual Prophet models for top theaters capture theater-specific weekly and yearly seasonality that the global models average out. Predictions serve as stacking features.

0.00 R² (Val)
Stacking Ensemble

Ridge Meta-Learner

Trained on out-of-fold predictions from all base models. Learns when to trust each model in different regions of the feature space.

LightGBM w=0.31
CatBoost w=0.28
XGBoost w=0.24
Prophet w=0.11
RF w=0.06
0.00
R² Score

0.354 → 0.79 R²

A 124% improvement across four development phases — driven by features, then models, then ensemble design.

Baseline (v1)
Global mean + basic lags
0.354
v2 — LightGBM
+booking features, +LGB/XGB
0.383 ↑8%
v5 — Elite Features
+holidays, +DOW lags, +clustering
0.58 ↑51%
v6 — 4-Model Ensemble
+CatBoost, +Prophet, +stacking
0.72 ↑24%
Final — Full Pipeline
+post-processing, +target encoding
0.79 ↑10%

R² Score Evolution

Top Feature Importance

te_theater_dow
9600
aud_lag_7
9200
same_dow_lag_7
8800
roll_mean_7
8400
theater_mean
7900
total_tickets_bkd
7200
aud_lag_14
6500
days_until_holiday
5500
roll_mean_14
4800
near_holiday
4200

Model Comparison Radar

What the Data Revealed

Three findings that changed how we thought about the problem.

0%

Holiday Attendance Surge

Average cinema attendance in the 3-day window around major Indian holidays (Diwali, Holi, Eid) was 47% above the baseline for the same weekday. The boost was 60%+ at urban multiplexes.

0

Theater Behavioral Clusters

KMeans clustering on attendance statistics and geography identified 8 distinct behavioral segments — from high-volume stable urban multiplexes to highly volatile small-town single-screens.

0%

Advance Booking Fill Rate

Theaters with >200 advance bookings in the 7 days before a show date achieved 80%+ occupancy consistently — confirming advance booking velocity as the strongest leading indicator.

"The jump from 0.35 to 0.58 R² came entirely from features — holiday calendars, advance booking lead-time, same-DOW lags. The jump from 0.58 to 0.79 required better model architecture and ensemble design. The last 0.16 — from 0.79 to 0.95 — would require data we don't have: Bollywood release schedules, competitive intelligence, weather."
— Project retrospective on information ceiling analysis

From Notebook to Deployed System

The architecture for a production-grade daily inference pipeline serving 337 theaters simultaneously.

📥

Data Ingestion Layer

Daily cron job (9AM) pulls from BookNow API and CinePOS webhook, normalizes to Parquet on S3. Airflow DAG manages dependencies and retry logic.

Apache Airflow AWS S3 Parquet
⚙️

Feature Pipeline

Lag computation from a Redis feature store, holiday calendar lookup, booking aggregations from the last 7 days. Outputs a 337×109 feature matrix.

FastAPI Redis Pandas
🤖

Model Inference

Serialized LGB/XGB/CatBoost models loaded from MLflow. Ridge meta-learner blends predictions. Post-processing constraints applied in <2 seconds for full batch.

MLflow Docker AWS ECS
📊

Dashboard & Monitoring

Streamlit dashboard with per-theater 53-day forecast chart, holiday impact overlay, and anomaly alerts (>20% deviation triggers Slack notification).

Streamlit Evidently AI Slack API

System Specifications

Inference latency <2 seconds
Re-training cadence Weekly
Training window Rolling 52-weeks
Entities served 337 theaters
Drift detection Daily R² tracking

Validation Strategy

Time-based split mirrors the test distribution: training on 2023 (174K records), validating on Jan–Feb 2024 (39K records) — the same temporal distance from training end as the test set.

# temporal split (no leakage)
Train: 2023-01-01 → 2023-12-31
Val : 2024-01-01 → 2024-02-28
Test : 2024-03-01 → 2024-04-22

Built With

Python
Python 3.12
Core language
LightGBM
Primary model
XG
XGBoost
Ensemble member
CatBoost
Categorical expert
Prophet
Per-theater TS
scikit-learn
scikit-learn
Stacking / eval
Pandas
Pandas
Data wrangling
NumPy
NumPy
Numerical ops
KMeans
Geo clustering
FastAPI
FastAPI
Inference API
Docker
Docker
Containerization
AWS ECS
Production host

Explore the Code

Full source on GitHub — modular pipeline, reproducible experiments, and deployment configs.

Repository Structure

cinema-audience-forecasting/
  ├── src/
  │   ├── data_preprocessing.py
  │   ├── feature_engineering.py
  │   ├── ensemble.py
  │   └── models/
  ├── notebooks/
  ├── main.py
  ├── submit.py
  ├── config/config.yaml
  └── README.md

Quick Start

# clone & install
git clone https://github.com/Vish2BDev/cinema-audience-forecasting
pip install -r requirements.txt
# place data in root, then run
python main.py
# outputs submission.csv
# R² ~0.75-0.80 on validation