Skip to content

Generation Models

Flow models

API Description Example
Gravity Gravity model: flows between places from their sizes and the distance between them. Fit and run a gravity model
Gravity.fit Fit the Gravity model parameters to observed flows via Poisson regression. Fit and run a gravity model
Gravity.fit_statistics Goodness-of-fit statistics of the last fit. The distance decay, with a confidence interval
Gravity.fit_summary The fitted parameters with standard errors, confidence intervals and p-values. The distance decay, with a confidence interval
Gravity.generate Generate synthetic flows with the Gravity model. Fit and run a gravity model
Radiation Radiation model: flows between places from their populations and the opportunities in between. Flows
Radiation.generate Generate synthetic flows with the Radiation model. Flows

Individual trajectory models

API Description Example
EPR Exploration and Preferential Return (EPR) trajectory generator. Exploration and preferential return
EPR.generate Simulate agents from start_date to end_date. Exploration and preferential return
DensityEPR Density-EPR (d-EPR) trajectory generator. Exploration and preferential return
DensityEPR.generate Simulate agents from start_date to end_date. Exploration and preferential return
SpatialEPR Spatial-EPR (s-EPR) trajectory generator. Exploration and preferential return
SpatialEPR.generate Simulate agents from start_date to end_date. Exploration and preferential return
Ditras DITRAS (DIary-based TRAjectory Simulator) modelling framework. Realistic daily rhythm
Ditras.generate Simulate agents from start_date to end_date. Realistic daily rhythm
MarkovDiaryGenerator Markov diary learner and generator: when a person is at home or away, hour by hour. Realistic daily rhythm
MarkovDiaryGenerator.fit Learn the Markov mobility diary from real trajectories. Realistic daily rhythm
MarkovDiaryGenerator.generate Generate a synthetic mobility diary. Realistic daily rhythm

Social trajectory models

API Description Example
GeoSim GeoSim social trajectory generator. Social ties
GeoSim.generate Simulate a socially connected population from start_date to end_date. Social ties
STS_epr STS-EPR (Spatial, Temporal, and Social EPR) trajectory generator. Social ties
STS_epr.generate Simulate a socially connected population from start_date to end_date. Social ties

Next-location prediction

API Description Example
NextLocationPredictor Order-k Markov next-location predictor with optional backoff. Predict the next place
NextLocationPredictor.evaluate Holdout-last-n_holdout accuracy over the data given to fit. Predict the next place
NextLocationPredictor.fit Fit one Markov model per user from each user's location-id sequence. Predict the next place
NextLocationPredictor.predict Predict each fitted user's single most likely next location. Predict the next place
NextLocationPredictor.predict_proba Predict each fitted user's next location(s) from their own training history's tail. Predict the next place

The fastmob.models package mirrors the original scikit-mobility generation API. Model implementations accept pandas or Narwhals-compatible eager dataframes and may convert inputs to pandas internally.

Only Gravity.fit() needs Statsmodels for Poisson-GLM fitting:

pip install statsmodels

Flow Models

Fitting flows with custom column names

Gravity.fit accepts a FlowDataFrame with an attached Locations catalogue, or a dataframe or FlowDataFrame with the catalogue passed as locations=. The origin and destination values must match its location IDs, and the catalogue must contain the selected relevance column (population or another measure of location size). For an existing pandas table flows_df with columns Area_O, Area_D, and Weight_Day, and a prepared locations catalogue:

from fastmob.core import FlowDataFrame
from fastmob.models import Gravity

flows = FlowDataFrame(flows_df, locations=locations)
model = Gravity()
model.fit(
    flows,
    origin_col="Area_O",
    destination_col="Area_D",
    flow_col="Weight_Day",
    relevance_column="relevance",
)

For an OD table without an attached catalogue, pass it directly:

model.fit(flows_df, locations=locations, origin_col="Area_O",
          destination_col="Area_D", flow_col="Weight_Day")

An explicit locations argument takes precedence over an attached catalogue.

The default names are origin, destination, and flow. Alternatively, FlowDataFrame can rename input columns to those defaults using its origin, destination, and flow constructor arguments; in that case use the default names when fitting. See the worked example for preparing locations and interpreting a fit.

Gravity

Gravity model: flows between places from their sizes and the distance between them.

The Gravity model of human migration. In its original formulation, the probability \(T_{ij}\) of moving from location \(i\) to location \(j\) is proportional to [Z1946]:

\[ T_{ij} \propto \frac{P_i P_j}{r_{ij}} \]

where \(P_i\) and \(P_j\) are the populations (or relevances) of locations \(i\) and \(j\) and \(r_{ij}\) is the distance between them. The general form is [BBGJLLMRST2018]:

\[ T_{ij} = K m_i m_j f(r_{ij}) \]

where \(K\) is a constant and \(f(r_{ij})\) is a deterrence function — a decreasing function of distance commonly modelled as a power law or exponential.

Singly constrained variant. When the total outflow \(O_i\) from each origin is known, the model estimates destinations only:

\[ T_{ij} = O_i \frac{m_j f(r_{ij})}{\sum_k m_k f(r_{ik})}. \]

Globally constrained variant. Only the total flow of the whole system is fixed, through a single constant \(K\):

\[ T_{ij} = K m_i^{a} m_j^{b} f(r_{ij}), \qquad \sum_{ij} T_{ij} = \sum_i O_i. \]

Parameters:

Name Type Description Default
deterrence_func_type str

The deterrence function to use. Accepted values: "power_law" and "exponential". The default is "power_law".

'power_law'
deterrence_func_args list

Arguments for the deterrence function. For "power_law" this is the exponent; for "exponential" it is the decay rate. The default is [-2.0].

None
origin_exp float

Exponent applied to the origin's relevance (only used in the globally constrained model). The default is 1.0.

1.0
destination_exp float

Exponent applied to the destination's relevance. The default is 1.0.

1.0
gravity_type str

The model variant. Accepted values: "singly constrained" and "globally constrained". The default is "singly constrained".

'singly constrained'
name str

Human-readable label for this model instance. The default is "Gravity model".

'Gravity model'

Attributes:

Name Type Description
deterrence_func_type str

The deterrence function in use.

deterrence_func_args list

Arguments for the deterrence function.

origin_exp float

Exponent applied to the origin's relevance.

destination_exp float

Exponent applied to the destination's relevance.

gravity_type str

The model variant ("singly constrained" or "globally constrained").

name str

Human-readable label of this model instance.

Notes

The places are given as a Locations catalogue (Locations.from_tessellation builds one from a table with a tile id, latitude, longitude, a relevance column and, to generate flows, a total outflow column).

Examples:

