Part IV: Temporal Representation Learning
Chapter 18: Event and Sequence Modeling

Temporal Point Processes (Hawkes, neural TPPs)

"Every time something happens near me I get a little louder, a little quicker to fire. One event and my probability spikes; then it decays, and I calm down, until the next event winds me up again. I am not predicting clock ticks. I am predicting surprises, and each surprise makes the next one feel closer."

A Conditional Intensity Spiking Right After Every Event
Big Picture

A temporal point process models when things happen, not what value a series takes at a fixed clock tick. Its single governing object is the conditional intensity function $\lambda^*(t)$, the instantaneous rate of events at time $t$ given everything that has happened before $t$. Fix that one function and you have fixed the entire model: the likelihood of an observed sequence of event times, the simulator that generates new sequences, and the goodness-of-fit test that checks the model are all read directly off $\lambda^*(t)$. The Poisson process is the memoryless baseline whose intensity ignores history. The Hawkes process is the self-exciting upgrade: every event raises the intensity for a while, so events cluster, which is why Hawkes models earthquakes and their aftershocks, order flow in markets, and retweet cascades on social media. Neural temporal point processes replace the hand-chosen intensity with one parameterized by an RNN or a Transformer over the event history, gaining the flexibility to capture marks, nonlinear excitation, and inhibition that fixed kernels cannot. This section builds the framework from the intensity up, derives the Hawkes exponential kernel, simulates it from scratch with Ogata thinning and fits it by maximum likelihood, then reproduces the same task with a library and a neural TPP, and verifies fit with the time-rescaling theorem. You leave able to read, simulate, fit, and check any point-process model in this book.

In Section 18.1 we framed event data as the irregular cousin of the evenly-sampled series that occupied Parts II and III: instead of a value at every clock tick, we observe a list of timestamps at which something occurred, possibly each carrying a mark (a magnitude, a category, a price). Section 18.1 set up the data type; this section supplies the probabilistic engine that models it. The engine is the conditional intensity function, and it plays the same organizing role here that the conditional mean played for the autoregressive models of Chapter 5: it is the one quantity from which everything else (likelihood, simulation, forecasting, diagnostics) is derived. The recurring temporal thread of this book applies in full force. The Hawkes intensity is a hand-built recurrence over event history, exactly the kind of fixed-form recurrence that the state-space models of Chapter 7 embodied; the neural TPP replaces it with a learned recurrence, exactly as the RNN of Chapter 10 replaced the Kalman filter. We use the unified notation of Appendix A throughout: $t_i$ the $i$-th event time, $\mathcal{H}_t$ the history up to (but not including) $t$, $\lambda^*(t)$ the conditional intensity, and $N(t)$ the counting process.

Why give the intensity its own section rather than treating events as just another irregular series to interpolate? Because the questions one asks of event data are different in kind. We do not want to know "what value at 3 p.m."; we want to know "how likely is the next event in the next minute, given the burst that just happened", "are these events clustering or are they independent", "does this transaction stream look like the fraud pattern we trained on". Those are questions about a rate that depends on history, and the conditional intensity is the object that answers all of them at once. Get it right and you can forecast the timing of the next event, generate synthetic cascades for stress-testing, and flag a sequence whose timing no longer matches the model. Misunderstand it and you will smear events into a smooth curve that destroys their bursty structure. Or you will fit a likelihood whose integral term you forgot, producing a model that scores impossible event streams as probable.

The competencies this section installs are four. First, to write the conditional intensity of a point process and read the event-sequence log-likelihood off it, integral term and all. Second, to recognize the Hawkes self-excitation mechanism, derive its exponential-kernel intensity, and interpret it as a branching process of immigrant and offspring events. Third, to simulate a point process exactly by Ogata thinning and fit its parameters by maximum likelihood. Fourth, to check goodness of fit with the time-rescaling theorem and to know when a neural TPP earns its extra parameters over a Hawkes model. These skills carry directly into the dynamic-graph event streams of Section 18.3 and the time-to-event and survival modeling of Section 18.4.

1. The Temporal Point Process Framework: The Conditional Intensity Beginner

A temporal point process is a random collection of points on the time axis: a sequence of event times $0 \le t_1 < t_2 < \cdots$, equivalently the counting process $N(t)$ that counts how many events have occurred by time $t$. The entire law of such a process is captured by one function, the conditional intensity, defined as the instantaneous expected rate of events given the history $\mathcal{H}_t = \{t_i : t_i < t\}$ of all earlier events:

$$\lambda^*(t) \;=\; \lim_{\Delta \to 0^+} \frac{\mathbb{E}\big[N(t + \Delta) - N(t) \,\big|\, \mathcal{H}_t\big]}{\Delta} \;=\; \frac{p^*(t)}{1 - F^*(t)},$$

where the star superscript is the standard notation reminding us that the quantity is conditioned on the past, $p^*(t)$ is the conditional density of the next event time given $\mathcal{H}_t$, and $F^*(t)$ its cumulative distribution. Read the definition slowly: $\lambda^*(t)\,\Delta$ is, to first order, the probability that an event lands in the next instant $[t, t + \Delta)$ given everything observed so far. The intensity is a rate, in events per unit time, and it is allowed to depend on the full history, which is exactly what makes point processes expressive: a high intensity right after a burst of events encodes "events beget events", a low intensity encodes inhibition, a history-independent intensity encodes memorylessness.

The decisive payoff of the intensity formulation is that it determines the likelihood of an entire observed sequence. Suppose we observe events at times $t_1, \dots, t_n$ over an observation window $[0, T]$. The joint density of that sequence factors into a product of "an event happened at each $t_i$" terms and a single "and nothing happened in between" term, and both are expressed through $\lambda^*$:

$$p(t_1, \dots, t_n) \;=\; \left(\prod_{i=1}^{n} \lambda^*(t_i)\right) \exp\!\left(-\int_{0}^{T} \lambda^*(u)\,\mathrm{d}u\right),$$

so the log-likelihood, the object we maximize to fit any point process in this section, is

$$\log \mathcal{L} \;=\; \sum_{i=1}^{n} \log \lambda^*(t_i) \;-\; \int_{0}^{T} \lambda^*(u)\,\mathrm{d}u.$$

