Evaluation Measures
| API | Description |
|---|---|
common_part_of_commuters |
Compare Trips or sparse FlowDataFrames with Rust-backed CPC. |
common_part_of_links |
Return the common part of links (CPL) between two flow arrays. |
common_part_of_commuters_distance |
Return the common part of commuters by distance (CPCD). |
compare_to |
Compare a value column between two dataframes, optionally grouped by an existing column. Also available as BaseDataFrame.compare_to(). |
r_squared |
Return the coefficient of determination R-squared. |
rmse |
Return the root mean squared error between true and predicted values. |
nrmse |
Return the normalized root mean squared error (RMSE / sum(true)). |
information_gain |
Return the information gain of true over predicted values. |
kullback_leibler_divergence |
Return the Kullback-Leibler divergence between true and predicted values. |
max_error |
Return the maximum signed error max(true_i - pred_i). |
mse |
Return the mean squared error between true and predicted values. |
jensen_shannon_divergence |
Return Jensen-Shannon divergence between two distributions. |
wasserstein_distance |
Return Rust-backed 1D Wasserstein distance between empirical samples. |
stvd_emd |
Compute the spatio-temporal Wasserstein distance between two distributions. |
fastmob.measures.evaluation
fastmob.measures.evaluation — generic comparison metrics.
For grouped/dataframe-level comparisons, use BaseDataFrame.compare_to()
(inherited by Staypoints, Trips, Triplegs, Locations,
TrajDataFrame, FlowDataFrame, Tours) instead of hand-coding a
grouping around these primitives.
ComparisonResult
dataclass
Result of :func:compare_to: an overall value and, if grouped, a per-group breakdown.
common_part_of_commuters(observed, predicted)
Compare two Trips or two FlowDataFrames through sparse Rust CPC.
common_part_of_commuters_distance(observed, predicted)
Compare distance_km distributions in two Trips using Rust CPCD.
common_part_of_links(observed, predicted)
Compare active sparse OD links in two Trips or FlowDataFrames.
compare_to(df1, df2, value_col, *, group_col=None, metric=None)
Compare value_col between two dataframes, optionally grouped by group_col.
metric defaults to :func:wasserstein_distance and accepts any
(array, array) -> float callable, e.g. :func:jensen_shannon_divergence.
When group_col is given, the comparison runs once per label present in
both dataframes (sorted for determinism) and overall is the mean across
groups.
information_gain(true, pred)
Return the information gain (KL divergence variant) of true over pred.
where \(N = \sum_i y_i\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
true
|
Ground truth target values (must be positive). |
required | |
pred
|
Estimated target values (must be positive). |
required |
Returns:
| Type | Description |
|---|---|
float
|
Information gain value; 0.0 when the distributions are identical. |
Examples:
jensen_shannon_divergence(distribution1, distribution2)
Return Jensen-Shannon divergence between two distributions.
Inputs are normalised internally (raw counts and probabilities both
work) and must have the same length -- unlike :func:wasserstein_distance,
the two arrays are paired by index (one entry per category/bin), not
independent samples.
kullback_leibler_divergence(true, pred)
Return the Kullback–Leibler divergence \(D_\mathrm{KL}(\mathrm{true}\,\|\,\mathrm{pred})\).
Inputs are normalized to probability distributions before evaluation,
matching the historical scipy.stats.entropy(true, pred) behavior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
true
|
Probability distribution P (reference). |
required | |
pred
|
Probability distribution Q (approximation). |
required |
Returns:
| Type | Description |
|---|---|
float
|
KL divergence; 0.0 when the distributions are identical. |
Examples:
max_error(true, pred)
Return the maximum signed error max(true_i - pred_i).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
true
|
Ground truth target values. |
required | |
pred
|
Estimated target values. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Maximum element-wise difference true - pred. |
Examples:
mse(true, pred)
Return the mean squared error between true and predicted values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
true
|
Ground truth target values. |
required | |
pred
|
Estimated target values. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Non-negative MSE; 0.0 is the best possible value. |
Examples:
nrmse(true, pred)
Return the normalized root mean squared error (RMSE / sum(true)).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
true
|
Ground truth target values. |
required | |
pred
|
Estimated target values. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Non-negative NRMSE; 0.0 is the best possible value. |
Examples:
r_squared(true, pred)
Return the coefficient of determination R².
where
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
true
|
Ground truth target values. |
required | |
pred
|
Estimated target values. |
required |
Returns:
| Type | Description |
|---|---|
float
|
R² score. Best possible value is 1.0; can be negative. |
Examples:
rmse(true, pred)
Return the root mean squared error between true and predicted values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
true
|
Ground truth target values. |
required | |
pred
|
Estimated target values. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Non-negative RMSE; 0.0 is the best possible value. |
Examples:
stvd_emd(dist_a, dist_b, alpha=10.0, cyclical_period=1440.0, *, time_col=None, weight_col=None, lat_col=None, lng_col=None)
Compute the spatio-temporal Wasserstein distance between two distributions.
Each input is a DataFrame representing a spatial-temporal distribution with
columns for a time bin (HH:MM string), a weight/volume value, and a WGS84
latitude/longitude centroid — the exact shape produced by
:func:fastmob.measures.collective.build_stvd.
Distances are computed as an entropy-regularised (Sinkhorn) Earth Mover's
Distance over an explicit cost matrix combining the great-circle
(Haversine) distance between centroids with a cyclical-time term: two
points at times t1/t2 contribute 2 * r * sin(d_theta / 2)
metres, where r = alpha * cyclical_period / (2*pi),
theta = 2*pi*(t / cyclical_period), and d_theta is the shortest
angular difference between the two times.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dist_a
|
Any
|
Any Narwhals-compatible eager DataFrame (pandas, polars, …). |
required |
dist_b
|
Any
|
Any Narwhals-compatible eager DataFrame (pandas, polars, …). |
required |
alpha
|
float
|
Space-time tradeoff: 1 minute equals |
10.0
|
cyclical_period
|
float
|
Wrap-around period in minutes. Default |
1440.0
|
time_col
|
str | None
|
Explicit time column name. Auto-detected when |
None
|
weight_col
|
str | None
|
Explicit weight column name. Auto-detected when |
None
|
lat_col
|
str | None
|
Explicit latitude/longitude column names. Auto-detected when |
None
|
lng_col
|
str | None
|
Explicit latitude/longitude column names. Auto-detected when |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Spatio-temporal Wasserstein distance in metres. |
Examples:
>>> import pandas as pd
>>> from fastmob.measures.evaluation import stvd_emd
>>> dist_a = pd.DataFrame(
... {
... "time_bin": ["08:00", "08:10"],
... "mean_volume": [2.0, 1.0],
... "center_lat": [0.0, 0.0],
... "center_lng": [0.0, 0.001],
... }
... )
>>> dist_b = pd.DataFrame(
... {
... "time_bin": ["08:00", "08:10"],
... "mean_volume": [1.0, 2.0],
... "center_lat": [0.0, 0.0],
... "center_lng": [0.0, 0.002],
... }
... )
>>> print(round(stvd_emd(dist_a, dist_b), 3))
74.156
wasserstein_distance(values1, values2)
Return Rust-backed 1D Wasserstein distance between empirical samples.