>>> import pandas as pd
>>> from fastmob.core import Locations
>>> from fastmob.models import Gravity
>>> tessellation = pd.DataFrame({
...     "tile_id": [0, 1, 2, 3],
...     "lat": [40.71, 41.88, 37.77, 33.44],
...     "lng": [-74.01, -87.62, -122.42, -112.07],
...     "relevance": [1_000_000, 2_700_000, 880_000, 1_600_000],
...     "tot_outflow": [100_000, 250_000, 90_000, 150_000],
... })
>>> locations = Locations.from_tessellation(tessellation, tile_id_col="tile_id", lat_col="lat", lng_col="lng")
>>> gravity = Gravity(gravity_type="singly constrained")
>>> print(gravity)
Gravity(name="Gravity model", deterrence_func_type="power_law", deterrence_func_args=[-2.0], origin_exp=1.0, destination_exp=1.0, gravity_type="singly constrained")
>>> flows = gravity.generate(locations, out_format="flows")
>>> int(round(flows.to_pandas()["flow"].sum()))
590000
References

.. [Z1946] Zipf, G. K. (1946). The P1 P2/D Hypothesis: On the Intercity Movement of Persons. American Sociological Review, 11(6), 677–686. .. [W1971] Wilson, A. G. (1971). A family of spatial interaction models, and associated developments. Environment and Planning A, 3(1), 1–32. .. [BBGJLLMRST2018] Barbosa, H. et al. (2018). Human mobility: Models and applications. Physics Reports, 734, 1–74.

See Also

Radiation

fit(flow_df, relevance_column=RELEVANCE, robust=True, include_zeros=True, *, origin_col='origin', destination_col='destination', flow_col=FLOW, locations=None, origin_relevance_column=None, destination_relevance_column=None, cov_type=None)

Fit the Gravity model parameters to observed flows via Poisson regression.

Uses a Generalised Linear Model (GLM) with a Poisson family and log link to estimate destination_exp and deterrence_func_args (and origin_exp for the globally constrained variant) from real flows [FM1982].

Parameters:

Name Type Description Default
flow_df FlowDataFrame or dataframe

Observed flows. Supply a Locations catalogue via locations or on the FlowDataFrame (as on the one returned by Gravity.generate()). The table must contain origin, destination and flow columns by default. List only the pairs with flow: the pairs without flow are added as zeros (see include_zeros).

required
relevance_column str

Name of the column of the locations catalogue that holds the location relevance (e.g. population). It is used for the origin and the destination unless origin_relevance_column or destination_relevance_column is given. The default is "relevance".

RELEVANCE
robust bool

Report heteroskedasticity-robust (sandwich) standard errors and confidence intervals. Real flows are usually overdispersed relative to the Poisson model, which makes the model-based errors too small; the point estimates are the same either way. Default True. cov_type overrides it.

True
include_zeros bool

Add every pair of locations that is missing from flow_df as a flow of 0. Tables of observed flows, such as the output of trajectory_to_od, list only the pairs with flow, and fitting those alone biases the distance coefficient towards zero because the long pairs that nobody travels are missing (Santos Silva and Tenreyro, 2006). The added pairs are the off-diagonal pairs of the catalogue whose origin has at least one observed flow. The singly constrained fit needs memory for one row per pair (the square of the number of locations: about 400 MB and 10 seconds for 1,000 locations); pass False only when the table already lists every pair, as complete matrices do. Default True.

True
origin_col str

Name of the origin column in the flow table. Default "origin".

'origin'
destination_col str

Name of the destination column in the flow table. Default "destination".

'destination'
flow_col str

Name of the flow column in the flow table. Default "flow".

FLOW
locations Locations

Location catalogue to use for fitting. When supplied, it takes precedence over a catalogue attached to flow_df. Required for a native dataframe or a flow object without a catalogue.

None
origin_relevance_column str

Column of the catalogue with the size of the origin (the outflow side, for example residents or departures). Default: relevance_column. Only the globally constrained model has an origin size term (origin_exp); the singly constrained model absorbs the origin in one level per origin, so naming a column there is an error.

None
destination_relevance_column str

Column of the catalogue with the size of the destination (the inflow side, for example jobs or arrivals). Default: relevance_column.

None
cov_type ('nonrobust', 'HC0', 'HC1')

Covariance estimator of the standard errors. "nonrobust" is the model-based Poisson one, "HC0" the sandwich estimator and "HC1" the same with the small-sample factor n / (n - k), where n is the number of flows and k the number of fitted coefficients (including one level for each origin in the singly constrained model), as in statsmodels. The estimates do not depend on it. Default: "HC0" when robust is True, otherwise "nonrobust".

"nonrobust"

Raises:

Type Description
ImportError

If statsmodels is not installed (only the globally constrained variant needs it).

AttributeError

If no locations catalogue is supplied or attached to flow_df.

TypeError

If locations is not a Locations catalogue.

KeyError

If a selected flow column is missing.

ValueError

If the design matrix is rank-deficient (too few distinct origins or distances), cov_type is not one of the options, or origin_relevance_column is given for the singly constrained model.

Notes

Modifies deterrence_func_args, destination_exp, and (for the globally constrained variant) origin_exp in-place.

After fitting, fit_summary returns the estimates with standard errors, 95% confidence intervals and p-values, and fit_statistics the number of flows used, the log-likelihood, the deviance, the pseudo R-squared and the dispersion. For "power_law" the distance coefficient is the exponent gamma of flow ∝ distance^gamma (negative: flows fall with distance); for "exponential" the table reports the decay rate lambda of exp(-lambda * distance) in km^-1 (positive: flows fall with distance). Relevance that is itself made of the flows (for example check-ins counted in the destination) makes the destination exponent partly circular; prefer an independent size such as population or jobs.

References
  • [FM1982] Flowerdew, R. & Murray, A. (1982). A method of fitting the gravity model based on the Poisson distribution. Journal of Regional Science, 22(2), 191–202.
  • [ST2006] Santos Silva, J. M. C. & Tenreyro, S. (2006). The log of gravity. The Review of Economics and Statistics, 88(4), 641–658.

Examples:

>>> import pandas as pd
>>> from fastmob.core import Locations
>>> from fastmob.models import Gravity
>>> places = pd.DataFrame({
...     "tile_id": range(6),
...     "lat": [45.0, 45.1, 45.3, 45.2, 45.6, 45.5],
...     "lng": [7.0, 7.4, 7.1, 7.9, 7.6, 7.2],
...     "relevance": [9_000, 7_000, 5_000, 3_000, 8_000, 6_000],
...     "tot_outflow": [60_000, 50_000, 40_000, 30_000, 70_000, 45_000],
... })
>>> locations = Locations.from_tessellation(places, tile_id_col="tile_id", lat_col="lat", lng_col="lng")
>>> observed = Gravity(deterrence_func_args=[-2.0]).generate(locations, out_format="flows")
>>> model = Gravity()
>>> model.fit(observed)
>>> round(model.deterrence_func_args[0], 2)
-2.0
>>> model.fit_summary().column("parameter").to_pylist()
['destination_exp', 'distance_coefficient']

fit_statistics()