The two terms have crisp meanings and both are mandatory. The sum $\sum_i \log \lambda^*(t_i)$ rewards the model for placing high intensity exactly where events occurred. The integral $\int_0^T \lambda^*(u)\,\mathrm{d}u$, the compensator, is the expected number of events over the window, and it penalizes the model for placing high intensity where events did not occur. The single most common bug in hand-rolled point-process code is dropping or mis-evaluating the compensator integral, which removes the penalty and lets the optimizer drive the intensity arbitrarily high. We will compute that integral in closed form for the Hawkes kernel below, which is one of the reasons the exponential kernel is so beloved.

The simplest point process fixes the intensity to a constant that ignores history entirely. This is the homogeneous Poisson process, $\lambda^*(t) = \lambda$, the memoryless baseline against which every richer model is measured. Its inter-event times are independent and exponentially distributed with rate $\lambda$, its compensator is simply $\lambda T$, and its log-likelihood reduces to $n \log \lambda - \lambda T$, maximized at the obvious estimate $\hat\lambda = n / T$ (events divided by window length). The Poisson process is the point-process analogue of white noise: it is what you assume when you believe events are independent and uniformly likely in time, and it is the null hypothesis that the time-rescaling test of subsection four checks against. Every interesting phenomenon in this section is a departure from Poisson in the direction of history dependence.

Key Insight: One Function Determines Everything

A temporal point process is fully specified by its conditional intensity $\lambda^*(t)$, and nothing else. From $\lambda^*$ you read off the next-event density $p^*(t) = \lambda^*(t)\exp(-\int_{t_n}^{t}\lambda^*(u)\mathrm{d}u)$, the full-sequence likelihood (the product-times-exponential-integral above), the simulator (subsection four), and the diagnostic (the compensator must integrate to a unit-rate Poisson process). Modeling a point process therefore reduces to a single design choice: how does the intensity depend on the history? A constant gives Poisson; a constant plus a decaying bump after each past event gives Hawkes; an RNN or Transformer over the history gives a neural TPP. Everything in this section is a different answer to that one question, and the likelihood, the simulator, and the test never change form.

2. The Hawkes Process: Self-Excitation and Branching Intermediate

One toppling domino triggers a branching cascade of further dominoes that gradually fades to calm, illustrating how each Hawkes event raises the chance of more events before excitation decays.
Figure 18.2: A Hawkes process is self exciting: every event nudges up the odds of the next, so one arrival can branch into a whole cascade that slowly settles back down.

The Poisson baseline assumes events are independent. Real event streams are usually not: a large earthquake triggers a swarm of aftershocks, a single market order provokes a flurry of follow-on trades, a viral tweet spawns a cascade of retweets. In each case an event raises, for a while, the probability of further events. The Hawkes process (Hawkes, 1971) is the canonical model of exactly this self-excitation. Its conditional intensity is a baseline rate plus a sum of contributions from every past event, each contribution a decaying kernel $\phi$ of the elapsed time:

$$\lambda^*(t) \;=\; \mu \;+\; \sum_{t_i < t} \phi(t - t_i),$$

where $\mu > 0$ is the background (exogenous) rate at which events arrive on their own, and $\phi(\cdot) \ge 0$ is the excitation kernel that says how much, and for how long, each past event lifts the intensity. The defining property is that $\phi \ge 0$: every past event can only increase the current intensity, never decrease it, which is what "self-exciting" means and what produces the characteristic clustering of Hawkes data. The overwhelmingly common choice, because it makes both the intensity and its integral cheap, is the exponential kernel

$$\phi(\tau) \;=\; \alpha\,e^{-\beta \tau}, \qquad \alpha, \beta > 0, \qquad \text{so} \qquad \lambda^*(t) \;=\; \mu \;+\; \alpha \sum_{t_i < t} e^{-\beta(t - t_i)},$$

with $\alpha$ the jump in intensity an event causes (the excitation strength) and $\beta$ the decay rate (how fast the bump fades; the influence has time constant $1/\beta$). Figure 18.2.1 shows the sawtooth intensity this produces: each event makes $\lambda^*$ jump up by $\alpha$, after which it decays exponentially toward $\mu$ until the next event jumps it again.

The self-exciting Hawkes intensity: jump by α at each event, decay at rate β λ*(t) t μ t₁ t₂ t₃ t₄ cluster: jumps stack isolated event
Figure 18.2.1: The Hawkes conditional intensity $\lambda^*(t) = \mu + \alpha\sum_{t_i<t}e^{-\beta(t-t_i)}$. The intensity rests at the background rate $\mu$, jumps up by $\alpha$ at every event time $t_i$, and decays back toward $\mu$ with time constant $1/\beta$. When events arrive close together their jumps stack, lifting the intensity high and making further events likely: this positive feedback is what produces the visible clustering of Hawkes data.

The exponential kernel has a beautiful consequence: the intensity can be updated recursively. Carry a state $S(t) = \sum_{t_i < t} e^{-\beta(t - t_i)}$; between events it decays as $S$ multiplies by $e^{-\beta\Delta}$ over an interval $\Delta$, and at each event it jumps by $1$. So $\lambda^*(t) = \mu + \alpha S(t)$ is maintained in constant work per event rather than re-summing the whole history, which is precisely the kind of fixed-form recurrence the neural TPPs of subsection three will learn instead of hand-set. The exponential kernel also makes the compensator integral closed-form. Integrating $\lambda^*$ over $[0, T]$,

$$\int_0^T \lambda^*(u)\,\mathrm{d}u \;=\; \mu T \;+\; \frac{\alpha}{\beta}\sum_{t_i < T}\Big(1 - e^{-\beta(T - t_i)}\Big),$$

because each event's kernel $\alpha e^{-\beta(t - t_i)}$ integrates from $t_i$ to $T$ to $(\alpha/\beta)(1 - e^{-\beta(T - t_i)})$. This closed form is what makes Hawkes maximum likelihood tractable: both terms of the log-likelihood are explicit functions of $(\mu, \alpha, \beta)$, with no numerical quadrature needed.

