← mariacybersec

Predicting Taxi-Out Time at 10 European Airports

PRC Data Challenge 2026: when the hardest part is knowing which numbers are real

Research question: can departure taxi-out time be predicted for months a model has never seen, when part of the data does not mean what it says?

The PRC Data Challenge 2026, organised by the OpenSky Network and EUROCONTROL's Performance Review Commission, asked teams to predict how long departing aircraft take from pushback to take-off at 10 major European airports: Amsterdam, Barcelona, Frankfurt, Istanbul, London Heathrow, Madrid, Munich, Paris CDG, Rome Fiumicino and Zurich.

I entered on my own, as team versatile-kitten. After more than ten years working in aviation, I know taxi time as the stretch of every flight between pushback and take-off. This was the first time I looked at it in the data.

The answer turned out to be more interesting than a prediction problem. A large part of the error did not come from taxiing at all, but from how the times were recorded.


1. The Challenge

The training data covered every movement at the 10 airports in 2025: about 4.2 million arrivals and departures, with schedules, flight-plan records, runways and stands. The target was the taxi-out time in seconds, and the score was RMSE (root mean square error), which punishes large mistakes much more than small ones.

Late in the competition, the organisers added a final phase: one single submission covering January, February, June and July 2026, ranked on Jan+Jul, Feb+Jun and all four months. February and June had no leaderboard feedback at all.

That shaped everything. The validation used the same four months of 2025 as a hold-out, so winter de-icing and summer peaks were tested the way they would be in the final.


2. Taxi Times That Are Not Taxi Times

The first baseline was an average per airport and hour: 654.99 s on the live leaderboard. A gradient-boosted model brought it to 432.98 s. Then the errors pointed somewhere unexpected.

At Rome Fiumicino, 82.9% of departures with a taxi time over one hour reported a taxi time equal to the scheduled delay. The aircraft had not taxied for hours. The off-block time had been recorded as the scheduled time, so the "taxi time" included the whole delay.

A model trained on those rows learns that taxi times can be hours long, and gets worse on normal flights. So the model became a mixture:

That one change took the four-month hold-out from 448.74 s to 395.09 s, and the live score to 384.90 s.

Live leaderboard score by version Live leaderboard score by version

3. Flights That Taxied for a Day

Sixteen 2025 departures had a taxi time over 80,000 s, more than 22 hours. Twelve of the fourteen that were not schedule artefacts were at Rome, and for every one of them the taxi time minus exactly one day was an ordinary 13 to 33 minute taxi.

The pattern only made sense once I looked at the clock: the flight was scheduled on one day and pushed back after midnight, and the off-block time was stored with the scheduled date. The data confirmed it:

Day errors
Rome departures that cross local midnight (scheduled one day, take-off the next) all 12
Rome departures that do not cross midnight (about 160,000) 0

Eleven cases are too few to learn from, so instead of a model I used a rule: in the risk group (Rome, no flight-plan record, delay over 4 hours, take-off after local midnight), 11 of 63 flights in 2025 were day errors, and the prediction is weighted by that measured rate.


4. Deciding Without Fooling Myself

With RMSE, a handful of rows can decide everything. In the hold-out, 10 rows with taxi times over 80,000 s dominated the variance of the whole score. The live leaderboard had the same problem: a single day-long taxi time can move a score by several seconds.

So I fixed a rule before looking at any result:

A change is kept only if the score on the other rows ("clean" rows) is clearly better across all four months, with a bootstrap 95% interval entirely below zero, and neither month pair gets clearly worse.

The live leaderboard became a sanity check only. That was tested quickly: one version scored 0.46 s worse live than the one before, although it was clearly better on the validation. It stayed.


5. What Moved the Score

Step Clean RMSE (s) Change
Mixture model, linear trees 315.39
+ day-error rule 307.69 -7.70
+ weather (METAR) 302.83 -4.86
+ learning rate 0.025 301.43 -1.39
+ NM off-block times (confirmed allowed by the organisers) 285.05 -16.38
+ second and third regressors (LightGBM and CatBoost) 281.03 -4.02
+ midnight day-error group, CatBoost classifier averaged in (3 seeds) 276.60
+ taxi level of other departures, cost-weighted classifier (final) 270.92 -5.68
What moved the score after the mixture model What moved the score after the mixture model

Weather helped exactly where it should: Munich -24.3 s, Paris CDG -15.0 s and Amsterdam -9.3 s, the airports with the most de-icing.

Two ideas in the final step are worth explaining. The first gives the model the current taxi level of the other departures around each flight, so it can tell when the airport is congested. The second came from a mismatch: a classifier can get better at ranking flights on average and still get worse on RMSE, because a wrong call on a flight delayed by three hours costs far more than one on a flight delayed by twenty minutes. Training the classifier with weights that reflect that cost improved the score although its AUC hardly moved.

Final result: clean RMSE 270.92 s on the 2025 validation (330.13 s on all rows), and 305.75 s on the live leaderboard.


6. What Did Not Work

Most ideas did not survive the rule, and they are all documented in the repository. A few of them taught me something:


7. Reproducibility

The final step was to prove the submission can be rebuilt from the public code alone. In a fresh folder, with only the repository files, a new environment and the raw data, the whole pipeline ran again for about 9.4 hours and produced a final file byte-identical to the one I submitted.


Conclusion

The biggest gains in this project did not come from tuning models. They came from understanding how the times were recorded: schedule copies, dates that slipped past midnight, local times stored as UTC.

This is the same lesson I keep meeting in security work. Before trusting a signal, understand how the data behind it is produced.

A model can be accurate on paper and still be learning the wrong thing, if the data does not mean what it says.

The final rankings will be announced by the organisers, and I will update this post with the result.


What I Learned

Data: PRC Data Challenge 2026 data, provided by the organisers (not redistributed). Weather: METAR reports from the Iowa Environmental Mesonet, Iowa State University (public domain).

Code and full experiment log: GitHub repository