Goodness-of-fit statistics of the last fit.

Returns:

Type Description
dict

n_observations (flows used), log_likelihood, deviance, pseudo_r_squared (one minus the ratio of the deviance to the null deviance), dispersion (Pearson chi-squared per degree of freedom; well above 1 means overdispersion), robust_errors and cov_type (the covariance estimator of the standard errors).

Raises:

Type Description
RuntimeError

If fit has not been called.

fit_summary()

The fitted parameters with standard errors, confidence intervals and p-values.

Returns:

Type Description
Table

One row per model parameter with parameter, estimate, std_error, ci_low, ci_high (95%) and p_value. For the exponential deterrence function the distance row is distance_decay, the decay rate lambda of exp(-lambda * distance) in km^-1; otherwise distance_coefficient is the exponent of the distance.

Raises:

Type Description
RuntimeError

If fit has not been called.

generate(locations, tot_outflows_column=TOT_OUTFLOW, relevance_column=RELEVANCE, out_format='flows', random_state=None)

Generate synthetic flows with the Gravity model.

Parameters:

Name Type Description Default
locations Locations

Global locations on which to run the model. They must provide a relevance column and, for "flows" and "flows_sample" output, a total-outflow column.

required
tot_outflows_column str

Name of the column containing the total outflow per location. Required when out_format is "flows" or "flows_sample". The default is "tot_outflow".

TOT_OUTFLOW
relevance_column str

Name of the column containing the location relevance (e.g. population). The default is "relevance".

RELEVANCE
out_format str

Format of the output. Accepted values:

  • "flows" — expected (average) flows between each pair of locations.
  • "flows_sample" — randomly sampled integer flows.
  • "probabilities" — probability of a trip from each origin to each destination (does not require tot_outflows_column).

The default is "flows".

'flows'

Returns:

Type Description
DataFrame

A dataframe with columns origin, destination, and flow (or probability). A to_matrix() method converts this to a 2-D numpy array.

Raises:

Type Description
KeyError

If out_format requires a total-outflow column but it is absent from locations.

Worked example: Fit and run a gravity model · The distance decay, with a confidence interval


Radiation

Radiation model: flows between places from their populations and the opportunities in between.

The radiation model for human migration. The model assumes that a traveller's destination choice follows two steps: each opportunity at every location is assigned a random fitness drawn from a distribution \(P(z)\), and the traveller accepts the closest opportunity whose fitness exceeds a threshold drawn from the same distribution. The resulting average flow from \(i\) to \(j\) is [SGMB2012]:

\[ T_{ij} = O_i \frac{1}{1 - \frac{m_i}{M}} \frac{m_i m_j}{(m_i + s_{ij})(m_i + m_j + s_{ij})} \]

where \(O_i\) is the total outflow from location \(i\), \(m_i\) (\(m_j\)) is the relevance (e.g. population) at the origin (destination), \(s_{ij}\) is the total relevance within the circle of radius \(r_{ij}\) centred on \(i\) excluding origin and destination, and \(M = \sum_i m_i\) is the total system relevance.

Parameters:

Name Type Description Default
name str

Human-readable label for this model instance. The default is "Radiation model".

'Radiation model'

Attributes:

Name Type Description
name str

Human-readable label of this model instance.

Notes

Generation accepts Locations with global location IDs and numeric centre coordinates.

Examples:

>>> import pandas as pd
>>> from fastmob.core import Locations
>>> from fastmob.models import Radiation
>>> locations = Locations(pd.DataFrame({
...     "tile_id": [0, 1, 2, 3],
...     "lat": [40.71, 41.88, 37.77, 33.44],
...     "lng": [-74.01, -87.62, -122.42, -112.07],
...     "relevance": [1_000_000, 2_700_000, 880_000, 1_600_000],
...     "tot_outflow": [100_000, 250_000, 90_000, 150_000],
... }))
>>> radiation = Radiation()
>>> rad_flows = radiation.generate(locations, tot_outflows_column="tot_outflow",
...                                relevance_column="relevance",
...                                out_format="flows_sample")
>>> print(rad_flows.head())
References

.. [SGMB2012] Simini, F., González, M. C., Maritan, A. & Barabási, A.-L. (2012). A universal model for mobility and migration patterns. Nature, 484(7392), 96–100. .. [MSJB2013] Masucci, A. P., Serras, J., Johansson, A. & Batty, M. (2013). Gravity versus radiation models: On the importance of scale and heterogeneity in commuting flows. Physical Review E, 88(2), 022812.

See Also

Gravity

generate(locations, tot_outflows_column=TOT_OUTFLOW, relevance_column=RELEVANCE, out_format='flows', random_state=None)

Generate synthetic flows with the Radiation model.

Parameters:

Name Type Description Default
locations Locations

Global locations on which to run the model. Must include a relevance column; the total-outflow column is required when out_format is "flows" or "flows_sample".

required
tot_outflows_column str

Name of the column containing the total outflow per location. Required when out_format is "flows" or "flows_sample". The default is "tot_outflow".

TOT_OUTFLOW
relevance_column str

Name of the column containing the location relevance (e.g. population). The default is "relevance".

RELEVANCE
out_format str

Format of the output. Accepted values:

  • "flows" — expected (average) flows between each pair of locations.
  • "flows_sample" — randomly sampled integer flows drawn from a multinomial distribution.
  • "probabilities" — raw trip probability from each origin to each destination (does not require tot_outflows_column).

The default is "flows".

'flows'

Returns:

Type Description
DataFrame

A dataframe with columns origin, destination, and flow (or probability). A to_matrix() method converts this to a 2-D array indexed by location order.

Raises:

Type Description
KeyError

If out_format requires a total-outflow column but it is absent from locations.

ValueError

If out_format is not one of the accepted values.

Worked example: Flows


Individual Trajectory Models

EPR

Exploration and Preferential Return (EPR) trajectory generator.

The EPR model generates synthetic individual mobility trajectories based on two competing mechanisms drawn from empirical observations of human travel patterns [SKWB2010]:

Waiting time choice. The time \(\Delta t\) between consecutive moves is drawn from a truncated power law:

\[ P(\Delta t) \sim \Delta t^{-1-\beta} \exp(-\Delta t / \tau). \]

Action selection. With probability \(P_{\text{new}} = \rho S^{-\gamma}\), where \(S\) is the number of distinct previously visited locations, the agent explores a new location; otherwise it returns to a previously visited one.

Exploration. The new location \(j \neq i\) is chosen with probability proportional to the gravity-model score \(p_{ij}\) derived from gravity_singly.

Return. A previously visited location \(i\) is chosen with probability \(\Pi_i = f_i\), proportional to its visitation frequency.

This class is the base for DensityEPR, SpatialEPR, and Ditras.

Parameters:

Name Type Description Default
name str

Human-readable label for this model instance. The default is "EPR model".

'EPR model'
rho float