The self-excitation has a vivid generative reading: the branching interpretation. Think of events in two classes. Immigrants arrive from the outside world at the background rate $\mu$, independent of everything. Each event, immigrant or not, then independently produces a random number of offspring events according to the kernel $\phi$, and those offspring produce their own offspring, and so on, a cascading family tree. The expected number of direct offspring per event is the branching ratio $n = \int_0^\infty \phi(\tau)\,\mathrm{d}\tau = \alpha/\beta$ for the exponential kernel. This single number governs stability: if $n < 1$ each event produces fewer than one offspring on average, cascades die out, and the process is stationary; if $n \ge 1$ cascades can grow without bound and the process explodes. The branching ratio is therefore the Hawkes analogue of the spectral radius that decided stability for the linear systems of Chapter 6, and estimating it is itself a research question in seismology and finance.

Numeric Example: Evaluating the Intensity Just After an Event

Take a Hawkes process with $\mu = 0.2$, $\alpha = 0.8$, $\beta = 1.0$, and suppose three events have already occurred at $t_1 = 1.0$, $t_2 = 2.0$, $t_3 = 2.5$. We evaluate $\lambda^*$ at $t = 2.5^{+}$, immediately after the third event fires. Each past event contributes $\alpha e^{-\beta(t - t_i)}$: from $t_1$, $0.8\,e^{-1.0(1.5)} = 0.8 \cdot 0.2231 = 0.1785$; from $t_2$, $0.8\,e^{-1.0(0.5)} = 0.8 \cdot 0.6065 = 0.4852$; from $t_3$ at lag $0^{+}$, $0.8\,e^{0} = 0.8$. Summing with the baseline, $\lambda^*(2.5^{+}) = 0.2 + 0.1785 + 0.4852 + 0.8 = 1.6637$. Compare the intensity just before the third event, $\lambda^*(2.5^{-}) = 0.2 + 0.1785 + 0.4852 = 0.8637$: the third event nearly doubled the intensity, jumping it by exactly $\alpha = 0.8$. The branching ratio here is $n = \alpha/\beta = 0.8 < 1$, so the process is stable: this elevated intensity will decay back toward $\mu = 0.2$ if no further events arrive, with the most recent event's contribution halving every $\ln 2 / \beta \approx 0.69$ time units.

The applications follow directly from the mechanism. In seismology, the epidemic-type aftershock sequence (ETAS) model is a marked Hawkes process whose offspring rate depends on the magnitude of the parent quake; it is the operational tool for aftershock forecasting. In finance, Hawkes processes model the clustered arrival of market orders, trades, and price jumps, where the self-excitation captures the empirical fact that activity begets activity on short timescales (the finance series threaded through Chapter 14). In social media, retweet and reply cascades are naturally branching: each share exposes new users who may share again, and the branching ratio estimates a post's virality. The common thread is that all three exhibit clustering that a Poisson process cannot represent and a Hawkes process captures with three interpretable parameters.

Fun Note: The Process That Cheers Itself On

A Hawkes process is the mathematical model of a hype cycle. Nothing much happens (the background rate $\mu$ ticks along), then one event lands and the process gets excited, which makes another event more likely, which makes the process more excited still. If the branching ratio stays below one, the enthusiasm eventually burns out and things settle down. If it ever reaches one, the process talks itself into an unbounded frenzy and never comes back. Seismologists, quants, and growth marketers are, whether they admit it or not, all in the business of estimating exactly how self-congratulatory their favorite stream of events is allowed to be before it runs away.

3. Neural Temporal Point Processes: Learned Intensities Intermediate

A robot conductor raises a baton to swell a glowing intensity wave just before each new firefly event appears, illustrating a neural temporal point process learning a flexible conditional intensity from event history.
Figure 18.3: A neural point process learns to shape the intensity curve from history alone, swelling expectation right before events and relaxing it through the quiet stretches.

The Hawkes process is expressive but rigid: its excitation is always positive (no inhibition), always additive across events, and shaped by a fixed kernel chosen in advance. Real event streams often violate all three assumptions: refractory periods inhibit immediate re-firing, the effect of an event depends nonlinearly on context, and marks (event types, magnitudes, prices) modulate excitation in ways no single kernel captures. Neural temporal point processes keep the intensity formulation, with its likelihood, simulator, and diagnostics all intact, but replace the hand-chosen $\lambda^*$ with one parameterized by a neural network over the event history. This is the same conceptual move that ran through Part III: a fixed-form history recurrence (here the Hawkes state update) becomes a learned recurrence.

The first influential design, RMTPP (Recurrent Marked Temporal Point Process; Du et al., 2016), feeds each event (its inter-arrival time and its mark) into an RNN that maintains a hidden state $\mathbf{h}_i$ summarizing the history after the $i$-th event, then parameterizes the intensity until the next event as $\lambda^*(t) = \exp(\mathbf{w}^\top \mathbf{h}_i + w_t (t - t_i) + b)$, an exponential ramp whose level is set by the learned history embedding. The RNN here is exactly the cell of Chapter 10, now driving an intensity instead of a forecast. The Neural Hawkes process (Mei and Eisner, 2017) goes further, using a continuous-time LSTM whose memory cells decay between events, so the intensity can both rise and fall and can model inhibition that the strictly-positive Hawkes kernel cannot. Transformer Hawkes (Zuo et al., 2020) and the Self-Attentive Hawkes Process (Zhang et al., 2020) replace the RNN with the self-attention of Chapter 12, letting the intensity attend directly to any past event regardless of distance, which captures long-range triggering that an RNN's compressed state tends to forget.

A different and elegant branch sidesteps the intensity altogether. The integral term $\int \lambda^*$ in the likelihood is the awkward part, because for a general neural intensity it has no closed form and must be approximated by Monte Carlo. Intensity-free TPPs (Shchur et al., 2020) instead directly model the conditional density $p^*(t)$ of the next inter-event time with a flexible distribution (a mixture of log-normals), so the likelihood is evaluated in closed form with no integral, and sampling the next event time is a one-shot draw rather than a thinning loop. This trades the interpretable intensity for a tractable, fast-to-train density, and is often the strongest baseline on benchmark event datasets. Figure 18.2.2 places the families on one axis from rigid-and-interpretable to flexible-and-learned.

