Predicting Delayed Train Trajectories on the Dutch Railway Network: Explainable AI Evaluation of Topological, Operational and Weather Features with Tree Based Ensemble Methods
Abstract
The reliable prediction of passenger train delays is a critical component of railway management. While contemporary research frequently attempts to maximize absolute accuracy by deploying opaque deep learning architectures, the underlying data mechanics driving longitudinal predictive decay remain underexplored. Consequently, this study provides an explainable temporal robustness analysis of network-wide railway delay prediction. Focusing on the Dutch railway network, this research utilizes interpretable tree-based ensembles to integrate granular topological, environmental, and operational features. The overarching finding establishes that while feature-rich tree-based models improve simultaneous (within-month) prediction, predictive performance systematically degrades when evaluated across non-simultaneous (future) months. Furthermore, multi-horizon SHAP and dispersion analyses explicitly link this degradation to environmental feature volatility and instability within the statistical target definition. Ultimately, this thesis demonstrates that richer feature sets alone are insufficient to resolve long-term forecasting constraints, underscoring the necessity to transition toward dynamic, season-aware architectures anchored by absolute operational boundaries.
Figures & tables
Appendix figures & tables52 assets
Supplementary material from the paper’s appendix.
Appendix
| Preprocessing Step | Rationale / Justification | Methodological Origin |
|---|---|---|
| Filtering non-domestic NS services (Freight & International) | Excludes distinct routing priorities and scheduling dynamics to strictly isolate domestic passenger patterns. | Novel exclusion criteria |
| Stop-level trajectory formulation (Graph structure) | Increases observation density and prevents spatial sparsity by treating all intermediate stops as discrete edge trajectories. | Inherited ( brakenhoff_dynamic_2026 ) |
| Bidirectional spatial filtering | Prevents the generation of isolated, disconnected nodes and ensures topological validity within the graph structure. | Inherited ( brakenhoff_dynamic_2026 ) |
| Terminal stop imputation | Aligns missing terminal timestamps with scheduled times, reflecting physical starting/ending realities. | Novel contribution |
| Handling of full/partial cancellations | Reflects true operational impact. Includes all types of cancellations in the definition for delayed trajectories. | Methodological extension ( kampere_predicting_2025 ; brakenhoff_dynamic_2026 ) |
| Retention of October DST weather duplicates | Timestamps are duplicated but meteorological values are distinct and valid; retaining them prevents data loss and maintains unbiased monthly aggregates. | Novel justification |
| Split Type | Imbalance Handling | Purpose |
|---|---|---|
| Time-Based (All Models) | Time-Based Split | Primary temporal generalizability evaluation. Ensures 70%/30% train data split volume for each month. |
| Trajectory-Based (XGBoost) | Random Under-Sampling | Secondary baseline for strict literature comparability and standardized SHAP evaluation. Ensures 70%/30% train data split of trajectories across the whole dataset |
| Trajectory-Based Null Model | Random Under-Sampling | Establishes a theoretical performance floor (shuffled labels). If the Null Model performs similar to non-shuffled data, then the non-shuffled data is likely a result of overfitting. |
| Absolute Threshold (0.20) | Historical Seasonal Threshold | |||
|---|---|---|---|---|
| Feature Set | Simultaneous | Non-Simultaneous | Simultaneous | Non-Simultaneous |
| Topological Features | 0.570 | 0.580 | 0.577 | 0.546 |
| Weight Features | 0.624 | 0.618 | 0.613 | 0.562 |
| Weather Features | 0.575 | 0.501 | 0.577 | 0.500 |
| Operational Features | 0.581 | 0.538 | 0.592 | 0.533 |
| Topological + Weight | 0.612 | 0.608 | 0.621 | 0.564 |
| Feature Set | Direction | Mdn (Sim) | Mdn (Null) | Mdn Diff | W | p-value | Effect ( ) |
|---|---|---|---|---|---|---|---|
| Topological Features | Sim Null | 0.582 | 0.501 | +0.075 | 2599.0 | 0.601 | |
| Weight Features | Sim Null | 0.601 | 0.496 | +0.107 | 2538.0 | 0.602 | |
| Weather Features | Sim Null | 0.571 | 0.490 | +0.082 | 2582.0 | 0.593 | |
| Operational Features | Sim Null | 0.584 | 0.496 | +0.090 | 2520.0 | 0.564 | |
| Topological + Weight | Sim Null | 0.605 | 0.513 | +0.104 | 2593.5 | 0.598 | |
| Topological + Weight + Weather | Sim Null | 0.630 | 0.512 | +0.106 | 2627.0 | 0.614 |
| Model | Direction | Mdn (Sim) | Mdn (Non-Sim) | Mdn Diff | W | p-value | Effect ( ) |
|---|---|---|---|---|---|---|---|
| Topological Features | Sim Non-Sim | 0.583 | 0.556 | +0.033 | 2197.0 | 0.442 | |
| Weight Features | Sim Non-Sim | 0.601 | 0.569 | +0.041 | 2305.0 | 0.494 | |
| Weather Features | Sim Non-Sim | 0.571 | 0.500 | +0.069 | 2556.0 | 0.615 | |
| Operational Features | Sim Non-Sim | 0.584 | 0.540 | +0.045 | 2394.0 | 0.537 | |
| Topological + Weight | Sim Non-Sim | 0.606 | 0.571 | +0.037 | 2308.0 | 0.495 | |
| Topological + Weight + Weather | Sim Non-Sim | 0.630 | 0.553 | +0.074 | 2539.0 | 0.606 |
| Classifier | Feature Set | Direction | Mdn (Sim) | Mdn (Non-Sim) | Mdn Diff | W | p-value | Effect ( ) |
|---|---|---|---|---|---|---|---|---|
| LGBM | Topological Features | Sim Non-Sim | 0.576 | 0.609 | -0.029 | 557.0 | 0.305 | |
| Weight Features | Sim Non-Sim | 0.619 | 0.601 | +0.019 | 1363.0 | 0.143 | ||
| Weather Features | Sim Non-Sim | 0.584 | 0.500 | +0.079 | 2179.0 | 0.597 | ||
| Operational Features | Sim Non-Sim | 0.592 | 0.574 | +0.014 | 1435.0 | 0.183 | ||
| Topological + Weight | Sim Non-Sim | 0.616 | 0.616 | +0.000 | 1058.0 | 0.026 | ||
| Top + Weight + Weather | Sim Non-Sim | 0.632 | 0.568 | +0.062 | 1998.0 | 0.496 |
| Model | Direction | Mdn (Sim) | Mdn (Non-Sim) | Mdn Diff | W | p-value | Effect ( ) |
|---|---|---|---|---|---|---|---|
| Topological Features | Sim Non-Sim | 0.574 | 0.570 | -0.000 | 1212.0 | 0.032 | |
| Weight Features | Sim Non-Sim | 0.620 | 0.607 | +0.024 | 1876.0 | 0.288 | |
| Weather Features | Sim Non-Sim | 0.569 | 0.502 | +0.068 | 2538.0 | 0.606 | |
| Operational Features | Sim Non-Sim | 0.581 | 0.543 | +0.039 | 2318.0 | 0.500 | |
| Topological + Weight | Sim Non-Sim | 0.606 | 0.595 | +0.010 | 1695.0 | 0.201 | |
| Topological + Weight + Weather | Sim Non-Sim | 0.619 | 0.588 | +0.032 | 2314.0 | 0.498 |
| Model | Direction | Mdn (Sim) | Mdn (Non-Sim) | Mdn Diff | W | p-value | Effect ( ) |
|---|---|---|---|---|---|---|---|
| Topological Features | Sim Non-Sim | 0.580 | 0.547 | +0.034 | 2178.0 | 0.433 | |
| Weight Features | Sim Non-Sim | 0.618 | 0.562 | +0.053 | 2400.0 | 0.539 | |
| Weather Features | Sim Non-Sim | 0.580 | 0.501 | +0.080 | 2495.0 | 0.585 | |
| Operational Features | Sim Non-Sim | 0.582 | 0.532 | +0.056 | 2505.0 | 0.590 | |
| Topological + Weight | Sim Non-Sim | 0.619 | 0.565 | +0.055 | 2406.0 | 0.542 | |
| Topological + Weight + Weather | Sim Non-Sim | 0.628 | 0.556 | +0.075 | 2489.0 | 0.582 |
| Step | Base Model | Enhanced Model | Direction | Mdn (Base) | Mdn (Enh) | Mdn Diff | W | p-value | Effect ( ) |
|---|---|---|---|---|---|---|---|---|---|
| Adding Weights | Topological Features | Topological + Weight | Enh Base | 0.547 | 0.565 | +0.018 | 368.0 | 0.611 | |
| Adding Weather | Topological + Weight | Top + Weight + Weather | Enh Base | 0.565 | 0.556 | -0.006 | 1931.0 | 0.314 | |
| Adding Operational | Topological + Weight | Top + Weight + Op | Enh Base | 0.565 | 0.565 | +0.003 | 699.0 | 0.278 | |
| Adding Op. to Weather | Top + Weight + Weather | All Features | Enh Base | 0.556 | 0.553 | -0.006 | 1831.0 | 0.266 | |
| Adding Wth. to Op. | Top + Weight + Op | All Features | Enh Base | 0.565 | 0.553 | -0.014 | 2528.0 | 0.601 | |
| Base vs. Best | Topological Features | Top + Weight + Op | Enh Base | 0.547 | 0.565 | +0.023 | 21.0 | 0.604 |
| Model | Direction | Mdn (Sim) | Mdn (Non-Sim) | Mdn Diff | W | p-value | Effect ( ) |
|---|---|---|---|---|---|---|---|
| All Features | Sim Non-Sim | 0.650 | 0.572 | +0.071 | 2555.0 | 0.614 |
| Feature Set | MAE | RMSE | MAE (Null) | RMSE (Null) |
|---|---|---|---|---|
| (a) Simultaneous Testing | ||||
| Topological Features | 0.0758 | 0.1326 | 0.0961 | 0.1574 |
| Weight Features | 0.0600 | 0.1196 | 0.0942 | 0.1542 |
| Weather Features | 0.0771 | 0.1428 | 0.0978 | 0.1622 |
| Operational Features | 0.0553 | 0.1145 | 0.0936 | 0.1548 |
| Topological + Weight | 0.0585 | 0.1141 | 0.0934 | 0.1529 |
| Feature Set | MAE | RMSE | MAE (Null) | RMSE (Null) |
|---|---|---|---|---|
| (a) Simultaneous Testing | ||||
| Topological Features | 0.1366 | 0.1864 | 0.1645 | 0.2200 |
| Weight Features | 0.1228 | 0.1758 | 0.1617 | 0.2169 |
| Weather Features | 0.1486 | 0.2028 | 0.1673 | 0.2241 |
| Operational Features | 0.1290 | 0.1827 | 0.1588 | 0.2123 |
| Topological + Weight | 0.1209 | 0.1721 | 0.1620 | 0.2185 |
| Baseline Model | Statistic | Balanced Accuracy | F1 Score | ROC AUC |
|---|---|---|---|---|
| Naive ( ) | Mean | 0.8080 | 0.7798 | 0.8080 |
| Median | 0.8246 | 0.8147 | 0.8246 | |
| Q1 | 0.7807 | 0.7172 | 0.7807 | |
| Q3 | 0.8459 | 0.8703 | 0.8459 | |
| Seasonal Naive ( ) | Mean | 0.7190 | 0.6531 | 0.7190 |
| Median | 0.7257 | 0.6612 | 0.7257 |
| Baseline Model | Metric | Default Rate | Default Delay Rate | Non-Def. Delay Rate | Delay Rate Gap | Non-Def. Bal. Acc. |
|---|---|---|---|---|---|---|
| Naive | Mean | 0.0356 | 0.6983 | 0.4953 | 0.2030 | 0.8274 |
| Median | 0.0329 | 0.7208 | 0.5355 | 0.2155 | 0.8453 | |
| Seasonal Naive | Mean | 0.0525 | 0.6215 | 0.4962 | 0.1254 | 0.7377 |
| Median | 0.0466 | 0.6250 | 0.5396 | 0.1760 | 0.7396 |
| Feature Set | (Features) | Mean | Min | Max | Significant Transitions ( ) |
|---|---|---|---|---|---|
| Topological Features | 13 | 0.540 | 0.128 | 0.769 | 59 / 71 |
| Weight Features | 7 | 0.421 | -0.048 | 0.905 | 12 / 71 |
| Weather Features | 14 | 0.449 | -0.209 | 0.846 | 48 / 71 |
| Operational Features | 9 | 0.831 | 0.556 | 1.000 | 71 / 71 |
| Topological + Weight | 20 | 0.479 | -0.158 | 0.705 | 63 / 71 |
| Topological + Weight + Weather | 34 | 0.367 | -0.005 | 0.647 | 58 / 71 |
| Category | Drift Frequency (%) | Mean D-Stat | Max D-Stat |
|---|---|---|---|
| Operational (OPS) | 3.29 | 0.028 | 0.994 |
| Topological (TOP) | 6.94 | 0.045 | 0.190 |
| Weight (WGT) | 1.41 | 0.043 | 1.000 |
| Weather (WTH) | 84.81 | 0.645 | 1.000 |
| Feature | Category | Significance Rate (%) | Mean D-Stat | Max D-Stat |
|---|---|---|---|---|
| Topological Features (TOP) | ||||
| src_degree | TOP | 4.23 | 0.045 | 0.079 |
| tgt_degree | TOP | 1.41 | 0.044 | 0.073 |
| src_avg_distance_in | TOP | 4.23 | 0.047 | 0.162 |
| common_neighbors | TOP | 12.68 | 0.040 | 0.095 |
| jaccard_coefficient | TOP | 12.68 | 0.045 | 0.100 |
| Feature | Category | Significance Rate (%) | Mean D-Stat | Max D-Stat |
|---|---|---|---|---|
| Weather Features (WTH) | ||||
| src_avg_temperature_2m | WTH | 100.00 | 0.878 | 1.000 |
| tgt_avg_temperature_2m | WTH | 100.00 | 0.878 | 1.000 |
| src_avg_soil_temperature | WTH | 100.00 | 0.913 | 1.000 |
| tgt_avg_soil_temperature | WTH | 100.00 | 0.914 | 1.000 |
| src_avg_rain | WTH | 100.00 | 0.784 | 1.000 |
| Feature Name | Measured In |
|---|---|
| Topological Features (Unweighted) | |
| [src/tgt] degree | Count |
| [src/tgt] avg distance in | Kilometers |
| [src/tgt] avg distance out | Kilometers |
| [src/tgt] avg distance total | Kilometers |
| common neighbors | Count |
| Feature | Type | Formula / Description |
|---|---|---|
| Node Degree | Node-level | |
| Out Weighted Degree | Node-level | , where is the edge weight. |
| In Weighted Degree | Node-level | , where is the edge weight. |
| Total Weighted Degree | Node-level | |
| Out Average Distance | Node-level | |
| In Average Distance | Node-level |
| Classifier | Hyperparameters |
|---|---|
| LogisticRegression (scikit-learn 1.8.0) | penalty: {’l2’}, C: {1.0}, l1_ratio: {0.0}, fit_intercept: {True}, intercept_scaling: {1}, solver: {’lbfgs’}, max_iter: {1000}, tol: {0.0001}, dual: {False}, class_weight: {None}, random_state: {88}, warm_start: {False}, n_jobs: {None} |
| RandomForestClassifier (scikit-learn 1.8.0) | n_estimators: {100}, criterion: {’gini’}, max_depth: {None}, min_samples_split: {2}, min_samples_leaf: {1}, min_weight_fraction_leaf: {0.0}, max_features: {’sqrt’}, max_leaf_nodes: {None}, min_impurity_decrease: {0.0}, bootstrap: {True}, oob_score: {False}, n_jobs: {None}, random_state: {88}, class_weight: {None}, ccp_alpha: {0.0}, max_samples: {None}, monotonic_cst: {None} |
| XGBClassifier (xgboost 3.2.0) | objective: {’binary:logistic’}, n_estimators: {100}, learning_rate: {0.3}, max_depth: {6}, booster: {’gbtree’}, tree_method: {’auto’}, gamma: {0}, min_child_weight: {1}, max_delta_step: {0}, subsample: {1}, colsample_bytree: {1}, colsample_bylevel: {1}, colsample_bynode: {1}, reg_alpha: {0}, reg_lambda: {1}, scale_pos_weight: {1}, base_score: {auto}, random_state: {88} |
| LGBMClassifier (lightgbm 4.6.0) | objective: {’binary’}, boosting_type: {’gbdt’}, num_leaves: {31}, max_depth: {-1}, learning_rate: {0.1}, n_estimators: {100}, subsample_for_bin: {200000}, scale_pos_weight: {1}, min_split_gain: {0.0}, min_child_weight: {0.001}, min_child_samples: {20}, subsample: {1.0}, subsample_freq: {0}, colsample_bytree: {1.0}, reg_alpha: {0.0}, reg_lambda: {0.0}, random_state: {88} |