Exploration parameter \(\rho \in (0, 1]\) in \(P_{\text{new}} = \rho S^{-\gamma}\). Controls the overall tendency to explore new locations. The default is 0.6 [SKWB2010].

0.6
gamma float

Return-penalty exponent \(\gamma \geq 0\) in \(P_{\text{new}} = \rho S^{-\gamma}\). Larger values cause agents to return more frequently as they accumulate visited locations. The default is 0.21 [SKWB2010].

0.21
beta float

Tail exponent \(\beta\) of the waiting-time distribution. The default is 0.8 [SKWB2010].

0.8
tau int

Characteristic time scale \(\tau\) (in hours) of the waiting-time distribution. The default is 17 [SKWB2010].

17
min_wait_time_minutes int

Minimum waiting time between two moves, in minutes. The default is 20.

20

Attributes:

Name Type Description
name str

Human-readable label of this model instance.

rho float

The exploration parameter \(\rho\).

gamma float

The return-penalty exponent \(\gamma\).

beta float

The waiting-time tail exponent \(\beta\).

tau int

The waiting-time scale \(\tau\) (in hours).

min_wait_time float

Minimum waiting time in hours (min_wait_time_minutes / 60).

spatial_tessellation_ DataFrame or None

The tessellation used in the last generate() call.

trajectories_ list

Raw trajectory records produced by the last generate() call.

References

.. [SKWB2010] Song, C., Koren, T., Wang, P. & Barabási, A.-L. (2010). Modelling the scaling properties of human mobility. Nature Physics, 6, 818–823.

See Also

DensityEPR, SpatialEPR, Ditras

generate(start_date, end_date, spatial_tessellation, gravity_singly=None, n_agents=1, starting_locations=None, relevance_column=RELEVANCE, random_state=None)

Simulate agents from start_date to end_date.

Parameters:

Name Type Description Default
start_date Timestamp or datetime

Start time of the simulation.

required
end_date Timestamp or datetime

End time of the simulation.

required
spatial_tessellation DataFrame or GeoDataFrame

Division of the territory into locations. Must include either a geometry column or explicit lat / lng columns.

required
gravity_singly Gravity or None

A singly constrained Gravity model used to derive origin–destination trip probabilities. If None, a default Gravity(gravity_type="singly constrained") is created automatically. The default is None.

None
n_agents int

Number of agents to simulate. The default is 1.

1
starting_locations list of int or None

One starting tessellation index per agent. Length must equal n_agents. If None, starting locations are chosen uniformly at random. The default is None.

None
relevance_column str

Name of the column in spatial_tessellation used as location relevance for the gravity model. The default is "relevance".

RELEVANCE
random_state int or None

Seed for the random number generator, enabling reproducible results. The default is None (non-deterministic).

None

Returns:

Type Description
DataFrame

Synthetic trajectories with columns uid, datetime, lat, and lng. One row per recorded position.

Raises:

Type Description
IndexError

If starting_locations is provided and has fewer entries than n_agents.

TypeError

If gravity_singly is not a Gravity instance.

AttributeError

If gravity_singly is a Gravity instance but its gravity_type is not "singly constrained".

Worked example: Exploration and preferential return


DensityEPR

Bases: EPR

Density-EPR (d-EPR) trajectory generator.

The d-EPR model weights exploratory moves according to a gravity model that accounts for location relevance (e.g. population density) [PSRPGB2015][PSR2016]. EPR explores with the same gravity score, so DensityEPR and EPR produce the same trajectories for equal inputs and seed; this class is provided under the name used in the literature. The four mechanisms are:

Waiting time choice. The waiting time \(\Delta t\) between two moves is drawn from \(P(\Delta t) \sim \Delta t^{-1-\beta} \exp(-\Delta t/\tau)\).

Action selection. With probability \(P_{\text{new}} = \rho S^{-\gamma}\), where \(S\) is the number of distinct previously visited locations, the agent explores a new location; otherwise it returns to a previously visited one.

Exploration. If the agent at location \(i\) explores, the destination \(j \neq i\) is selected with probability proportional to the gravity score:

\[ p_{ij} = \frac{n_i n_j}{r_{ij}^2} \]

where \(n_{i(j)}\) is the relevance of location \(i(j)\) and \(r_{ij}\) is their Haversine distance. The set of visited locations \(S\) grows by 1.

Return. A previously visited location \(i\) is chosen with probability proportional to its visitation frequency: \(\Pi_i = f_i\).

Parameters:

Name Type Description Default
name str

Human-readable label. The default is "Density EPR model".

'Density EPR model'
rho float

Exploration parameter \(\rho \in (0, 1]\). The default is 0.6 [SKWB2010].

0.6
gamma float

Return-penalty exponent \(\gamma \geq 0\). The default is 0.21 [SKWB2010].

0.21
beta float

Waiting-time tail exponent \(\beta\). The default is 0.8 [SKWB2010].

0.8
tau int

Waiting-time scale \(\tau\) in hours. The default is 17 [SKWB2010].

17
min_wait_time_minutes int

Minimum waiting time between moves, in minutes. The default is 20.

20

Attributes:

Name Type Description
name str

Human-readable label of this model instance.

rho float

The exploration parameter \(\rho\).

gamma float

The return-penalty exponent \(\gamma\).

beta float

The waiting-time tail exponent \(\beta\).

tau int

The waiting-time scale \(\tau\) (in hours).

min_wait_time float

Minimum waiting time in hours.

Notes

spatial_tessellation accepts any eager dataframe (pandas, polars, …). If a relevance column is absent, all locations are treated as equally relevant.

Examples:

>>> import pandas as pd
>>> from fastmob.models import DensityEPR
>>> tessellation = pd.DataFrame({
...     "tile_id": [0, 1, 2, 3],
...     "lat": [40.71, 41.88, 37.77, 33.44],
...     "lng": [-74.01, -87.62, -122.42, -112.07],
...     "relevance": [0.40, 0.30, 0.18, 0.12],
... })
>>> start = pd.Timestamp("2020-01-01 08:00:00")
>>> end   = pd.Timestamp("2020-01-14 08:00:00")
>>> tdf = DensityEPR().generate(start, end, tessellation, n_agents=2, random_state=0)
>>> print(tdf.head())
References

.. [PSRPGB2015] Pappalardo, L. et al. (2015). Returners and Explorers dichotomy in human mobility. Nature Communications, 6, 8166. .. [PSR2016] Pappalardo, L., Simini, F. & Rinzivillo, S. (2016). Human Mobility Modelling: exploration and preferential return meet the gravity model. Procedia Computer Science, 83. .. [SKWB2010] Song, C., Koren, T., Wang, P. & Barabási, A.-L. (2010). Modelling the scaling properties of human mobility. Nature Physics, 6, 818–823.

See Also

EPR, SpatialEPR, Ditras

generate(start_date, end_date, spatial_tessellation, gravity_singly=None, n_agents=1, starting_locations=None, relevance_column=RELEVANCE, random_state=None)