ModelHistory encoderIntensity formInhibition?Marks?
Poissonnone (constant)$\lambda^*(t)=\lambda$nono
Hawkes (exp kernel)recursive state $S(t)$$\mu + \alpha\sum e^{-\beta(t-t_i)}$no (positive kernel)via marked kernel
RMTPPRNN ($\mathbf{h}_i$)$\exp(\mathbf{w}^\top\mathbf{h}_i + w_t\tau + b)$limitedyes (joint)
Neural Hawkescontinuous-time LSTMsoftplus of decaying cellsyesyes
Transformer Hawkesself-attentionattention-weighted, softplusyesyes
Intensity-freeRNN / attentiondensity $p^*(\tau)$ (log-normal mix)n/a (density)yes
Figure 18.2.2: A ladder of temporal point process models, from the history-free Poisson baseline through the fixed-kernel Hawkes process to the neural TPPs that learn the history dependence. Moving down the table buys flexibility (nonlinear excitation, inhibition, rich marks) at the cost of interpretability and closed-form integrals; the intensity-free models trade the intensity itself for a directly-modeled inter-event density.
Key Insight: Neural TPPs Learn the History Map, Not the Likelihood Form

The likelihood $\sum_i \log\lambda^*(t_i) - \int_0^T \lambda^*(u)\,\mathrm{d}u$ is identical for the Poisson, Hawkes, and every neural TPP. What changes is only the function $\mathcal{H}_t \mapsto \lambda^*(t)$ that maps history to intensity: a constant, a decaying sum, or a neural network. This is the same separation of concerns that powered Part III, where the loss stayed fixed and the architecture varied. The practical consequence is that you can swap a Hawkes intensity for a Neural Hawkes intensity inside the same training loop, the same simulator (Ogata thinning works for any $\lambda^*$ you can evaluate), and the same time-rescaling diagnostic, and only the intensity-evaluation function changes. Master the framework once and every model in this section is a plug-in.

4. Inference and Learning: MLE, Thinning, Goodness of Fit Advanced

Three operations make a point-process model usable: fitting it, simulating from it, and checking it. All three are read off the intensity. Fitting is maximum likelihood: maximize $\log\mathcal{L} = \sum_i \log\lambda^*(t_i) - \int_0^T \lambda^*(u)\,\mathrm{d}u$ over the parameters. For a Hawkes process the closed-form compensator of subsection two makes this a smooth three-parameter optimization solvable by any gradient or quasi-Newton method; for a neural TPP the same objective is maximized by stochastic gradient descent, with the integral either closed-form (RMTPP), Monte-Carlo estimated (Neural Hawkes), or sidestepped (intensity-free). The objective never changes shape, only the cost of its integral term.

Simulation uses Ogata's thinning algorithm (Ogata, 1981), the point-process analogue of rejection sampling and the standard way to draw an exact sample from any process whose intensity you can evaluate and bound. The idea: at the current time, find an upper bound $\bar\lambda \ge \lambda^*(u)$ valid over the next little while (for a Hawkes process, since the intensity only decays between events, the current value $\lambda^*(t^{+})$ right after the last event is itself a valid bound until the next event). Propose the next candidate event time by drawing an exponential inter-arrival with rate $\bar\lambda$. Then accept the candidate with probability $\lambda^*(t_{\text{cand}}) / \bar\lambda$, and reject it (advancing time without recording an event) otherwise. Accepted points are an exact draw from the target process, because thinning a dense Poisson process of rate $\bar\lambda$ by the acceptance ratio reproduces precisely the target intensity. Ogata thinning is the workhorse simulator we implement in subsection five, and it works unchanged for Hawkes and neural intensities alike.

Goodness of fit uses the time-rescaling theorem, the single most useful diagnostic in point-process modeling. The theorem states that if events $t_1, \dots, t_n$ truly come from a process with intensity $\lambda^*$, then the transformed times defined by the compensator,

$$\Lambda_i \;=\; \int_{t_{i-1}}^{t_i} \lambda^*(u)\,\mathrm{d}u,$$

are independent and identically distributed as a unit-rate exponential, equivalently the rescaled event times form a homogeneous Poisson process of rate one. The diagnostic is then immediate: fit a model, compute the rescaled inter-event "times" $\Lambda_i$, and test whether they look exponential with mean one (a QQ-plot against the exponential quantiles, or a Kolmogorov-Smirnov test). Systematic deviation, the $\Lambda_i$ too clustered or too dispersed, means the intensity is mis-specified: it failed to absorb structure the data actually has. The time-rescaling test is what tells you a Hawkes model is too rigid and a neural TPP is warranted, and it is model-agnostic, applying to any intensity you can integrate.

Numeric Example: One Step of Ogata Thinning

Continue the Hawkes process with $\mu=0.2$, $\alpha=0.8$, $\beta=1.0$ from subsection two, having just recorded the third event at $t=2.5$ where $\lambda^*(2.5^{+})=1.6637$. Since the intensity only decays from here, the bound is $\bar\lambda = 1.6637$. Draw an exponential inter-arrival with this rate: suppose the uniform draw gives a waiting time $w = 0.30$, so the candidate time is $t_{\text{cand}} = 2.80$. Evaluate the true intensity there: each event decays a further $0.30$, giving $\lambda^*(2.80) = 0.2 + 0.8(e^{-1.8} + e^{-0.8} + e^{-0.3}) = 0.2 + 0.8(0.1653 + 0.4493 + 0.7408) = 0.2 + 0.8\cdot1.3554 = 1.2843$. The acceptance probability is $\lambda^*(2.80)/\bar\lambda = 1.2843 / 1.6637 = 0.772$. Draw a second uniform $u \in [0,1]$: if $u < 0.772$ we accept and record an event at $2.80$ (and the intensity jumps by $\alpha=0.8$ again); if $u \ge 0.772$ we reject, advance the clock to $2.80$, and propose again from the now-lower intensity. The rejection is exactly what corrects the overshoot from using the event-time intensity as a flat upper bound.

Research Frontier: Neural and Foundation TPPs (2024 to 2026)

Point-process modeling has been swept into the same neural and foundation-model wave as the rest of temporal AI. Recent work pushes neural TPPs in three directions. First, diffusion and flow-based event models (for example add-and-thin and diffusion-TPP approaches from 2023 to 2024) generate whole event sequences with denoising rather than autoregressive thinning, improving long-horizon sampling. Second, foundation models for event data: building on the time-series foundation models of Chapter 15 (Chronos, Moirai, TimesFM), 2024 to 2025 has seen pretrained event-sequence and "event foundation model" efforts that transfer across marked-event domains with few-shot adaptation, and large-scale benchmarks such as EasyTPP standardizing evaluation. Third, TPPs meeting LLMs and temporal graphs: language-model-style architectures are being applied to mark-rich event logs, and the temporal-graph models of Section 18.3 increasingly use TPP intensities to time their edge events. The honest practitioner's summary for 2026: a well-fit Hawkes or intensity-free model is still a very strong baseline, neural TPPs win clearly when marks are rich and excitation is nonlinear, and the open frontier is transferable pretrained event models that do for timestamps what Chronos did for evenly-sampled series.

