How Predspot works¶
Predspot frames hotspot prediction as a supervised time series problem on a spatial grid. The library is organised around four stages that map onto four modules:
flowchart LR
A["Crime events<br/>(tag, t, lon, lat)"] --> B["Dataset<br/><small>dataset_preparation</small>"]
S["Study area<br/>(GeoDataFrame)"] --> B
B --> C["Spatio-temporal mapping<br/><small>crime_mapping</small>"]
C --> D["Feature engineering<br/><small>feature_engineering</small>"]
D --> E["Estimator<br/><small>ml_modelling</small>"]
E --> F["Forecast for<br/>the next period"]
1. Dataset¶
A Dataset is a validated pair of
crime events (a DataFrame with tag, t, lon, lat) and a study area
(a GeoDataFrame with a CRS). The events become a GeoDataFrame of points in
WGS84. See Data and study areas.
2. Spatio-temporal mapping¶
The study area is discretised into places — a grid of points, hexagons or
squares — and time into periods (tfreq: daily, weekly or monthly). A
mapping assigns a value to every (period, place) pair:
KDEfits a Gaussian kernel density estimate to the events of each period and evaluates it at the grid points (the default, and the approach of the original thesis);QuadratCountcounts the events falling in each polygonal cell.
Both return the same object: a pandas.Series named crime_density with a
(t, places) MultiIndex — the spatio-temporal series. See
Grids and mapping.
3. Feature engineering¶
For every place, the history of the series is turned into lagged features.
Each feature class first transforms the series (identity, first difference,
STL seasonal or trend component) and then builds lags columns with the
previous values. A PandasFeatureUnion
concatenates several of them. The result is a feature matrix indexed by
(t, places), with one extra row per place for the period after the last
observed one — the row the model will forecast. See
Feature engineering.
4. Estimator¶
Any scikit-learn regressor learns to map the features at t to the series
value at t. Because every row is a (period, place) pair, a single model
is shared by all places, and the spatial structure enters through the mapping
and the features rather than through the model. PredictionPipeline shuffles
the rows for training, evaluates with
TimeSeriesSplit
and forecasts the next period. See Prediction and evaluation.
Design choices worth knowing¶
- Resolutions are in kilometres. Grid functions convert them to degrees using the length of a degree at the equator, so cells are slightly distorted away from it; for city-scale study areas this is negligible.
- Grids are built in WGS84 and re-projected to the study area's CRS.
Cell centroids are computed in a projected CRS, so
lon/latcolumns are accurate. - KDE bandwidth is estimated once. With
bandwidth="silverman"(or"scott") the factor is estimated on the first period with at least three events and held fixed, so densities are comparable across periods. Pass a number to fix it yourself. - Periods with no events are kept (zeros everywhere), and
start_time/end_timecan extend the series beyond the observed range. - Monthly periods use pandas'
ME(month end) frequency. You can keep writingtfreq="M"; it is translated internally.