Simulate agents from start_date to end_date.

Parameters:

Name Type Description Default
start_date Timestamp or datetime

Start time of the simulation.

required
end_date Timestamp or datetime

End time of the simulation.

required
spatial_tessellation DataFrame or GeoDataFrame

Division of the territory into locations. Must include either a geometry column or explicit lat / lng columns.

required
gravity_singly Gravity or None

A singly constrained Gravity model for the exploration phase. If None, a default Gravity(gravity_type="singly constrained") is used. The default is None.

None
n_agents int

Number of agents to simulate. The default is 1.

1
starting_locations list of int or None

One tessellation index per agent as the starting position. If None, chosen uniformly at random. The default is None.

None
relevance_column str

Column in spatial_tessellation used as location relevance for the gravity model. The default is "relevance".

RELEVANCE
random_state int or None

Random seed for reproducibility. The default is None.

None

Returns:

Type Description
DataFrame

Synthetic trajectories with columns uid, datetime, lat, and lng.

Worked example: Exploration and preferential return


SpatialEPR

Bases: EPR

Spatial-EPR (s-EPR) trajectory generator.

The s-EPR model is a distance-only variant of DensityEPR that ignores location relevance during exploration [PSRPGB2015][PSR2016] [SKWB2010]. The four mechanisms are:

Waiting time choice. The waiting time \(\Delta t\) between two moves is drawn from \(P(\Delta t) \sim \Delta t^{-1-\beta} \exp(-\Delta t/\tau)\).

Action selection. With probability \(P_{\text{new}} = \rho S^{-\gamma}\), where \(S\) is the number of distinct previously visited locations, the agent explores a new location; otherwise it returns to a previously visited one.

Exploration. If the agent at location \(i\) explores, the unvisited destination \(j \neq i\) is selected inversely proportional to squared distance only:

\[ p_{ij} = \frac{1}{r_{ij}^2}. \]

Return. A previously visited location \(i\) is chosen with probability proportional to its visitation frequency: \(\Pi_i = f_i\).

Parameters:

Name Type Description Default
name str

Human-readable label. The default is "Spatial EPR model".

'Spatial EPR model'
rho float

Exploration parameter \(\rho \in (0, 1]\). The default is 0.6 [SKWB2010].

0.6
gamma float

Return-penalty exponent \(\gamma \geq 0\). The default is 0.21 [SKWB2010].

0.21
beta float

Waiting-time tail exponent \(\beta\). The default is 0.8 [SKWB2010].

0.8
tau int

Waiting-time scale \(\tau\) in hours. The default is 17 [SKWB2010].

17
min_wait_time_minutes int

Minimum waiting time between moves, in minutes. The default is 20.

20

Attributes:

Name Type Description
name str

Human-readable label of this model instance.

rho float

The exploration parameter \(\rho\).

gamma float

The return-penalty exponent \(\gamma\).

beta float

The waiting-time tail exponent \(\beta\).

tau int

The waiting-time scale \(\tau\) (in hours).

min_wait_time float

Minimum waiting time in hours.

Notes

spatial_tessellation accepts any eager dataframe (pandas, polars, …). The relevance_column parameter is accepted for API compatibility but is not used — all location relevances are treated as equal in the spatial phase.

Examples:

>>> import pandas as pd
>>> from fastmob.models import SpatialEPR
>>> tessellation = pd.DataFrame({
...     "tile_id": [0, 1, 2, 3],
...     "lat": [40.71, 41.88, 37.77, 33.44],
...     "lng": [-74.01, -87.62, -122.42, -112.07],
... })
>>> start = pd.Timestamp("2020-01-01 08:00:00")
>>> end   = pd.Timestamp("2020-01-14 08:00:00")
>>> tdf = SpatialEPR().generate(start, end, tessellation, n_agents=2, random_state=0)
>>> print(tdf.head())
References

.. [PSRPGB2015] Pappalardo, L. et al. (2015). Returners and Explorers dichotomy in human mobility. Nature Communications, 6, 8166. .. [PSR2016] Pappalardo, L., Simini, F. & Rinzivillo, S. (2016). Human Mobility Modelling: exploration and preferential return meet the gravity model. Procedia Computer Science, 83. .. [SKWB2010] Song, C., Koren, T., Wang, P. & Barabási, A.-L. (2010). Modelling the scaling properties of human mobility. Nature Physics, 6, 818–823.

See Also

EPR, DensityEPR, Ditras

generate(start_date, end_date, spatial_tessellation, gravity_singly=None, n_agents=1, starting_locations=None, random_state=None)

Simulate agents from start_date to end_date.

Parameters:

Name Type Description Default
start_date Timestamp or datetime

Start time of the simulation.

required
end_date Timestamp or datetime

End time of the simulation.

required
spatial_tessellation DataFrame or GeoDataFrame

Division of the territory into locations.

required
gravity_singly Gravity or None

A singly constrained Gravity model. The relevance column is ignored; only distances affect exploration probabilities. If None, a default Gravity(gravity_type="singly constrained") is created. The default is None.

None
n_agents int

Number of agents to simulate. The default is 1.

1
starting_locations list of int or None

One tessellation index per agent as the starting position. The default is None (chosen uniformly at random).

None
random_state int or None

Random seed for reproducibility. The default is None.

None

Returns:

Type Description
DataFrame

Synthetic trajectories with columns uid, datetime, lat, and lng.

Worked example: Exploration and preferential return


Ditras

Bases: EPR

DITRAS (DIary-based TRAjectory Simulator) modelling framework.

DITRAS simulates spatio-temporal mobility patterns by combining two probabilistic models [PS2018]:

Phase 1 — Mobility Diary Generation. A MarkovDiaryGenerator produces a mobility diary \(D(t)\) that encodes the temporal pattern of an agent's routine (home vs. away at each hour).

Phase 2 — Trajectory Generation. The mobility diary drives a DensityEPR-like spatial mechanism: diary slots labelled 0 map the agent back to its home location; other slots trigger an EPR exploration/return step to assign a physical location.

Parameters:

Name Type Description Default
diary_generator MarkovDiaryGenerator

A fitted MarkovDiaryGenerator used to produce mobility diaries.

required
name str

Human-readable label. The default is "Ditras model".

'Ditras model'
rho float

Exploration parameter \(\rho \in (0, 1]\) for the spatial phase. The default is 0.3 [PS2018].

0.3
gamma float

Return-penalty exponent \(\gamma \geq 0\) for the spatial phase. The default is 0.21 [PS2018].

0.21

Attributes:

Name Type Description
name str

Human-readable label of this model instance.

rho float

The exploration parameter \(\rho\).

gamma float

The return-penalty exponent \(\gamma\).

Notes

spatial_tessellation accepts any eager dataframe (pandas, polars, …). The diary generator must be fitted via MarkovDiaryGenerator.fit before passing it to this class.