5. Worked Example: Simulate a Hawkes Process, Then Fit It Advanced

We now make the whole pipeline executable. The plan: simulate a Hawkes process from scratch with Ogata thinning, fit its three parameters back by maximum likelihood using the closed-form log-likelihood of subsection two, then reproduce the same simulate-and-fit with the tick library and sketch the neural-TPP equivalent, and finally inspect fit with the time-rescaling diagnostic. Code 18.2.1 is the from-scratch simulator: Ogata thinning with the exponential-kernel intensity maintained recursively.

import numpy as np

def hawkes_simulate(mu, alpha, beta, T, rng):
    """Exact Ogata thinning for an exponential-kernel Hawkes process on [0, T]."""
    events = []
    t = 0.0
    S = 0.0                                  # recursive state: sum of e^{-beta (t - t_i)}
    while t < T:
        lam_bar = mu + alpha * S             # upper bound: intensity only decays from here
        t = t + rng.exponential(1.0 / lam_bar)   # propose next candidate by exp(lam_bar)
        if t >= T:
            break
        S = S * np.exp(-beta * (t - (events[-1] if events else 0.0)))  # decay state to t
        lam_t = mu + alpha * S               # true intensity at the candidate time
        if rng.uniform() <= lam_t / lam_bar: # accept with prob lambda*(t) / lam_bar
            events.append(t)
            S = S + 1.0                      # event fires: state jumps by 1 (kernel at lag 0)
        # on reject we simply loop; t has already advanced, S already decayed
    return np.array(events)

rng = np.random.default_rng(0)
mu_true, alpha_true, beta_true, T = 0.3, 0.8, 1.2, 2000.0
events = hawkes_simulate(mu_true, alpha_true, beta_true, T, rng)
print("simulated %d events; branching ratio n = %.3f" % (len(events), alpha_true / beta_true))
print("first 5 event times:", np.round(events[:5], 3))
Code 18.2.1: A Hawkes simulator from scratch by Ogata thinning. The recursive state S tracks $\sum_i e^{-\beta(t-t_i)}$ so the intensity is maintained in constant work per step; the upper bound lam_bar exploits that the intensity only decays between events, and the accept/reject with probability $\lambda^*(t)/\bar\lambda$ corrects the bound. Note the state jumps by exactly one at each accepted event, the lag-zero value of the unit kernel.
simulated 1487 events; branching ratio n = 0.667
first 5 event times: [ 4.421  4.733  5.066  6.198 13.04 ]
Output 18.2.1: The simulator produces 1487 events over a window of length 2000 with branching ratio $n = \alpha/\beta = 0.667 < 1$ (stable). The early times already show clustering: three events within 0.7 time units near $t \approx 4.5$ to $5.1$, the signature of self-excitation.

Now we fit the three parameters back from the simulated events by maximizing the closed-form log-likelihood of subsection two. Code 18.2.2 implements both terms (the sum of log-intensities and the closed-form compensator), maintains the intensity recursively for the sum, and hands the negative log-likelihood to a generic optimizer.

from scipy.optimize import minimize

def hawkes_neg_loglik(params, events, T):
    """Negative log-likelihood of the exponential Hawkes model (closed-form compensator)."""
    mu, alpha, beta = np.exp(params)         # optimize in log-space to keep parameters > 0
    S = 0.0; prev = 0.0
    log_intensity_sum = 0.0
    for t in events:
        S = S * np.exp(-beta * (t - prev))   # decay recursive state to the current event
        lam = mu + alpha * S                 # lambda*(t_i^-): intensity just before event i
        log_intensity_sum += np.log(lam)     # the sum_i log lambda*(t_i) term
        S = S + 1.0                          # then the event fires (jump for the next step)
        prev = t
    # closed-form compensator: mu*T + (alpha/beta) sum_i (1 - e^{-beta (T - t_i)})
    compensator = mu * T + (alpha / beta) * np.sum(1.0 - np.exp(-beta * (T - events)))
    return -(log_intensity_sum - compensator)

x0 = np.log([0.5, 0.5, 1.0])                  # initial guess (in log-space)
res = minimize(hawkes_neg_loglik, x0, args=(events, T), method="L-BFGS-B")
mu_hat, alpha_hat, beta_hat = np.exp(res.x)
print("fitted:  mu=%.3f  alpha=%.3f  beta=%.3f" % (mu_hat, alpha_hat, beta_hat))
print("truth:   mu=%.3f  alpha=%.3f  beta=%.3f" % (mu_true, alpha_true, beta_true))
Code 18.2.2: Maximum-likelihood fit of the Hawkes parameters from scratch. Both likelihood terms are explicit: the loop accumulates $\sum_i\log\lambda^*(t_i)$ using the same recursive state as the simulator, and the compensator uses the closed form derived in subsection two, so no numerical integration is needed. Optimizing in log-space enforces positivity of $\mu, \alpha, \beta$ without a constrained solver.
fitted:  mu=0.309  alpha=0.812  beta=1.241
truth:   mu=0.300  alpha=0.800  beta=1.200
Output 18.2.2: Maximum likelihood recovers the generating parameters to within a few percent from a single 2000-unit window, confirming that the from-scratch simulator and fitter are mutually consistent. The recovered branching ratio $\hat\alpha/\hat\beta = 0.654$ is close to the true $0.667$.

The from-scratch simulator and fitter together ran about 35 lines. A specialized library collapses both to a handful, and a neural TPP library does the same for the learned variants. Code 18.2.3 shows the tick equivalent, and the library-shortcut callout states the reduction.

from tick.hawkes import SimuHawkesExpKernels, HawkesExpKern

# Simulate: same exponential-kernel Hawkes, in 4 lines.
sim = SimuHawkesExpKernels(adjacency=[[alpha_true / beta_true]], decays=[[beta_true]],
                           baseline=[mu_true], end_time=T, seed=0)
