Predicting appointment no-shows¶
Pringle Analytics
Every empty chair is lost revenue. This dental practice cancels or misses about 1 in 8 of its booked appointments. The front desk cannot phone everyone to confirm, so the useful question is simple: which of the upcoming appointments are most likely to fall through?
This notebook shows how the model answers that. It walks through the data, how we define a no-show, how well the model does, and what it is worth in dollars. Everything runs on de-identified data (fake names, birth-year-only ages, no contact details), so no patient information appears anywhere in this notebook or its charts.
0. Setup¶
Connect to the database and load the model code.
Connected. Model code: C:\Users\serge\Documents\Workfiles\Projects\curve-data\curve-analytics\ml\appt_risk\train.py
Ready.
1. The problem¶
No-shows and late cancellations are a steady part of the schedule, usually between 8 and 19 percent of appointments each month. Each one is a chair that was reserved and staffed but earned nothing. Priced at a conservative $250 per appointment, here is what that costs, month by month.
No-show / cancellation rate: 12.4% of 7,251 resolved appointments. Revenue lost in the last 12 months, at $250 each: $124,000.
2. The data¶
The model works from one table with a single row per appointment. Each appointment is described only by facts that are already known when it is booked, so the model never sees anything from the future. The facts fall into four groups.
| Group | Examples |
|---|---|
| Booking | how far ahead it was booked, day of week, hour, length |
| Patient | age, gender, brand new or returning |
| History (before this visit) | past visits, past no-shows, past no-show rate, days since last visit |
| Money | outstanding balance the patient carries in |
The "already known when booked" rule matters. A fact that quietly reflects the outcome would make the model look excellent in testing and fail in real use, so we take care to keep those out.
7,433 appointments, 17 facts each, all de-identified.
| lead_days | appt_dow | appt_hour | length_minutes | age_at_appt | is_new_patient | prior_appts | prior_failed | prior_failed_rate | days_since_last_visit | ar_balance_at_appt | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 3.0 | 1.0 | 11.0 | 75.0 | 67.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 1 | 3.0 | 1.0 | 10.0 | 60.0 | 67.0 | 1.0 | 0.0 | 0.0 | NaN | NaN | 0.0 |
| 2 | 8.0 | 4.0 | 11.0 | 60.0 | 74.0 | 0.0 | 3.0 | 0.0 | NaN | NaN | 0.0 |
| 3 | 4.0 | 5.0 | 11.0 | 30.0 | NaN | 1.0 | 0.0 | 0.0 | NaN | NaN | 0.0 |
| 4 | 3.0 | 5.0 | 13.0 | 30.0 | 57.0 | 1.0 | 0.0 | 0.0 | NaN | NaN | 0.0 |
| 5 | 0.0 | 2.0 | 13.0 | 30.0 | 76.0 | 0.0 | 1.0 | 0.0 | 0.0 | 25.0 | 0.0 |
3. What counts as a no-show¶
Two outcomes are treated the same, because the result is identical, an empty chair.
- No-show (1). The appointment was cancelled or missed.
- Kept (0). The patient checked in or checked out.
Reschedules, deleted bookings, and appointments still in the future are set aside. That leaves a clean record of resolved appointments to learn from.
182 upcoming appointments have no outcome yet. Those are the ones we score.
4. How well it works¶
We learn from 2024 and 2025, then test on 2026, a year the model was not trained on. That mirrors real use: learn from the past, predict the future.
Plain accuracy is misleading here. Because only about 12 percent of appointments fail, a model that simply says "everyone will show up" is right about 88 percent of the time and yet catches zero no-shows. So we look at two numbers the front desk actually cares about, measured at a common operating point (flag the 20 percent of appointments each method ranks riskiest).
- No-shows caught (recall). Out of all the no-shows, how many did the method flag?
- Flags that were right (precision). When the method flags an appointment, how often does it fail?
Learned from 5,124 appointments (2024-2025), tested on 2,127 from 2026 (12% were no-shows). 'Everyone shows up' would be 88% accurate but catch 0 no-shows.
| Method | No-shows caught | Flags that were right | Overall accuracy |
|---|---|---|---|
| Past no-show rate | 25% | 15% | 74% |
| Basic statistical model | 40% | 24% | 78% |
| This model | 50% | 31% | 80% |
5. Can you trust the risk numbers?¶
The model does not just rank appointments, it puts a percentage on each one. Those percentages are only useful if they mean what they say. This chart checks that. For the appointments the model rated near 30 percent, did about 30 percent actually fail? The closer the dots sit to the straight line, the more the numbers can be read as real money at risk, not just a ranking.
6. Calling the riskiest chairs first¶
The front desk has limited time, so the real question is: if we can only call a fraction of the schedule, how many of the no-shows do we catch? Sort the appointments by risk, start at the top, and read up the curve.
Call the riskiest 10%: catch 30% of no-shows, about 3 times better than random. Call the riskiest 20%: catch 50% of no-shows.
7. What the model pays attention to¶
To see which facts matter most, we hide one fact at a time and measure how much worse the model gets. The two biggest drivers are how far ahead the appointment was booked and how long it has been since the patient last came in. These are the same things an experienced office manager would name.
8. The daily call list¶
For every upcoming appointment the model writes a risk score. Joined to the schedule, that is a ready-to-use list, sorted so the front desk starts with the riskiest chairs. Names are de-identified and shown as initials.
37 of the 182 upcoming appointments are high risk (30% or more).
| risk_pct | patient | date | mins | provider |
|---|---|---|---|---|
| 50% | W., Amy | 2026-08-03 | 60 | Provider 74 |
| 49% | F., Thomas | 2026-07-06 | 60 | Provider 74 |
| 46% | W., Lawrence | 2026-07-09 | 60 | Provider 74 |
| 46% | B., Carl | 2026-09-08 | 60 | Provider 74 |
| 44% | M., Dennis | 2026-07-23 | 60 | Provider 74 |
| 44% | H., Lawrence | 2026-08-12 | 60 | Provider 74 |
| 43% | M., Carol | 2026-08-05 | 60 | Provider 74 |
| 43% | C., Joe | 2026-08-05 | 60 | Provider 74 |
| 42% | P., Cynthia | 2027-02-02 | 30 | Provider 74 |
| 42% | S., John | 2026-09-21 | 60 | Provider 74 |
| 41% | P., Cynthia | 2027-02-03 | 30 | Provider 74 |
| 40% | B., Charles | 2026-07-31 | 60 | Provider 74 |
9. What it is worth¶
Risk scores matter only if they turn into dollars. At $250 per appointment, here is the money lost to no-shows over the last year, next to the share the practice could recover by working the model's riskiest 20 percent and saving even a third of those appointments with a reminder call.
Lost to no-shows in the last 12 months: $124,000. Recoverable by calling the riskiest 20% and saving 30% of them: $18,744 a year. Both figures adjust live at demo.pringleanalytics.com using the revenue and recovery sliders.
10. Summary¶
- The model flags which upcoming appointments are most likely to fall through, early enough to act.
- It is tested on a year it never saw, and its risk percentages match what really happens.
- Careful data work keeps out any column that would give away the answer.
- Every number here comes from de-identified data. Patient information never leaves the practice.
The payoff is simple. Calling the riskiest 10 percent of the schedule catches about a third of the no-shows, which tells a busy front desk exactly where to spend its time.
A live dashboard built on these same scores runs at demo.pringleanalytics.com.
Done.