Examples:

>>> import pandas as pd
>>> from fastmob.models import Ditras
>>> from fastmob.models import MarkovDiaryGenerator
>>> # Build a minimal diary generator (normally trained on real trajectories)
>>> mdg = MarkovDiaryGenerator()
>>> tessellation = pd.DataFrame({
...     "tile_id": [0, 1, 2, 3],
...     "lat": [40.71, 41.88, 37.77, 33.44],
...     "lng": [-74.01, -87.62, -122.42, -112.07],
...     "relevance": [0.40, 0.30, 0.18, 0.12],
... })
>>> start = pd.Timestamp("2020-01-01 08:00:00")
>>> end   = pd.Timestamp("2020-01-14 08:00:00")
>>> ditras = Ditras(mdg)
>>> tdf = ditras.generate(start, end, tessellation,
...                       relevance_column="relevance", n_agents=2,
...                       random_state=0)
>>> print(tdf.head())
References

.. [PS2018] Pappalardo, L. & Simini, F. (2018). Data-driven generation of spatio-temporal routines in human mobility. Data Mining and Knowledge Discovery, 32, 787–829.

See Also

DensityEPR, MarkovDiaryGenerator

generate(start_date, end_date, spatial_tessellation, gravity_singly=None, n_agents=1, starting_locations=None, relevance_column=RELEVANCE, random_state=None)

Simulate agents from start_date to end_date.

Parameters:

Name Type Description Default
start_date Timestamp or datetime

Start time of the simulation.

required
end_date Timestamp or datetime

End time of the simulation.

required
spatial_tessellation DataFrame or GeoDataFrame

Division of the territory into locations. Must include either a geometry column or explicit lat / lng columns.

required
gravity_singly Gravity or None

A singly constrained Gravity model for the exploration phase. If None, a default Gravity(gravity_type="singly constrained") is used. The default is None.

None
n_agents int

Number of agents to simulate. The default is 1.

1
starting_locations list of int or None

One tessellation index per agent as the starting (home) location. If None, chosen uniformly at random. The default is None.

None
relevance_column str

Column in spatial_tessellation used as location relevance for the gravity exploration phase. The default is "relevance".

RELEVANCE
random_state int or None

Random seed for reproducibility. The default is None.

None

Returns:

Type Description
DataFrame

Synthetic trajectories with columns uid, datetime, lat, and lng.

Worked example: Realistic daily rhythm


MarkovDiaryGenerator

Markov diary learner and generator: when a person is at home or away, hour by hour.

A Mobility Diary Learner (MDL) learns hourly temporal mobility patterns from real individual trajectories and then synthesises new mobility diaries [PS2018]. A diary \(D(t)\) is a sequence of abstract locations (0 = home, 1, 2, … = non-home destinations in decreasing visitation-frequency order) at hourly resolution.

The learner translates each individual's trajectory into an abstract time series and builds a Markov chain \(MD(t)\) over 48 states: 24 hours of the day \(\times\) 2 typicality values (1 = at the typical/home location, 0 = away). Transition probabilities are estimated by counting state-to-state transitions across all individuals.

A fitted MarkovDiaryGenerator can be passed to Ditras or STS_epr to drive their temporal pattern.

Parameters:

Name Type Description Default
name str

Human-readable label for this instance. The default is "Markov diary".

'Markov diary'
granularity_minutes int

Temporal resolution of a diary slot, in minutes. Must be a positive divisor of 1440. The default is 60 (hourly, 24 slots/day); 15 gives 96 slots/day and 5 gives 288 slots/day.

60

Attributes:

Name Type Description
name str

Human-readable label of this instance.

markov_chain_ ndarray or None

Flattened CDF matrix built after fit. Shape (48 * 48,). None before fitting.

time_slot_length str

Length of each time slot (fixed at "1h").

Notes

The fit method accepts any pandas-compatible dataframe. The trajectory must contain a datetime column (auto-detected) and a user-ID column (uid by default).

Examples:

>>> import pandas as pd
>>> from fastmob.models import MarkovDiaryGenerator
>>> # Normally you would pass a real trajectory TrajDataFrame here.
>>> # This example uses an unfitted generator (home-only diary).
>>> mdg = MarkovDiaryGenerator()
>>> diary = mdg.generate(72, pd.Timestamp("2020-01-01 00:00:00"), random_state=0)
>>> print(diary.head())
References

.. [PS2018] Pappalardo, L. & Simini, F. (2018). Data-driven generation of spatio-temporal routines in human mobility. Data Mining and Knowledge Discovery, 32, 787–829.

See Also

Ditras, STS_epr

fit(traj, n_individuals, lid='location')

Learn the Markov mobility diary from real trajectories.

Builds a 48-state Markov chain from the first n_individuals users in traj. Each state encodes an hour of the day (0–23) and a typicality value (1 = home, 0 = away). The resulting transition probabilities are stored in markov_chain_.

Parameters:

Name Type Description Default
traj DataFrame

Mobility trajectories. Must contain a datetime column and a uid column (auto-detected), plus the location column specified by lid.

required
n_individuals int

Number of individuals from traj to use for training.

required
lid str

Name of the column containing the location cluster identifier. The default is "location".

'location'
Notes

Modifies the internal Markov chain in-place. Call before passing this instance to Ditras or STS_epr.

generate(diary_length, start_date, random_state=None)

Generate a synthetic mobility diary.

Samples a sequence of hourly abstract locations from the fitted Markov chain and returns a compact representation where consecutive identical locations are collapsed to a single row.

Parameters:

Name Type Description Default
diary_length int

Length of the diary in time slots (equal to hours when granularity_minutes=60; e.g. 96 slots = one day at 15-min granularity).

required
start_date Timestamp or datetime

Starting timestamp for the diary.

required
random_state int or None

Random seed for reproducibility. The default is None.

None

Returns:

Type Description
DataFrame

A dataframe with columns:

  • datetime — timestamp of each location change.
  • abstract_location — abstract location identifier (0 = home, 1, 2, … = non-home locations in order of decreasing frequency as learned from real data).
Notes

If fit has not been called, a trivial diary is generated where the agent stays at home (abstract_location == 0) for the entire period.

Worked example: Realistic daily rhythm

Social Trajectory Models

GeoSim

GeoSim social trajectory generator.

GeoSim generates synthetic individual mobility trajectories by combining the EPR exploration/return mechanism with a social influence layer [THSG2015]. Each agent is embedded in a social network, and with probability \(\alpha\) it consults a social contact when choosing its next location.

Waiting time choice. The time \(\Delta t\) between moves is drawn from:

\[ P(\Delta t) \sim \Delta t^{-1-\beta} \exp(-\Delta t/\tau). \]

Action selection. With probability \(P_{\text{exp}} = \rho S^{-\gamma}\), where \(S\) is the number of distinct previously visited locations, the agent explores a new location; otherwise it returns. At that point, with probability \(\alpha\) a social contact influences the location choice (Social); with probability \(1 - \alpha\) the agent acts alone (Individual).