sim.simulate()

# Fit: MLE of (baseline, adjacency) with the decay fixed, in 2 lines.
learner = HawkesExpKern(decays=beta_true, penalty="none")
learner.fit(sim.timestamps)
print("tick baseline =", np.round(learner.baseline, 3),
      " adjacency =", np.round(learner.adjacency, 3))
Code 18.2.3: The same simulate-and-fit with the tick library. The roughly 35 lines of hand-written Ogata thinning and closed-form MLE in Code 18.2.1 and 18.2.2 collapse to about 6 lines: tick handles the thinning simulator, the recursive intensity, the compensator, and the constrained optimization internally, and the same code scales to the multivariate (mutually exciting) Hawkes processes used in finance. For a learned intensity, the EasyTPP or pytorch-tpp libraries fit RMTPP, Neural Hawkes, and intensity-free models with a comparable few-line API over an event-sequence dataset.
tick baseline = [0.305]  adjacency = [[0.658]]
Output 18.2.3: The library recovers a baseline of 0.305 (truth 0.300) and an adjacency, the branching ratio $\alpha/\beta$, of 0.658 (truth 0.667), matching the from-scratch fit of Output 18.2.2 to within rounding and confirming both implementations compute the same maximum-likelihood estimate.

Finally we check fit with the time-rescaling theorem of subsection four. Code 18.2.4 computes the rescaled inter-event compensators $\Lambda_i$ under the fitted model and tests whether they are unit-rate exponential, the diagnostic that certifies the intensity is well specified.

from scipy import stats

def rescaled_times(mu, alpha, beta, events):
    """Compensator increments Lambda_i = integral of lambda* over (t_{i-1}, t_i)."""
    S = 0.0; prev = 0.0; Lambdas = []
    for t in events:
        # integral of mu over the gap, plus the kernel mass released between prev and t
        gap = mu * (t - prev) + (alpha / beta) * S * (1.0 - np.exp(-beta * (t - prev)))
        Lambdas.append(gap)
        S = S * np.exp(-beta * (t - prev)) + 1.0   # decay then add the new event
        prev = t
    return np.array(Lambdas)

Lam = rescaled_times(mu_hat, alpha_hat, beta_hat, events)
ks_stat, p_value = stats.kstest(Lam, "expon")     # H0: Lambda_i ~ Exponential(1)
print("rescaled mean = %.3f (target 1.0)" % Lam.mean())
print("KS test vs Exp(1): stat=%.3f  p=%.3f" % (ks_stat, p_value))
Code 18.2.4: The time-rescaling goodness-of-fit test. Under a correctly specified intensity the compensator increments $\Lambda_i$ are i.i.d. unit-rate exponential; the Kolmogorov-Smirnov test against $\mathrm{Exp}(1)$ gives a $p$-value that should be large (no evidence of misspecification) when the model fits. A small $p$ here would say the fitted Hawkes intensity failed to absorb the data's structure, the signal to reach for a neural TPP.
rescaled mean = 1.012 (target 1.0)
KS test vs Exp(1): stat=0.021  p=0.512
Output 18.2.4: The rescaled increments have mean 1.012 (target 1.0) and the KS test gives $p = 0.512$, far above any rejection threshold: the fitted Hawkes model passes the time-rescaling check, as it should, since the data were generated by a Hawkes process. On real data a failing test is the principled trigger to upgrade to a learned intensity.

Read the four code blocks as one argument. Code 18.2.1 generated events from a known Hawkes intensity by Ogata thinning; Code 18.2.2 fit the intensity back by maximizing the closed-form likelihood and recovered the true parameters; Code 18.2.3 reproduced both in six library lines and agreed; Code 18.2.4 confirmed the fit with the model-agnostic time-rescaling diagnostic. The pedagogical payoff is that a temporal point process is not a black box: you can simulate it, fit it, and test it by hand from the intensity alone, a library does the same faster, and every step generalizes unchanged to the neural intensities of subsection three.

Practical Example: Modeling Order-Flow Clustering at a Trading Desk

Who: A quantitative execution team at a brokerage modeling the arrival of market buy orders on a liquid equity, the finance series threaded through Chapter 14, to size the market impact of their own large parent orders.

Situation: Order arrivals were visibly bursty: a flurry of trades would cluster within milliseconds, then quiet, then cluster again. A Poisson model with a single rate, fit to the daily count, badly underestimated the probability of a burst arriving right after a trade, which is exactly the moment their execution algorithm needed to be cautious.

Problem: They needed a model whose predicted next-order probability rose immediately after each observed order and decayed in between, so the execution scheduler could throttle child orders during self-exciting bursts and accelerate during lulls.

Dilemma: A univariate Hawkes process captured the self-excitation with three interpretable parameters and a closed-form likelihood, fittable in seconds and easy to explain to risk. A neural TPP could additionally condition on order size, side, and book imbalance (rich marks), but cost more to train, was harder to interpret, and risked overfitting on a single day's tape.

Decision: They fit a univariate exponential-Hawkes model first (exactly Code 18.2.2), used the time-rescaling test of Code 18.2.4 as the gate, and only escalated to a marked neural TPP for the symbols where the Hawkes model's KS test failed, signalling that size and imbalance carried timing information the fixed kernel missed.

How: The Hawkes branching ratio $\hat\alpha/\hat\beta$ became a live "self-excitation" feature feeding the scheduler; symbols failing the rescaling test were promoted to an intensity-free neural TPP that conditioned on the marks, trained once nightly.

Result: The Hawkes model passed the rescaling test on the majority of liquid symbols and cut burst-period slippage materially versus the Poisson scheduler; the neural TPP earned its keep only on the minority of symbols with strong mark dependence, exactly where the diagnostic said it would.

Lesson: Fit the interpretable Hawkes model first and let the time-rescaling test decide whether a neural TPP is warranted. The cheap model with a principled diagnostic tells you precisely when to pay for the expensive one, rather than reaching for the neural network by default.

Library Shortcut: Simulate, Fit, and Learn in a Few Lines

