EventGPT: Next-Event Pretraining on Banking Customer Histories
Abstract
A model pretrained to predict a customer's next event can estimate the probability of future events without training on their labels and provide a reusable representation for supervised downstream banking tasks. We pretrain EventGPT, a hierarchical causal transformer, by next-token maximum likelihood estimation on the public Multimodal Banking Dataset (MBD-mini: 100,224 clients, 38.8 million transactions and 66.3 million geolocation pings). Keeping one state per event, EventGPT trains in about two hours on one L4 GPU at windows up to 8,192 tokens. From its next-event distribution, with no labels, EventGPT scores five targets of the form "the client makes a transaction of a given kind for the first time next month" at ROC-AUC 0.79 to 0.92. Gradient boosting on 114 engineered features needs 10,000 to 300,000 labeled client-months to match it on four targets and stays below it on the fifth. For product prediction, frozen EventGPT embeddings score below the engineered features (mean ROC-AUC 0.787 against 0.808 over five test folds), and a rank-averaged ensemble of EventGPT, profile fields and token counts with the engineered features adds 0.014 to 0.017, of which 0.007 to 0.016 is EventGPT's own. The code and pretrained weights are released.
Figures & tables
| modality | events | clients | span | per client (p50 / p90 / p99) |
|---|---|---|---|---|
| transactions | 38.8M | 98,721 | Jan 2021 – Dec 2022 | 170 / 1,007 / 2,243 |
| geolocation pings | 66.3M | 72,573 | Dec 2021 – Dec 2022 | 507 / 2,293 / 5,580 |
| dialogues | 0.22M | 46,320 | Feb 2021 – Dec 2022 | 3 / 10 / 27 |
| method | transactions | transactions + geo |
|---|---|---|
| aggregation | 0.783 | |
| CoLES | 0.773 | 0.775 |
| TabBERT | 0.762 | 0.764 |
| TabGPT | 0.802 | 0.800 |
| supervised RNN | 0.819 | 0.819 |
| Markov | Markov | EventGPT | |||||
|---|---|---|---|---|---|---|---|
| target | pos. | last event | last ten | activity | events | EventGPT | Markov events |
| first 48/31 | 59 | 0.671 | 0.835 | 0.848 | 0.882 | 0.906 (0.022) | (0.025) |
| first 23/49 | 195 | 0.667 | 0.833 | 0.811 | 0.860 | 0.916 (0.011) | (0.016) |
| first 26/28 | 252 | 0.577 | 0.743 | 0.787 | 0.833 | 0.823 (0.013) | (0.014) |
| first 48/10 | 290 | 0.608 | 0.718 | 0.759 | 0.791 | 0.777 (0.014) | (0.013) |
| first 50/19 | 770 | 0.667 | 0.802 | 0.773 | 0.811 | 0.906 (0.006) | (0.007) |
| EventGPT zero-shot | flat decoder | supervised | zero-shot | engineered | ||||
|---|---|---|---|---|---|---|---|---|
| target | pos. | seed 42 | seed 43 | aligned | zero-shot | head | head ( ) | features |
| first 48/31 | 59 | 0.916 (0.019) | 0.902 | 0.913 | 0.909 | 0.891 (0.026) | (0.19) | 0.920 |
| first 23/49 | 195 | 0.918 (0.011) | 0.918 | 0.909 | 0.905 | 0.930 (0.009) | (0.16) | 0.920 |
| first 26/28 | 252 | 0.829 (0.014) | 0.827 | 0.826 | 0.799 | 0.875 (0.010) | ( ) | 0.868 |
| first 48/10 | 290 | 0.791 (0.014) | 0.784 | 0.780 | 0.784 | 0.836 (0.012) | ( ) | 0.835 |
| first 50/19 | 770 | 0.906 (0.006) | 0.904 | 0.905 | 0.915 | 0.896 (0.006) | (0.07) | 0.937 |
| target | positives | one-step | scaled | month rollout | rollout one-step |
|---|---|---|---|---|---|
| first 48/31 | 59 | 0.912 | 0.927 | 0.922 | 0.010 (0.007) |
| first 23/49 | 195 | 0.908 | 0.928 | 0.926 | 0.018 (0.005) |
| first 26/28 | 252 | 0.826 | 0.859 | 0.861 | 0.036 (0.005) |
| first 48/10 | 290 | 0.781 | 0.812 | 0.813 | 0.032 (0.004) |
| first 50/19 | 770 | 0.907 | 0.907 | 0.919 | 0.012 (0.002) |
| zero-shot | engineered features, labeled positives | |||||||
|---|---|---|---|---|---|---|---|---|
| target | (no labels) | 5 | 10 | 20 | 50 | 100 | 200 | 400 |
| first 48/31 | 0.909 | 0.865 (0.025) | 0.833 (0.101) | 0.893 (0.018) | 0.911 (0.009) | 0.914 (0.006) | ||
| first 23/49 | 0.918 | 0.839 (0.023) | 0.857 (0.015) | 0.854 (0.018) | 0.882 (0.018) | 0.897 (0.024) | 0.910 (0.008) | 0.927 (0.002) |
| first 26/28 | 0.828 | 0.800 (0.040) | 0.763 (0.057) | 0.813 (0.039) | 0.826 (0.023) | 0.844 (0.017) | 0.860 (0.011) | 0.874 (0.003) |
| first 48/10 | 0.787 | 0.678 (0.089) | 0.721 (0.030) | 0.746 (0.047) | 0.777 (0.018) | 0.797 (0.026) | 0.817 (0.005) | 0.836 (0.009) |
| first 50/19 | 0.905 | 0.815 (0.031) | 0.847 (0.022) | 0.875 (0.021) | 0.897 (0.007) | 0.921 (0.006) | 0.927 (0.002) | 0.926 (0.010) |
| engineered | token counts | flat decoder | EventGPT, last | ||||
| target | features | full history | 2,048 tokens | last | recency | random | aligned |
| target_1 | 0.787 | 0.781 | 0.757 | 0.692 | 0.738 | 0.740 | 0.756 |
| target_2 | 0.843 | 0.849 | 0.792 | 0.725 | 0.823 | 0.829 | 0.850 |
| target_3 | 0.816 | 0.809 | 0.788 | 0.729 | 0.783 | 0.776 | 0.789 |
| target_4 | 0.818 | 0.774 | 0.770 | 0.709 | 0.765 | 0.753 | 0.752 |
| mean | 0.816 | 0.803 | 0.777 | 0.714 | 0.777 | 0.774 | 0.787 |
| seed 42 | seed 43 | |||||
| model | mean | difference [95% int.] | mean | difference [95% int.] | ||
| EventGPT | ||||||
| hidden state | 0.786 | [ , ] | 0.788 | [ , ] | ||
| + profile fields, late fusion | 0.800 | [ , ] | 0.801 | [ , ] | 0.004 | |
| EventGPT with early fusion of the profile fields | ||||||
| hidden state | 0.784 | [ , ] | 0.793 | [ , ] | ||
| engineered | EventGPT | ensemble | |||
|---|---|---|---|---|---|
| test fold | features | hidden state | + profile, counts | ensemble | engineered |
| 0 | 0.816 | 0.789 | 0.808 | 0.830 | |
| 1 | 0.804 | 0.790 | 0.802 | 0.819 | |
| 2 | 0.810 | 0.782 | 0.805 | 0.826 | |
| 3 | 0.813 | 0.794 | 0.809 | 0.830 | |
| 4 | 0.798 | 0.780 | 0.796 | 0.814 | |
Appendix figures & tables8 assets
Supplementary material from the paper’s appendix.
Appendix
| zero-shot | engineered features, labeled rows | all | ||||||
|---|---|---|---|---|---|---|---|---|
| target | (no labels) | 1,000 | 3,000 | 10,000 | 30,000 | 100,000 | 300,000 | labels |
| first 48/31 | 0.909 | 0.573 (0) | 0.650 (0) | 0.718 (2) | 0.871 (6) | 0.894 (19) | 0.912 (66) | 0.921 |
| first 23/49 | 0.918 | 0.784 (2) | 0.809 (2) | 0.866 (7) | 0.856 (25) | 0.896 (81) | 0.902 (263) | 0.930 |
| first 26/28 | 0.828 | 0.735 (2) | 0.739 (4) | 0.776 (11) | 0.817 (34) | 0.858 (128) | 0.849 (355) | 0.880 |
| first 48/10 | 0.787 | 0.739 (2) | 0.668 (5) | 0.695 (11) | 0.763 (34) | 0.771 (134) | 0.826 (394) | 0.841 |
| first 50/19 | 0.905 | 0.746 (2) | 0.821 (8) | 0.854 (34) | 0.921 (95) | 0.929 (342) | 0.932 (992) | 0.937 |
| engineered | EventGPT | ||||
|---|---|---|---|---|---|
| target | prevalence | features | hidden state | + profile fields, token counts | ensemble |
| target_1 | 0.0044 | 0.023 | 0.014 | 0.016 | 0.023 |
| target_2 | 0.0005 | 0.014 | 0.008 | 0.017 | 0.021 |
| target_3 | 0.0038 | 0.021 | 0.014 | 0.019 | 0.022 |
| target_4 | 0.0026 | 0.017 | 0.011 | 0.018 | 0.019 |
| mean | 0.0028 | 0.019 | 0.012 | 0.017 | 0.021 |
| EventGPT | flat decoder | |||
|---|---|---|---|---|
| seed 42 | seed 43 | seed 42 | seed 43 | |
| throughput (tokens per second) | 117,300 | 117,600 | 47,100 | 55,600 |
| validation loss | 1.023 | 1.020 | 0.944 | 0.947 |
| top-1 accuracy, geohash_5 | 0.582 | 0.567 | 0.686 | 0.680 |
| top-1 accuracy, event name | 0.573 | 0.574 | 0.579 | 0.580 |
| official mean ROC-AUC | 0.774 | 0.775 | 0.786 | 0.768 |
| element | variant | seeds | mean ROC-AUC |
|---|---|---|---|
| architecture | hierarchy (EventGPT), last state | 2 | 0.774 (0.774, 0.775) |
| flat decoder, last token | 2 | 0.714 (0.713, 0.714) | |
| flat decoder, recency over tokens | 2 | 0.777 (0.768, 0.786) | |
| positions § | temporal RoPE | 2 | 0.781 (0.777, 0.786) |
| ordinal | 2 | 0.778 (0.775, 0.780) | |
| modalities | transactions + geolocation | 2 | 0.774 (0.774, 0.775) |
| EventGPT | flat decoder | |||
|---|---|---|---|---|
| window | hours | tokens/s | hours | tokens/s |
| 2,048 | 1.5 | 118k | 3.9 | 47k |
| 4,096 | 1.5 | 125k | 6.2 | 29k |
| 8,192 | 1.4 | 126k | ||
| token counts | EventGPT | flat decoder | ||
|---|---|---|---|---|
| window | (CatBoost) | random | aligned | recency |
| 2,048 | 0.777 | 0.774 (0.934) | 0.788 (0.933) | 0.786 (0.900) |
| 4,096 | 0.782 | 0.772 (0.936) | 0.785 (0.896) | |
| 8,192 | 0.801 | 0.772 (0.935) | 0.780 (0.935) | |