BrowseFlow: Sparse Event Flow Matching for Generative User Simulation

Yitian Pang, Jiayi Zhang, Zhenjia Ma, Xiaowei Yue, Dagui Chen, Jian Xu
32 minread4.00scoreNo. 211-03 Personalization issue
Contents · 9 sections1What problem is it really solving?2The pipeline: pick a depth, then insert clicks3Why sample the depth first?4How are clicks inserted one by one?5What ruler is used?6What the results show7Limitations as I see them8How a recommendation team could try it9Verdict
Rel 4Nov 4Prac 4Evid 4Time 4

Shown the same feed, the same user might scroll to item 20 and click two things this time, and leave at item 8 the next; the log keeps only one of these. BrowseFlow is worth reading for teams building user simulators and offline evaluation, because it changes the goal from "copy that one log" to "learn the distribution of such outcomes", and gives a practical way to generate clicks directly. The core idea in one sentence: a browsing session is described by just two things, how deep the user scrolls and at which positions they click; the model first samples a depth, then inserts clicks one by one within that depth. On a dataset built from real Taobao recommendation logs, the energy score, which measures the gap between the generated and real outcome distributions, falls from 0.10847 for the best baseline to 0.07264, and the gap in click-count distribution falls from 0.2595 to 0.0697.

What problem is it really solving?

A user simulator answers "how would users scroll under a different recommendation" without going live. It has to generate the whole session: scrolling, clicking, liking, leaving. Most existing simulators predict step by step: is the next action a scroll, a click or an exit?

That has two problems. First, a log is a single sample. For the same user and the same feed, the outcome is random to begin with, as in this illustrative table:

Run (illustrative)Scrolled to itemClicked positions
1205, 14
283
312none

The log may contain only run 1. If a simulator is judged only by how closely it matches the log, it is pushed to output run 1 every time, and nobody can tell whether it gives runs 2 and 3 the right probability.

Second, clicks are rare. Across the paper's three datasets, only 1.52% to 5.96% of exposures carry a click or like; for the Taobao data it is 5.48%. When predicting step by step, almost every training target is "scroll", so the clicks that actually matter get little supervision. Generation has a knock-on effect too: a wrong "exit" midway means later clicks can never be generated.

Figure 1 of the paper: the top shows one session, mostly scrolls with few clicks, and a bar chart of the positive-feedback rate in three datasets; the bottom shows the same user on the same feed producing three different sessions, with different clicked items and exit points.
Figure 1 of the paper: the top shows one session, mostly scrolls with few clicks, and a bar chart of the positive-feedback rate in three datasets; the bottom shows the same user on the same feed producing three different sessions, with different clicked items and exit points.

The pipeline: pick a depth, then insert clicks

Figure 2 of the paper: BrowseFlow overview. Top left rewrites a session as "depth plus click list"; top middle predicts how deep the user scrolls from the user and the whole feed, then masks items beyond that depth; top right inserts clicks step by step starting from an empty list; the bottom shows training, where part of the real clicks are randomly kept and the model learns to fill in the missing ones.
Figure 2 of the paper: BrowseFlow overview. Top left rewrites a session as "depth plus click list"; top middle predicts how deep the user scrolls from the user and the whole feed, then masks items beyond that depth; top right inserts clicks step by step starting from an empty list; the bottom shows training, where part of the real clicks are randomly kept and the model learns to fill in the missing ones.

Three steps:

  1. Rewrite a session as two things: the final depth reached, and an ordered list of clicks, each recording the position and the clicked item. Scrolls are no longer modelled separately; given the depth and the click list, the scrolls in between can be reconstructed directly.
  2. A model reads the user profile, history and the whole feed, assigns a probability to each possible depth, and one depth is sampled.
  3. Items beyond that depth are masked, and clicks are inserted one by one within the depth, starting from an empty list. When insertion ends, a complete session is obtained.

The key division of labour: the depth model carries the randomness of "how far", and the insertion process carries "how many clicks and where". The next sections take these apart.

Why sample the depth first?

The depth decides which items the user can see, and clicks can only land on items that were seen. Sampling the depth first gives click generation a hard constraint: a session that leaves at item 8 can never click item 14.

The depth model outputs a probability distribution, not a single number. In the example above it might give depth 8 a 30% chance, 12 a 25% chance and 20 a 20% chance (illustrative). Each simulation draws again from this distribution, so the same user naturally produces sessions of different length. The paper's breakdown by depth compares it with UserSim (a step-by-step action simulator and the baseline with the lowest depth error): the two have similar depth errors on short sessions, but the gap grows with session length, and UserSim tends to underestimate long sessions.