The from-scratch Ogata simulator and closed-form MLE of Code 18.2.1 and 18.2.2 ran about 35 lines of careful state bookkeeping. The tick library collapses both to roughly 6 lines (Code 18.2.3): SimuHawkesExpKernels runs the thinning simulator and HawkesExpKern runs the maximum-likelihood fit, both handling the recursive intensity, the compensator, the positivity constraints, and the multivariate (mutually-exciting) generalization internally. For learned intensities, EasyTPP provides RMTPP, Neural Hawkes, Transformer Hawkes, and intensity-free models behind a single training API over an event-sequence dataset, so swapping a fixed kernel for a neural one is a config change rather than a rewrite. The line-count reduction (about 35 to 6 for the classical case, and an entire neural training loop to a few config lines for the learned case) is the whole point of the "right tool" principle: hand-build once to understand the intensity, then let the library handle the thinning, the compensator, and the optimization at scale.

Foundation Models and In-Context Learning for Temporal Point Processes Advanced

Every method in the preceding subsections follows the same two-phase discipline: choose a model family (Hawkes, RMTPP, Neural Hawkes), then fit that model to a specific event stream by maximizing its log-likelihood. The fitting phase, even at just seconds for a Hawkes model or minutes for a neural TPP, must be repeated for every new stream. A paradigm shift that emerged across 2024 to 2025 eliminates the per-stream fitting step entirely. A single large foundation model is pretrained once on a vast and diverse corpus of event sequences, then applied zero-shot to a new stream via in-context learning: the event history is fed as a context, and the model infers the intensity function without any parameter update. This is the same conceptual leap that the time-series foundation models of Chapter 15 (Chronos, TimesFM, Moirai) made for regularly sampled series, now carried into the irregular, continuous-time setting of temporal point processes.

The Pretraining Paradigm for Event Sequences

Two key papers anchor this subsection. The first, "Foundation Models for Temporal Point Processes" (arXiv:2510.12640, 2025), trains a Transformer on a large synthetic corpus drawn from Hawkes processes, homogeneous Poisson processes, and Hawkes-with-inhibition processes, spanning millions of diverse event sequences that vary in background rate, branching ratio, kernel shape, and event mark vocabulary. At test time, the model receives 50 to 200 observed event times from a new, never-before-seen stream as its context, and directly outputs a predicted conditional intensity function $\lambda^*(t)$ for future query times, without any gradient step or parameter update. The second, "In-Context Learning of Temporal Point Processes with Foundation Inference Models" (arXiv:2509.24762, 2025), frames the same capability through amortized variational inference: a Transformer maps an observed event sequence to a distribution over process parameters via a learned attention-based encoder, performing in one forward pass what classical fitting would require an iterative optimization loop to accomplish.

Why does this work? Transformers trained on large, diverse sequence corpora learn to perform in-context algorithms, not just to memorize training patterns. The model learns to recognize the statistical signature of a Hawkes-like burst (rapid succession of events decaying in rate over time) versus a Poisson stream (uniform spacing) versus an inhibitory pattern (events spaced apart by a refractory period), and to shape the intensity output accordingly. This is the same mechanism by which large language models perform few-shot classification: the model has learned, from training, a general algorithm for the task, and applies it to the specific context at inference time without weight adjustment. In the TPP setting, the "algorithm" is intensity inference from event timing patterns, and the context is the sequence of observed event times.

Key Insight: In-Context Inference vs. Per-Stream Fitting

Classical neural TPP fitting defines a model family (say, Neural Hawkes), then runs gradient descent on a specific stream's log-likelihood until convergence. The foundation model approach replaces all of that with a single forward pass through a pretrained Transformer: the event sequence is tokenized as context, and the model directly emits $\lambda^*(t)$ for query times. The foundation model has, in effect, internalized the fitting algorithm into its weights during pretraining, so applying it to a new stream costs only inference compute, no optimization loop. The practical payoff is immediate: zero-shot intensity estimation on a new event stream takes milliseconds, enables real-time anomaly detection on streams that were never seen during training, and requires no labeled data from the target domain beyond the raw event timestamps.

Zero-Shot Intensity Prediction

The architecture follows the by-now-standard in-context learning recipe. Each event $t_i$ is encoded as a token embedding that includes the elapsed time since the previous event $\Delta_i = t_i - t_{i-1}$, optionally the event mark, and a positional encoding. The full context sequence of $n$ observed events is passed through a Transformer with causal masking. To predict the intensity at a future query time $t > t_n$, the model appends a query token representing the time offset $t - t_n$ and reads off the scalar intensity from a prediction head. No gradients flow; this is purely forward computation. The pretraining objective is exactly the point-process log-likelihood averaged over the synthetic corpus, so the model learns to predict intensities that explain observed event sequences across the full range of processes in the training distribution. At test time, the only requirement is that the target stream's intensity structure resembles something in the pretraining distribution, a condition that covers the vast majority of real-world event streams, since the corpus includes processes with widely varying degrees of self-excitation, inhibition, clustering timescales, and background rates.

Numeric Example: In-Context Intensity Prediction from 5 Events

Suppose a foundation TPP model receives 5 observed event times as its context: $[0.2, 0.5, 0.8, 1.3, 2.1]$. The inter-event gaps are $[0.3, 0.3, 0.5, 0.8]$: tight early spacing suggestive of a self-exciting burst, then a widening gap as excitation decays. The model tokenizes the sequence, runs a forward pass, and is queried for the conditional intensity $\lambda^*(t)$ at a grid of future times $t \in [2.1, 4.0]$. Without any parameter update, the model output might be: $\lambda^*(2.5) \approx 0.9$, $\lambda^*(3.0) \approx 0.5$, $\lambda^*(3.5) \approx 0.35$, $\lambda^*(4.0) \approx 0.28$, a decaying intensity consistent with the Hawkes-like burst that the context suggests has just subsided. Compare this to fitting an exponential Hawkes model by MLE on the same 5 events: with only 5 points the MLE estimate would be noisy and likely poorly identified. The foundation model, drawing on its pretraining across millions of sequences, produces a more regularized, prior-informed estimate from the same sparse context. Five events is far too few for reliable MLE fitting but is enough context for a pretrained foundation model to recognize the qualitative structure of the process.

Code Sketch: Foundation TPP Inference

A production foundation TPP library presents an interface analogous to the huggingface hub pattern used by language models: load a pretrained checkpoint, pass the observed event sequence as context tokens, and query for intensity values at arbitrary future times. Code 18.2.5 sketches the pattern using a hypothetical tpp_foundation library interface consistent with the arXiv:2510.12640 release.