Individual Exploration. An unvisited location is selected uniformly at random from the set \(\text{exp}(a)\) of all unvisited locations for agent \(a\). The set \(S\) grows by 1.

Social Exploration. A social contact \(c\) is selected with probability proportional to the cosine mobility similarity between \(a\) and \(c\). A location is then selected from \(\text{exp}(a) \cap \text{ret}(c)\) with probability proportional to \(c\)'s visitation frequency. The set \(S\) grows by 1.

Individual Return. A previously visited location \(j \in \text{ret}(a)\) is selected with probability proportional to its visitation frequency \(\Pi_j = f_j\).

Social Return. A social contact \(c\) is selected (as in Social Exploration). A location from \(\text{ret}(a) \cap \text{ret}(c)\) is selected proportionally to \(c\)'s visitation frequency.

Parameters:

Name Type Description Default
name str

Human-readable label. The default is "GeoSim".

'GeoSim'
rho float

Exploration parameter \(\rho \in (0, 1]\). The default is 0.6 [SKWB2010].

0.6
gamma float

Return-penalty exponent \(\gamma \geq 0\). The default is 0.21 [SKWB2010].

0.21
alpha float

Social influence probability \(\alpha \in [0, 1]\). The default is 0.2 [THSG2015].

0.2
beta float

Waiting-time tail exponent \(\beta\). The default is 0.8 [SKWB2010].

0.8
tau int

Waiting-time scale \(\tau\) in hours. The default is 17 [SKWB2010].

17
min_wait_time_hours float

Minimum waiting time between moves, in hours. The default is 1.

1

Attributes:

Name Type Description
name str

Human-readable label of this model instance.

rho float

The exploration parameter \(\rho\).

gamma float

The return-penalty exponent \(\gamma\).

alpha float

The social influence probability \(\alpha\).

beta float

The waiting-time tail exponent \(\beta\).

tau int

The waiting-time scale \(\tau\) (in hours).

min_wait_time_hours float

Minimum waiting time in hours.

Notes

spatial_tessellation accepts any pandas-compatible eager dataframe. It must contain either a geometry column or explicit lat / lng columns. When social_graph="random" a random geometric graph is generated automatically; alternatively, pass an edge list to define specific social connections.

References

.. [PSRPGB2015] Pappalardo, L. et al. (2015). Returners and Explorers dichotomy in human mobility. Nature Communications, 6, 8166. .. [PSR2016] Pappalardo, L., Simini, F. & Rinzivillo, S. (2016). Human Mobility Modelling: exploration and preferential return meet the gravity model. Procedia Computer Science, 83. .. [SKWB2010] Song, C., Koren, T., Wang, P. & Barabási, A.-L. (2010). Modelling the scaling properties of human mobility. Nature Physics, 6, 818–823. .. [THSG2015] Toole, J. et al. (2015). Coupling Human Mobility and Social Ties. Journal of the Royal Society Interface, 12, 20141128.

See Also

EPR, SpatialEPR, Ditras, STS_epr

generate(start_date, end_date, spatial_tessellation, social_graph='random', n_agents=500, dt_update_mobSim=24 * 7, indipendency_window=0.5, random_state=None)

Simulate a socially connected population from start_date to end_date.

Parameters:

Name Type Description Default
start_date Timestamp or datetime

Start time of the simulation.

required
end_date Timestamp or datetime

End time of the simulation.

required
spatial_tessellation DataFrame or GeoDataFrame

Division of the territory into locations. Must include either a geometry column or explicit lat / lng columns. Must contain at least 2 tiles.

required
social_graph ``"random"`` or list of (uid, uid) tuples

Social network for the simulated agents.

  • "random" — a random geometric graph on n_agents nodes is generated automatically.
  • A list of (uid_a, uid_b) edge tuples — the number of agents is inferred from the unique node set; n_agents is ignored.

The default is "random".

'random'
n_agents int

Number of agents when social_graph="random". The default is 500.

500
dt_update_mobSim float

Interval in hours between social-graph mobility-similarity updates. The default is 168 (one week).

24 * 7
indipendency_window float

Time window in hours that must elapse before an agent's move can affect other agents' social choices. The default is 0.5.

0.5
random_state int or None

Random seed for reproducibility. The default is None.

None

Returns:

Type Description
DataFrame

Synthetic trajectories with columns uid, datetime, lat, and lng.

Raises:

Type Description
ValueError

If n_agents <= 0, start_date > end_date, social_graph is an empty list, or social_graph is a string other than "random".

TypeError

If social_graph is neither a string nor a list.

Worked example: Social ties


STS_epr

STS-EPR (Spatial, Temporal, and Social EPR) trajectory generator.

STS-EPR extends GeoSim by incorporating a temporal diary (via MarkovDiaryGenerator) and a gravity-weighted individual exploration mechanism [CRP2020]. Each agent follows a pre-generated mobility diary that dictates when to move (home vs. away), while the social and EPR mechanisms determine where to go.

Action selection. With probability \(P_{\text{exp}} = \rho S^{-\gamma}\) the agent explores a new location; otherwise it returns. With probability \(\alpha\) a social contact influences the destination (Social); with probability \(1 - \alpha\) the agent acts alone (Individual). Diary entries with abstract_location == 0 always force a return to the home location.

Individual Exploration. An unvisited location \(j \neq i\) is selected with probability proportional to the gravity score:

\[ p_{ij} = \frac{r_i r_j}{d_{ij}^2} \]

where \(r_{i(j)}\) is location relevance and \(d_{ij}\) is the Haversine distance.

Social Exploration. A social contact \(c\) is selected with probability proportional to cosine mobility similarity. A location from \(\text{exp}(a) \cap \text{ret}(c)\) is chosen proportionally to \(c\)'s visitation frequency.

Individual Return. A previously visited location \(j \in \text{ret}(a)\) is chosen with probability \(\Pi_j = f_j\).

Social Return. As in Social Exploration, but from \(\text{ret}(a) \cap \text{ret}(c)\).

Parameters:

Name Type Description Default
name str

Human-readable label. The default is "STS-EPR".

'STS-EPR'
rho float

Exploration parameter \(\rho \in (0, 1]\). The default is 0.6 [SKWB2010].

0.6
gamma float

Return-penalty exponent \(\gamma \geq 0\). The default is 0.21 [SKWB2010].

0.21
alpha float

Social influence probability \(\alpha \in [0, 1]\). The default is 0.2 [THSG2015].

0.2

Attributes:

Name Type Description
name str

Human-readable label of this model instance.

rho float

The exploration parameter \(\rho\).

gamma float

The return-penalty exponent \(\gamma\).

alpha float

The social influence probability \(\alpha\).

Notes

spatial_tessellation must contain at least 3 tiles and a relevance column. The MarkovDiaryGenerator must be fitted before being passed to generate.