How are clicks inserted one by one?

This step uses discrete flow matching, which can be read as a "gradual completion" process: starting from an empty list, each small step decides whether to insert a click, between which existing clicks, at which position, and on which item. Generation splits the completion progress from 0 to 1 into 32 equal intervals, and what is left when progress reaches 1 is the final click list. The number of clicks needs no separate predictor; it is simply how many insertions happened.

How is it taught to fill in? Take a real click list from a log, say one click at item 5 and one at item 14 (illustrative). Pick a random progress value and keep each real click with probability , dropping it with probability , which gives an incomplete list. At , perhaps only the click at item 14 survives. The model learns which clicks are missing from this incomplete list and where each should go. The closer is to 1, the less is left to fill in.

The paper splits "how much to insert in the next small step, and what" into a total intensity times an allocation:

The intensity and the allocation come from the same network, whose inputs are user history, the feed with item attributes beyond the depth masked (both encoded once by Transformers and fixed during insertion), the sampled depth, the current click list (re-encoded after every insertion) and the progress . is the total insertion intensity at this step, which governs whether to keep inserting and how much; spreads that intensity over the valid insertions, where covers between which clicks, at which position and on which item. Valid insertions only include items within the depth that have not been clicked yet, so the output satisfies the exposure constraint by construction.

In training, the deleted real clicks directly become the targets for both quantities. If the partial list is missing clicks, the insertion loss is

The two terms with push the total intensity times the remaining progress toward the number of missing clicks : the more is missing, the faster it inserts (Eq. 16 of the paper). The term with puts the allocation's probability on the insertion matching each truly missing click . The depth model is trained separately with an ordinary classification loss on the logged depth, and the two losses are summed (Eqs. 14 and 15).

Within each of the 32 intervals, a waiting time is first drawn from an exponential distribution with rate equal to the total intensity , so the mean wait is and higher intensity means shorter waits. If the wait falls within what is left of the interval, one insertion is drawn from the allocation and added to the list, the intensity is recomputed on the new list, and the next wait is drawn; if the wait runs past the interval, generation moves on to the next one. So an interval may insert zero clicks or several. If an interval has no valid position or the intensity is 0, that interval ends; later intervals still run, because the intensity changes with progress.

Why not generate front to back in browsing order? In the ablation, a version that also uses flow matching but can only add new clicks at the end of the list has a click-count gap of 0.09407, while allowing insertion in between brings it to 0.06969. Insertion can place a new click between two already generated ones; with the depth-plus-click-list representation, this brings the click-count distribution closer to reality with almost no change in energy score.

What ruler is used?

Since outcomes are random, evaluation cannot just measure closeness to the log. The paper uses the energy score, which first needs a distance between two sessions: on Taobao, the whole session is encoded as 401 slots: the first 400 record each action in browsing order (keep scrolling, or clicked which item), unused slots are filled with padding, and the last slot records where the session ended. Two sessions are compared slot by slot, and the larger the share of differing slots, the larger the distance; on Kuaishou and AdSERP it compares click or no click position by position. For each context it then generates K simulated sessions, and the score is the average distance from the K sessions to the real log minus the sum of pairwise distances among them divided by K(K−1); lower is better:

is the real log, the -th simulated session and the distance above. The second term is subtracted, so variety among simulated sessions earns credit. In expectation the score has a useful property: averaged over many contexts, it is lowest only when the generated distribution matches the real one, so always outputting the same outcome or generating at random both make the average worse. The second ruler is the gap between click-count distributions (the paper calls it Count W1): turn the real click counts across all contexts and the simulated ones into cumulative distributions (the share of sessions with at most 0, 1, 2 ... clicks), take the absolute difference of the two cumulative shares at each count, and add them all up; smaller means closer.

What the results show

Three datasets: TaobaoBrowse, built from real Taobao recommendation logs (100K training examples), Kuaishou's like data KuaiRand-Like, and AdSERP, with clicks on search result pages. TaobaoBrowse is a new benchmark released with the paper: it keeps the real recommendation page, the item-by-item scroll trace and the click targets together, whereas existing public datasets (such as Kuaishou's KuaiRand) lack an item-level exposure trace. Among the six baselines, UBM (user browsing model) and DBN (dynamic Bayesian network click model) are classic click models from search that model whether the user saw an item and, if so, whether they clicked. UserSim, KuaiSim and others are simulators that generate actions step by step.

