Skip to main content

Solutions · Finance

Data Science Regression

Predict a film's box office from its production data

Estimate worldwide revenue for a film that does not exist yet — from budget, runtime, language, director and the cast/company/genre graph around it. A worked example of a relational model on 9 linked tables, and an honest account of how much of the signal is just budget.

Data Science Langsat Team 10 min read
5,454
Films across 9 linked tables
0.6347
Rank correlation — the metric a slate decision uses
14×
Revenue gap between disclosed and undisclosed budgets

The problem

For a movie that does not exist in the database yet, predict `revenue` — worldwide box office in dollars — from its production characteristics: budget, runtime, original language, director and title, plus the graph of production companies, countries, genres and billed cast around it. The output is a dollar estimate for a film described inline at request time, so a slate can be ranked before anything is committed.

See the model in action

The trained relational model. Every film is scored from its own row plus the company, country, genre and cast rows connected to it.

Live model — predicted worldwide revenue

Trained on Langsat

Open in Langsat ↗

Ask a question in plain English

You ask

“How does revenue divide between films that disclose a budget and films that don't?”

Budget disclosedFilmsMedian revenue
Yes4,604$58,500,000
No850$4,100,000

A 14× gap. This is why `budget_was_missing` came out as the model's single most important feature — whether a production discloses its budget is itself one of the strongest signals in the dataset, before any number in that field is read.

What this model is for

A studio’s hardest question arrives before anything exists: given this budget, this director, this cast and this genre — what does it make?

That question has an awkward shape for machine learning. The film has no row in any table. It has no history to look up. What it does have is a neighbourhood — the companies attached to it, the country producing it, the genres it sits in, the people billed on it — and those things do have history.

This model scores exactly that: a film described inline at request time, connected to real rows that already exist.

The data

TMDB relational schema: a movie table linked through movie_company, movie_country, movie_genre and movie_person to company, country, genre and person tables

Nine tables, 5,454 films. The movie table holds title, release date, budget, runtime, original language, revenue and director. Four link tables join it to companies (19,953 links), countries (8,215), genres (15,144) and people (27,232 billed credits).

Nothing here is pre-joined. The model reads the foreign keys and learns across the graph — which is the part that would otherwise be weeks of feature engineering: how much does this production company usually gross, in this genre, in this country?

What each input means

ColumnWhat it isWhy it matters
budgetProduction budget in USD, 0 when undisclosedThe single strongest numeric signal. 15.6% of films report 0
runtimeLength in minutesWeak on its own (19.1%); separates features from shorts and TV cuts
original_languageISO code — en, ja, frA large effect. Identical inputs at en predict ~3.3× what ja does, mostly a proxy for distribution reach
directorName, free textSecond-highest importance (39.5%). Unseen names still work, they just carry no history
titleFree textSmall (3.7%). Read as text, so it picks up franchise-like naming
movie_person.billing_orderCast billing position, 0 = leadThe inline related row. This is what the message passing runs over

1. Why this is worth solving

Box office is famously unpredictable, and that reputation is deserved: revenue in this dataset spans $1.5M at the 10th percentile to $995M at the 99th, with a maximum of $2.92B. Three orders of magnitude.

But “unpredictable” is not the same as “structureless”. The median film returns 2.55× its budget, and the distribution has a shape worth knowing before committing capital.

The clearest structure is one nobody would think to engineer by hand:

Budget disclosedFilmsMedian revenue
Yes4,604$58,500,000
No850$4,100,000

A 14× gap, and the model found it — budget_was_missing is its single highest-importance feature. Whether a production discloses its budget separates the dataset before any dollar figure is read.

The useful output of a revenue model is not a number you underwrite. It is an ordering you argue about.

2. How good is it, honestly

The trained model reports R² 0.3154, MAE $63,685,368 — against a median-constant baseline of $82,036,256 — RMSE $174,654,749, and rank correlation 0.6347.

Those need context, so we built the obvious competitor: a linear regression on budget alone, evaluated across 20 held-out 80/20 splits.

Budget aloneThis model
0.4920 ±0.0390.3154
Rank correlation0.7212 ±0.0190.6347
MAE$74,817,522 ±$2.4M$63,685,368

Read that honestly: most of the predictable part of box office is budget. A one-column regression ranks a slate slightly better than a nine-table relational model does.

What the relational model buys is precision on the dollar figure — about 15% lower absolute error — and coverage of the 850 films where a budget-only rule has nothing to work with.

Two caveats on that comparison. The baseline is fitted to minimise squared error, which is what R² measures, so it is flattered on that row specifically. And the two are evaluated on different splits — ours on all 5,454 rows, the model’s on its own holdout — so treat the direction as solid and the exact gaps as approximate.