References

.. [PSRPGB2015] Pappalardo, L. et al. (2015). Returners and Explorers dichotomy in human mobility. Nature Communications, 6, 8166. .. [PSR2016] Pappalardo, L., Simini, F. & Rinzivillo, S. (2016). Human Mobility Modelling: exploration and preferential return meet the gravity model. Procedia Computer Science, 83. .. [SKWB2010] Song, C., Koren, T., Wang, P. & Barabási, A.-L. (2010). Modelling the scaling properties of human mobility. Nature Physics, 6, 818–823. .. [THSG2015] Toole, J. et al. (2015). Coupling Human Mobility and Social Ties. Journal of the Royal Society Interface, 12, 20141128. .. [CRP2020] Cornacchia, G., Rossetti, G. & Pappalardo, L. (2020). Modelling Human Mobility considering Spatial, Temporal and Social Dimensions. .. [PS2018] Pappalardo, L. & Simini, F. (2018). Data-driven generation of spatio-temporal routines in human mobility. Data Mining and Knowledge Discovery, 32, 787–829.

See Also

GeoSim, Ditras, MarkovDiaryGenerator

generate(start_date, end_date, spatial_tessellation, diary_generator, social_graph='random', n_agents=500, rsl=False, distance_matrix=None, relevance_column=None, min_relevance=0.1, dt_update_mobSim=24 * 7, indipendency_window=0.5, random_state=None)

Simulate a socially connected population from start_date to end_date.

Parameters:

Name Type Description Default
start_date Timestamp or datetime

Start time of the simulation.

required
end_date Timestamp or datetime

End time of the simulation.

required
spatial_tessellation DataFrame or GeoDataFrame

Division of the territory into locations. Must include either a geometry column or explicit lat / lng columns, and a relevance column. Must contain at least 3 tiles.

required
diary_generator MarkovDiaryGenerator

A fitted MarkovDiaryGenerator that supplies the temporal mobility diary for each agent.

required
social_graph ``"random"`` or list of (uid, uid) tuples

Social network for the agents.

  • "random" — a random geometric graph is generated automatically.
  • A list of (uid_a, uid_b) edge tuples — the number of agents is inferred from the unique node set.

The default is "random".

'random'
n_agents int

Number of agents when social_graph="random". The default is 500.

500
rsl bool

If True, the starting location for each agent is sampled with probability proportional to the location's relevance. If False, it is chosen uniformly at random. The default is False.

False
distance_matrix ndarray or None

Pre-computed (n_locs, n_locs) distance matrix in kilometres. If None, the Rust simulator uses cached gravity OD rows instead of a full matrix. The default is None.

None
relevance_column str or None

Name of the column in spatial_tessellation used as location relevance. The default is None (falls back to "relevance").

None
min_relevance float

Value substituted for any zero-relevance location to avoid division by zero. The default is 0.1.

0.1
dt_update_mobSim float

Interval in hours between social-graph mobility-similarity updates. The default is 168 (one week).

24 * 7
indipendency_window float

Time window in hours before an agent's move can influence others. The default is 0.5.

0.5
random_state int or None

Random seed for reproducibility. The default is None.

None

Returns:

Type Description
DataFrame

Synthetic trajectories with columns uid, datetime, lat, and lng.

Raises:

Type Description
TypeError

If diary_generator is not a MarkovDiaryGenerator or rsl is not a bool.

ValueError

If n_agents <= 0, start_date > end_date, social_graph is an empty list, or the social graph string is not "random".

IndexError

If relevance_column is not found in spatial_tessellation.

Worked example: Social ties


Next-location prediction

NextLocationPredictor

Order-k Markov next-location predictor with optional backoff.

Parameters:

Name Type Description Default
order int

Markov chain order: number of most-recent locations used as context. order=0 degenerates to a most-frequent-location baseline (HuMobi's TopLoc). Default 1.

1
backoff bool

When an exact order-order context was never observed, fall back to progressively lower orders (down to order 0) instead of returning no prediction. Default True.

True

Examples:

>>> import pandas as pd
>>> from fastmob.models import NextLocationPredictor
>>> df = pd.DataFrame({
...     "uid": ["u1"] * 6,
...     "location_id": ["A", "B", "C", "A", "B", "C"],
...     "started_at": pd.date_range("2020-01-01", periods=6, freq="h"),
... })
>>> model = NextLocationPredictor(order=1).fit(df)
>>> model.predict()["location_id"].tolist()
['A']

evaluate(top_k=1, n_holdout=1)

Holdout-last-n_holdout accuracy over the data given to fit.

For each user with more than n_holdout observations, walks forward through the held-out tail one step at a time: at each step, fits a model on every prior observation (train portion plus any already-revealed holdout steps -- never the true value being predicted) and checks whether the true next location is among the top-top_k predictions. Accuracy is averaged over every (user, step) pair across every user and step.

This evaluates directly against fit's own input rather than a separate held-out dataframe, since fastmob's Staypoints/ Locations pipeline already produces one canonical per-user location sequence -- there is no second, independently-loaded test sequence to compare against in the common case.

Parameters:

Name Type Description Default
top_k int

Number of ranked candidates checked per prediction. Default 1.

1
n_holdout int

Number of most-recent observations per user to hold out and evaluate against. Users with len(sequence) <= n_holdout are skipped. Default 1.

1

Returns:

Type Description
float

Fraction of (user, holdout step) pairs where the true next location was among the top-top_k predictions. NaN if no user has enough observations to evaluate.

fit(traj, location_col=None, uid_col=None, started_at_col=None)

Fit one Markov model per user from each user's location-id sequence.

Parameters:

Name Type Description Default
traj dataframe or Staypoints

Source data; any Narwhals-compatible eager backend, or a fastmob.core.Staypoints instance.

required
location_col str

Column holding each row's location identifier. Auto-detected when None.

None
uid_col str

User-ID column. Auto-detected when None; when absent, the whole frame is treated as one user.

None
started_at_col str

Datetime column to sort each user's sequence by. When None, rows are assumed already in chronological order per user (matching Staypoints' own started_at_col, when traj is a Staypoints instance).

None

Returns:

Type Description
NextLocationPredictor

self, fitted.

predict(top_k=1)

Predict each fitted user's single most likely next location.

Returns:

Type Description
DataFrame

One row per user: columns [uid_col, location_col] holding the top-ranked prediction, in the same backend fit was given (use predict_proba for ranked candidates/probabilities).

predict_proba(top_k=1)

Predict each fitted user's next location(s) from their own training history's tail.

Parameters:

Name Type Description Default
top_k int

Number of ranked candidates to return per user. Default 1.

1

Returns:

Type Description
DataFrame

One row per (uid, rank): columns [uid_col, "rank", location_col, "probability"], rank starting at 1, in the same backend fit was given. A user with fewer than top_k observed candidates contributes fewer rows.

Worked example: Predict the next place