# 104. Hotel cancellation decision system

**Owner: Djellon Pllana.** Independently built portfolio case study using historical public observations. No employment by, or partnership with, the source organizations is claimed.

## Business question

Can a revenue team rank cancellation risk using conservative booking information, and how should it judge a proposed follow-up policy?

## Executive result

Logistic regression wins on validation log loss. On 19,986 future booking snapshots, test AUC is 0.669; the fixed review threshold flags 13.0% of bookings and captures 18.0% of recorded cancellations.

The conservative feature set produces modest discrimination. Final-snapshot predictors and the arrival-bounded extract prevent a claim of deployment-ready booking-time performance.

![Computed analysis](outputs/chart.png)

## Scope and architecture

119,390 original observations. Original files → hashed source manifest → typed transformations and SQL marts → chronological experiments → executed notebook → aggregate interactive dashboard.

1. Read H1 and H2 CSVs from the original article supplement; strip padding and validate targets.
2. Derive booking date as arrival minus lead time; require training labels known at the cutoff.
3. Compare candidate probability models using validation log loss, then freeze the selected model.
4. Evaluate January–April 2017 bookings and retain a validation-derived review threshold.
5. Aggregate additive outcome and probability counts for filters and scenario calculations.

## Data contract

One row is a booking snapshot. Two properties are labeled Resort and City. Training bookings and outcomes must both precede July 2016; validation bookings run July–September 2016 with outcomes known before January 2017. Test bookings run January–April 2017. The arrival-bounded extract does not represent all bookings created in those periods. Status date is used only to establish historical label maturity, never as a model input. Channel labels are observational and do not imply causal effects.

## Model and evaluation

Target: published cancellation flag. Conservative inputs: lead time, arrival month and weekday, planned weekday/weekend nights, party counts, hotel, meal, market segment, distribution channel and reserved room. Excluded: final reservation status/date, assigned room, booking changes, deposit, ADR, nationality and evolving requests. Models: training prevalence, regularized logistic regression, two fixed boosted-tree configurations. Select by validation log loss; do not tune on test performance. The review threshold is the 90th percentile of validation scores, so actual test workload can differ from 10%. Scores support a research prioritization exercise; feature availability is not proven for live booking time.

See [evaluation.json](outputs/evaluation.json), [results.csv](outputs/results.csv) and [quality.json](outputs/quality.json). Test observations are not used to choose configurations. Results are from the current historical evaluation; additional tuning requires a new evaluation period.

## Recommended next decision

Use the dashboard to compare risk and review workload by hotel and channel. Before operational use, obtain versioned booking events and run a randomized follow-up trial to estimate actual cancellation prevention and contribution margin.

## Limitations

The source is a final snapshot, not an event log. Even conservative fields may have changed after booking. Only two hotels and arrivals through August 2017 are represented, censoring later-arriving bookings. Customer identity is absent, so guest-separated evaluation is impossible. Identical records may represent groups and are retained. Scenario effects and euro amounts are assumptions, not measured savings.

## Reproduce

From the full project-collection root, use Python 3.12 and install `capstones/requirements.txt`. Run `python projects/104-hotel-cancellation-decision-system/analysis.py` or execute this project's notebook. Raw files are fetched from the original publisher, hashed and cached in `data/raw/capstones`. The full NYC run reads over 200 MB of compressed source data and needs several GB of working memory and disk. The website carries aggregated results rather than raw trip logs or trained model binaries.

The project Python file exposes the full study code. Shared helpers live in `capstones/common.py`; source downloads are declared in `capstones/fetch.py`; the native NYC Power BI companion is generated with `python -m capstones.bi`.

## Source and attribution

[Hotel booking demand datasets](https://doi.org/10.1016/j.dib.2018.11.126) — Nuno António, Ana de Almeida and Luís Nunes (2019). [Reuse information](https://creativecommons.org/licenses/by/4.0/). Data were transformed and aggregated for this study; see `data/source_manifest.json` for exact source files and hashes.
