event2vec · scikit-learn estimator · v0.1

Event sequences,
composed as vectors.

Event2Vec learns an embedding for each discrete event so that a sequence is the sum of its events. Two geometries, one estimator: Euclidean for flat trajectories, hyperbolic (Möbius addition on the Poincaré ball) for tree-like, hierarchical data — less distortion, the same compositional loss.

$ pip install event2vector
view source read paper
geometryEuclidean · Hyperbolic Poincaré ball
compositionva ⊕ vb ⊕ vc
API.fit · .transform · .most_similar
parallelpadded-batch variable-length

Most data is a
sequence of events.

clickstreams · journeys · ledgers · logs · lifecycles

Clickstreams, purchase histories, patient timelines, support tickets, system logs — a huge share of real-world data is just discrete events in order. Event2Vec turns each sequence into a single vector you can compose, compare, and explain — not another black box you can only score.

compose & decompose

A trajectory is the sum of its events. Add embeddings to assemble a journey; subtract them to isolate a transition — the step from first_job to promotion is itself a reusable “career move” vector you can apply elsewhere.

interpretable by design

No opaque hidden state — the geometry is the model. Distance is similarity, and the vector between two events is their relationship, so you can audit and reason about a whole trajectory rather than just predict the next step.

drop-in & light

A scikit-learn-style estimator — fit · transform · most_similar. Variable-length sequences via padded batches, CPU or GPU, and pip install event2vector to start.

Compose a life.
Watch its vector grow.

a sequence is the sum of its events · the model calls what's next

Event2Vec never looks at an event on its own — it learns from sequences. Here each example is a life trajectory — birth, school, a first job, a marriage — and during training the model reads the running total so far and predicts the next stage. So a trajectory is the sum of its events, and that sum is enough to call what comes next. Click events to build a life and watch its embedding take shape on the Poincaré ball 𝔻², where each step is composed by Möbius addition and the order you live them in leaves a trace. Events are coloured by life tier — childhood, career, family, finance… — and related stages settle into the same neighbourhood of the disk. This one demo is a deliberately simple, synthetic model, here to show the mechanism cleanly — the real-data evidence is in the sections below.

|s| 0 d(0,s)𝔻 0.00

Hyperbolic 𝔻² · Möbius addition ·

life tiers · events colour by stage

career and family each settle into their own arc of the disk; early life clusters near the centre and fans outward as a life unfolds.

life events ·
trajectory ·
predict →
add an event, or click a predicted chip to append it · play it out lets the model live the rest of the trajectory to its end

Compose to predict.
Decompose to explain.

additive contribution · which events drive an outcome

Because a trajectory is the sum of its events, the model's score for any next event o splits cleanly across the past: score(o) = Σi ei·wo + b. Every event carries a fixed contribution e·w toward — or away from — that outcome, so you can add them to see what a sequence is driving at, or remove one (a counterfactual) to see what it was responsible for. Same model as the composer above — the synthetic life-trajectory model; here an “outcome” is a later life event, and each earlier stage's contribution shows how strongly it pushes the model toward predicting it.

What drives “retirement” next? · contribution e·w across the vocabulary
Why the scholar reaches “retirement· additive climb, step by step

Flat space crowds.
Curved space breathes.

same taxonomy · ℝ² vs the Poincaré ball

A taxonomy is a set of root→leaf paths; each node sits at the composed state of its own path. In the Euclidean plane the paths pile up near each other. In the hyperbolic Poincaré ball the recurrence folds outward from the centre, so branches fan into their own angular sectors and leaves push toward the boundary — exponential room for a tree, the property the paper leans on. Hover a node to trace its lineage to the root.

Euclidean ℝ² · cumulative sum
Hyperbolic 𝔻² · Möbius, Poincaré ball
hover (or tap) a node to highlight its path to the root

Not hand-waving.
Measured.

real numbers · from the paper & this page
0.00 0.25
order sensitivity · Δ

Plain addition commutes, so the Euclidean model can't tell butter→flour from flour→butter (Δ = 0). Möbius addition can — Δ grows to 0.25 in 16-d. That gap is exactly why Event2Vec ships two geometries.

≈ 0.70
composition fidelity · len 50

The recurrent state stays within ~0.7 cosine of the exact vector sum of its events, even for 50-event sequences — the additive hypothesis holds in practice, not just in theory.paper · fig. 12

2.6×
vs Word2Vec · silhouette

On the Brown corpus it organizes grammatical structure at silhouette 0.0564 against Word2Vec's 0.0215 — more than double, with no supervision.paper · §5.2

9,000
real recipes · live, on CPU

The vectors in the demo above are a real event2vector run on ~9,000 real recipes (the 13k Kaggle dataset) — fit in seconds on a laptop, weights baked into this page.

Same estimator.
Five real datasets.

letters · phonemes · grammar · concept hierarchy · recipes · all open data

The composer above runs on synthetic recipes. Here is the unchanged event2vector package on three real, public datasets — each one fetched, sequence-built and trained by a script in code/. Every plot below is a genuine run: Event2Vec beside a Word2Vec baseline on the very same sequences, coloured by a ground-truth taxonomy the model never saw.

One estimator,
two geometries.

event2vec.Event2Vec
event2vec · Euclidean estimator
from event2vector import Event2Vec

# events: list[list[int]] — variable-length token sequences
model = Event2Vec(
    num_event_types=len(vocab),
    geometry="euclidean",
    embedding_dim=128,
    pad_sequences=True,
    num_epochs=50,
)

model.fit(train_sequences, verbose=True)
train_emb = model.transform(train_sequences)

# gensim-style nearest-neighbour lookup
model.most_similar("bake", topn=3)
# → [("fry", .93), ("boil", .91), ("cheese", .67)]  # cooking events cluster
geometries euclidean · hyperbolic dim 128 batched padded ✓ device cuda · mps · cpu stable API fit · fit_transform · transform

The paper.

Full derivation of the additive recurrence loss, padded-batch training, and the Brown-corpus POS evaluation are in Sulc, A. Event2Vec: A Geometric Approach to Learning Composable Representations of Event Sequences, arXiv:2509.12188.

Reference implementation, the Brown-corpus POS pipeline, and a minimal runnable example live in the public repository.

bibtex
@article{sulc2025event2vec,
  title   = {Event2Vec: A Geometric Approach to Learning
             Composable Representations of Event Sequences},
  author  = {Sulc, Antonin},
  journal = {arXiv preprint arXiv:2509.12188},
  year    = {2025}
}