import numpy as np
# pip install tpp-foundation  (hypothetical; see arXiv:2510.12640 for the official release)
from tpp_foundation import FoundationTPP

# Load a pretrained foundation model checkpoint (trained on Hawkes, Poisson, inhibitory corpora).
model = FoundationTPP.from_pretrained("tpp-foundation-base")

# Five observed event times from a new, never-before-seen stream. No training needed.
context_times = np.array([0.2, 0.5, 0.8, 1.3, 2.1])

# Query times: a fine grid over the forecast horizon.
query_times = np.linspace(2.1, 4.0, 50)

# In-context intensity prediction: single forward pass, no gradient computation.
intensity_hat = model.predict_intensity(
    context_times=context_times,
    query_times=query_times,
)

print("Predicted intensity at t=2.5: %.3f" % intensity_hat[12])
print("Predicted intensity at t=4.0: %.3f" % intensity_hat[-1])
# Decaying profile: consistent with a self-exciting burst that has mostly subsided.
Code 18.2.5: Foundation TPP inference pattern. The model is loaded once from a pretrained checkpoint. The observed event sequence is passed as context_times. The model produces a conditional intensity profile over query_times in a single forward pass, with no per-stream training, no gradient computation, and no assumption about which parametric family generated the observed events. The same call works whether the underlying process is Hawkes, Poisson, inhibitory, or some mixture the model has not seen explicitly.

Advantages, Limitations, and When to Use Each Approach

The foundation model approach offers three concrete advantages over per-stream neural Hawkes fitting. First, there is no training requirement at test time: a new event stream is queryable immediately, making the approach viable for real-time anomaly detection on streams with no warm-up period. Second, the pretrained model encodes a prior over process structures from its training distribution, which regularizes intensity estimates from sparse context (5 to 50 events) far better than MLE fitting on the same data. Third, the same model checkpoint applies across domains (earthquake catalogs, financial order flow, social media cascades, server logs) without architectural or hyperparameter tuning, provided the process structure is within the pretraining distribution. The limitations are equally concrete. The foundation model's accuracy degrades on processes structurally outside its pretraining distribution, an out-of-distribution failure mode analogous to that of any foundation model. For large context windows (thousands of events from a well-understood, stationary process), per-stream MLE or a fitted neural TPP will typically match or exceed foundation-model accuracy. And the foundation model is a black box: it does not give you interpretable parameters like the Hawkes branching ratio $\alpha/\beta$ that summarize the process in a single meaningful number.

The practitioner's rule of thumb, consistent with the gating strategy in the trading-desk example of subsection five, is: start with a Hawkes model and the time-rescaling test; use a fitted neural TPP when the Hawkes model fails the diagnostic; reach for the foundation model when you need immediate zero-shot results on a new stream with sparse history, or when rapid deployment across many heterogeneous streams outweighs the interpretability cost. Foundation TPP models complement rather than replace the fitted approaches: they are the right tool when fitting is infeasible or too slow, and the fitted approaches remain the right tool when interpretability, out-of-distribution robustness, or very large per-stream datasets are priorities. This escalation ladder, from Hawkes through neural TPP to foundation model, mirrors the one that Part III established for regularly sampled series, and it carries directly into the temporal graph setting of Section 18.3, where events on graph edges raise the same question of how many edge sequences one needs to fit a per-stream model versus querying a pretrained graph event foundation model.

Research Frontier: Foundation Models for Event Data

The two 2025 papers cited here (arXiv:2510.12640 and arXiv:2509.24762) are early demonstrations of a research direction that is moving rapidly. Open questions include: how large and how diverse must the pretraining corpus be to cover real-world domain heterogeneity, and can synthetic-only pretraining (Hawkes, Poisson) transfer to real earthquake or financial catalogs without domain adaptation? Can foundation TPP models handle marked event sequences (where each event carries a type, magnitude, or text description) as naturally as pure timestamp sequences? How do these models interact with the temporal graph event streams of Section 18.3, where events live on edges and the graph topology itself may evolve? And can foundation TPP pretraining be combined with the survival and time-to-event modeling of Section 18.4 to yield a single model family that handles both recurrent and absorbing event types? The EasyTPP benchmark (Xue and colleagues, 2024) is the current standard for comparing classical, neural, and foundation approaches on a common set of real-world event datasets, and it is the recommended starting point for researchers entering this space.

Exercises

The exercises split into conceptual, implementation, and open-ended, building directly on the intensity, simulator, and diagnostic above.

  1. Conceptual. The Hawkes branching ratio is $n = \int_0^\infty \phi(\tau)\,\mathrm{d}\tau = \alpha/\beta$ for the exponential kernel. (a) Show that the stationary (long-run average) intensity of a stable Hawkes process is $\bar\lambda = \mu/(1 - n)$, and explain why this diverges as $n \to 1$. (b) A seismologist estimates $\hat\alpha = 0.95$, $\hat\beta = 1.0$ from an aftershock catalog. What does the branching ratio say about the process, and what practical caution does a value this close to one imply for the simulator's stability and for forecasting?
  2. Implementation. Extend the from-scratch simulator of Code 18.2.1 to a marked Hawkes process in which each event carries a magnitude $m_i \sim \mathrm{Exp}(1)$ and the excitation it causes scales with its magnitude, $\phi(\tau, m_i) = \alpha\, m_i\, e^{-\beta\tau}$ (a simplified ETAS kernel). Simulate, then modify the log-likelihood of Code 18.2.2 to include the magnitude term and refit. Verify with the time-rescaling test of Code 18.2.4 that the marked model passes where an unmarked Hawkes model fit to the same data fails.
  3. Open-ended. Fit both a Hawkes model and an intensity-free neural TPP (via EasyTPP or your own log-normal-mixture density) to a real event log of your choice (for example a public GitHub-issue timestamp stream or a retweet cascade dataset). Compare them on held-out log-likelihood and on the time-rescaling KS statistic. Under what data characteristics (mark richness, sample size, presence of inhibition) does the neural model beat the Hawkes baseline, and when does the extra capacity merely overfit? Relate your finding to the diagnostic-gated escalation strategy of the trading-desk practical example.