3. What the model actually does with budget

Sweeping budget across a 300× range on an otherwise identical film:

BudgetPredicted revenueMultiple
$1,000,000$9,413,5719.41×
$10,000,000$15,056,0491.51×
$50,000,000$81,175,3411.62×
$150,000,000$443,365,3032.96×
$300,000,000$599,819,4492.00×

The multiples land near the dataset’s own median of 2.55×, and the predictions span a 64× range across a 300× budget range. That is a model producing plausible magnitudes rather than hedging toward the average — the failure mode that makes a revenue estimate useless for planning.

It is not linear, and it shouldn’t be: the $1M film predicted at 9.4× reflects that micro-budget films genuinely post the highest return multiples, while the $300M film flattening to 2.0× reflects that the market has a ceiling.

4. Try it

The panel below describes a film that does not exist and scores it. Things worth trying:

  • Change only the language. enja on identical inputs moves the estimate several-fold. That is the model reading distribution reach, not quality.
  • Push the budget to $300M. Watch the multiple compress toward 2×.
  • Use a director the data has never seen. It still returns an estimate — it just has no history to draw on, which is the honest behaviour for a cold start.

Try it yourself

Every trained model gets a REST endpoint. Describe a film that doesn't exist yet and run a real prediction.

Try the model

Describe a film that doesn't exist yet and run a real prediction.

live model

Film

Result

recorded

predicted worldwide revenue

443365303.00

prediction
443365303
task_type
regression
mode
inductive
version_label
v1

A real response recorded on 2026-09-03 for a film described inline — no row for it exists in the database. $443M against a $150M budget is a 2.96× multiple; the median film in this dataset returns 2.55×. The model ID is redacted; the demo proxy resolves it server-side.

FAQ

Frequently asked questions

How accurate is it, really?

It ranks better than it prices. Rank correlation is 0.6347, which is a usable ordering signal for a slate. But mean absolute error is $63.7M, and the median film in this dataset earns $43.3M — so the average miss is larger than a typical film's entire gross. Use it to sort candidates, not to underwrite one.

Does it beat a simple baseline?

Partly, and the honest answer is worth more than the flattering one. We fitted a linear regression on budget alone and evaluated it across 20 held-out 80/20 splits: R² 0.4920, rank correlation 0.7212, MAE $74.8M. Against that, the relational model wins on MAE by $11.1M (about 15% lower error) and loses on both R² and rank correlation. Most of the predictable part of box office is budget; the graph adds precision to the dollar estimate rather than a better ordering.

Then why use a relational model at all?

Two reasons visible in these numbers. It produces lower absolute error, which matters when the output is a dollar figure someone plans against. And it handles the 850 films with no disclosed budget, where a budget-only rule has nothing to work with — that is exactly the gap `budget_was_missing` fills. If your only question is 'rank this slate', ranking by budget is a strong, nearly free baseline and you should measure against it before building anything.

Why is `budget_was_missing` the top feature?

Because non-disclosure is informative. Films that report no budget earn a median $4.1M; films that report one earn a median $58.5M — a 14× gap across 5,454 titles. The flag captures that split before any budget value is read. One caveat: the serving path derives this flag from the budget you send, so it is not a control you can set independently, and its 100% importance is measured on training data where 15.6% of films genuinely lacked a budget.

The goal mentions release date and genre. Are those in the model?

Genre is, through the graph — `genre` and `movie_genre` are two of the nine tables, and the model reads them via message passing. Release date is NOT a feature of this build: the movie entity carries title, budget, runtime, director, original language and the derived budget flag. `release_date` exists in the data and could be added, but nothing on this page reflects it.

What does 'new entity + inline data' mean?

The film you are predicting has no row in the database. You describe it in the request, and you also supply the related rows it would connect to — here, one billed cast slot. The model then runs message passing over that inline neighbourhood. This is the mode that matters for a green-light decision, because the whole point is scoring something that does not exist yet.

What data does it need?

The nine tables in the schema above: movie, company, country, genre, person, and the four link tables joining them. You don't pre-join or flatten them — Langsat reads the foreign keys and learns across the graph directly. This build used a 5,454-film TMDB extract.

Can I trust it for an actual investment decision?

No, and nothing here should be read that way. This is a public TMDB extract with a $63.7M mean absolute error, no marketing spend, no release-window or competitive data, no star-salary or distribution terms, and no validation on any studio's real slate. It is a demonstration of relational learning on a public dataset. Treat it as a method you could apply to your own data, not as a number to commit capital against.

Build this on your own data

Point Langsat at your data, pick the task, and train a real model — no feature engineering, no infrastructure to run. Your data stays private: isolated to your account and encrypted in transit and at rest.