Spatial CV API¶
SpatialBlockSplitter¶
h2ml.features.spatial_cv.SpatialBlockSplitter
¶
K-fold splitter that groups spatially adjacent samples into blocks and holds out entire blocks as test sets.
Blocks are formed by quantile-binning coordinates on each axis (robust to uneven spatial distributions) and assigned to folds round-robin. Each fold's test set is one or more contiguous blocks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coords
|
ndarray
|
(n_samples, 2) array of spatial coordinates (lat/lon, x/y, or any 2-D position). |
required |
n_splits
|
int
|
Number of CV folds. |
5
|
n_blocks_per_fold
|
int
|
Number of blocks per test fold. Total blocks = n_splits × n_blocks_per_fold. More blocks give finer spatial granularity at the cost of smaller individual test sets. |
5
|
random_state
|
int
|
Seed for the block→fold shuffle (reproducible folds). |
42
|
metric
|
SpatialMetric
|
"euclidean" (projected coords) or "haversine" (lat/lon in decimal degrees). |
'euclidean'
|
Example
coords = np.column_stack([lats, lons]) splitter = SpatialBlockSplitter(coords, n_splits=5, n_blocks_per_fold=5) for train_idx, test_idx in splitter.split(X): ... model.fit(X[train_idx], y[train_idx]) ... score = model.score(X[test_idx], y[test_idx])
clone_with_n_splits(n_splits, random_state=None)
¶
Return a new splitter with n_splits folds, reusing the same coords and metric.
get_n_splits(X=None, y=None, groups=None)
¶
Number of folds (sklearn splitter interface; X/y/groups ignored).
plot(lon_col=1, lat_col=0, save_path=None)
¶
Two-panel scatter of block and fold assignments.
Thin wrapper over h2ml.plots.plot_spatial_blocks(self); see that function for details.
split(X, y=None, groups=None)
¶
Yield (train_idx, test_idx) for each of n_splits folds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray
|
Array-like whose row count must match the calibration coords. |
required |
y
|
Optional[ndarray]
|
Ignored (sklearn signature compatibility). |
None
|
groups
|
Optional[ndarray]
|
Ignored (sklearn signature compatibility). |
None
|
Yields:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
(train_idx, test_idx) integer index arrays per fold. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If len(X) does not match the number of stored coords. |
SPCVSplitter¶
h2ml.features.spatial_cv.SPCVSplitter
¶
Two-stage spatial cross-validation splitter (SP-CV). Reference: Wang et al. 2023. Spatial+: A new cross-validation method to evaluate geospatial machine learning models.
Stage 1 — AHC blocks: Agglomerative Hierarchical Clustering (AHC) on spatial coordinates forms blocks that respect the autocorrelation structure of the data. The AHC distance threshold controls block granularity; if not provided it defaults to the 10th percentile of pairwise distances.
Stage 2 — Cluster Ensemble fold assignment: Each block is represented by its mean coordinates, covariates, and target value. Three independent KMeans runs (on location, covariates, and target) are combined via Hybrid Bipartite Graph Formulation (HBGF): a co-occurrence affinity matrix is built from the stacked membership matrices and SpectralClustering produces the final k folds.
The result is folds that are geographically separated and representative of the full covariate and label space.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coords
|
ndarray
|
(n_samples, 2) spatial coordinates (lat/lon or projected). |
required |
X
|
ndarray
|
(n_samples, n_features) covariate matrix. |
required |
y
|
ndarray
|
(n_samples,) target array. |
required |
n_splits
|
int
|
Number of CV folds (k). |
5
|
threshold
|
Optional[float]
|
AHC distance threshold. Defaults to the 10th percentile of pairwise coordinate distances when None. |
None
|
linkage
|
LinkageCriterion
|
Linkage criterion for AHC ('ward', 'average', 'complete'). 'ward' minimises within-cluster variance and works well for compact geographic blocks. |
'ward'
|
random_state
|
int
|
Seed for KMeans and SpectralClustering reproducibility. |
42
|
metric
|
SpatialMetric
|
"euclidean" (projected coords) or "haversine" (lat/lon in decimal degrees). See the Note on linkage interaction. |
'euclidean'
|
pca_components
|
float
|
Variance fraction retained by PCA applied to block covariates before clustering. Default 0.95. |
0.95
|
exact_max_samples
|
int
|
Sample count below which exact scipy AHC is used; above it an approximate sklearn AHC (k-NN graph) is used. Default 5000. |
5000
|
knn_neighbors
|
int
|
k for the k-NN connectivity graph in approximate AHC. Default 15. |
15
|
Note
'ward' linkage operates on Euclidean distances. When metric='haversine', ward is silently downgraded to 'average' (in both the exact and approximate AHC paths) because ward is undefined for non-Euclidean distances. For projected coords (km, m) use metric='euclidean' and ward linkage is valid.
Example
splitter = SPCVSplitter(coords, X, y, n_splits=5) for train_idx, test_idx in splitter.split(X): ... model.fit(X[train_idx], y[train_idx]) ... score = model.score(X[test_idx], y[test_idx])
clone_with_n_splits(n_splits, random_state=None)
¶
Return a new splitter with n_splits folds, reusing the AHC block structure.
Stage 1 (AHC clustering) is skipped — block_id_ is copied directly. Stage 2 (fold assignment) is rerun with the new n_splits and random_state, so each HPO repeat gets different fold boundaries without repeating AHC.
get_n_splits(X=None, y=None, groups=None)
¶
Number of folds (sklearn splitter interface; X/y/groups ignored).
plot(lon_col=1, lat_col=0, save_path=None)
¶
Two-panel scatter of block and fold assignments.
Thin wrapper over h2ml.plots.plot_spatial_blocks(self); see that function for details.
split(X, y=None, groups=None)
¶
Yield (train_idx, test_idx) for each of n_splits folds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray
|
Array-like whose row count must match the calibration coords. |
required |
y
|
Optional[ndarray]
|
Ignored (sklearn signature compatibility). |
None
|
groups
|
Optional[ndarray]
|
Ignored (sklearn signature compatibility). |
None
|
Yields:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
(train_idx, test_idx) integer index arrays per fold. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If len(X) does not match the number of stored coords. |