DatasetMetricBest baselineBrowseFlow
TaobaoBrowseEnergy score0.10847 (DBN)0.07264
TaobaoBrowseClick-count gap0.2595 (UserSim)0.0697
KuaiRand-LikeClick-count gap0.0363 (CaseRec)0.0207
KuaiRand-LikeEnergy score0.02736 (UserSim)0.02703
AdSERPEnergy score0.15218 (RL4RS-DIEN)0.14271
AdSERPClick-count gap0.4626 (UserSim)0.1215

On the click-count distribution, the new representation plus insertion matters a lot: on the Taobao data the gap is about a quarter of the best baseline's. The energy score needs a separate reading. On Taobao the plainest ablation variant (full action sequence, step-by-step generation) already scores 0.07815, better than every baseline. Representation plus insertion only take it to 0.07264, so the paper does not isolate where most of that advantage comes from. On KuaiRand-Like the energy score improves by only about 1%, which the paper itself calls a modest gain. On the other side, BrowseFlow's TaobaoBrowse AUC of 0.6126 beats only UserSim and is below the other five baselines (the best is RL4RS-DIEN at 0.6592); on the other two datasets it is close to the best. BrowseFlow does not specifically optimize per-position click prediction. Judging single positions well is not the same as learning the distribution of whole sessions, and the two abilities need separate evaluation.

The ablation separates the two changes. Changing only the representation while keeping ordinary step-by-step autoregressive generation takes the click-count gap from 0.45158 to 0.38071; switching only to flow matching on the step-by-step action sequence takes it to 0.12666. Using both the sparse representation and flow matching, plus insertion, gets 0.06969. Insertion on the full action sequence collapses to 2.56907; the paper gives no reason, and one plausible explanation is that inserting among a mass of scroll actions breaks the structure too easily. So insertion only helps together with the sparse representation.

Limitations as I see them

First, each dataset has a single kind of key event: clicks for Taobao and AdSERP, likes for Kuaishou. In e-commerce, add-to-cart, saves and purchases often coexist, and the insertion process would also have to choose the event type, which I expect to be noticeably harder.

Second, the feed is fixed. The whole page of recommendations is given before simulation, and the recommender does not change content in response to earlier clicks. Real feeds load and recommend as the user scrolls, and this simulator cannot yet plug into that loop.

Third, local judgment is weaker. On TaobaoBrowse its AUC of 0.6126 is below five of the six baselines, so if the downstream use is per-item click-rate estimation, BrowseFlow is not the better choice.

How a recommendation team could try it

  1. Change only the ruler first. On the existing simulator, sample the same contexts several times and compute the energy score and click-count gap, to see whether it keeps copying the log and barely varies across samples.
  2. Then change only the representation: rewrite sessions as depth plus click list, predict depth with a classifier, and keep generating clicks with the current method. The ablation shows this step alone helps, and it is the cheapest.
  3. If that works, add insertion-based generation and watch the click-count distribution, especially whether the share of sessions with no click matches reality.
  4. Finally, use the simulator for offline policy evaluation and check whether its ranking of two recommendation policies matches the direction of their online A/B test, which is what a simulator is really for.

Verdict

The main lesson: a user simulator should learn the distribution of possible outcomes for a feed, and its evaluation should be able to tell whether it did. BrowseFlow gets there with the "depth plus click list" representation and insertion-based generation, at the cost of a TaobaoBrowse per-item AUC (0.6126) below five of the six baselines.

DimensionAssessment
Problem importanceMedium-high. Simulators underpin offline evaluation and RL for recommendation, and one that only copies logs gives overconfident conclusions
NoveltyMedium-high. Rewriting sessions as depth plus click list and generating with insertion-based flow matching is a new combination for user simulation
EvidenceMedium. Three datasets, six baselines and a clear ablation; no check of whether the simulator predicts how online policies rank
Engineering costMedium. The representation change is simple; flow matching training and a 32-interval generation loop that re-runs the network after every insertion need extra implementation
Worth tryingYes. First switch the ruler to see how far the current simulator's distribution is off; then try the sparse representation, which is cheap and whose gain is backed by the ablation

How did this read for you?

One tap, no sign-in; tap again to undo. Only anonymous counts are kept, never who you are.

Discussion

Add experiment details, reproduction notes or a different take. Requires a GitHub sign-in.

Loading the discussion…