| cv_knndm | R Documentation |
A k-fold version of the Nearest Neighbour Distance Matching algorithm (Linnenbrink et al., 2024).
Unlike cv_nndm, which is a leave-one-out (LOO) strategy producing as many folds as
there are points, kNNDM produces a small number of k folds (cheap to fit models on) while
still matching the nearest neighbour distance distribution function between the test and training
data to the one between the target prediction points and the training data.
cv_knndm(
x,
column = NULL,
r = NULL,
pred_points = NULL,
model_domain = NULL,
k = 5L,
maxp = 0.5,
clustering = "blocks",
space = "geographical",
hexagon = TRUE,
keep_blocks = TRUE,
num_sample = 10000L,
sampling = "regular",
nk_len = 100L,
linkage = "ward.D2",
scale = TRUE,
balance = TRUE,
presence_bg = FALSE,
biomod2 = TRUE,
deg_to_metre = 111325,
seed = NULL,
num_bins = 4L,
plot = interactive(),
report = interactive()
)
x |
a simple features (sf) or SpatialPoints object of spatial sample data (e.g., species data or ground truth sample for image classification). |
column |
character (optional). Indicating the name of the column in which response variable
(e.g. species data as a binary response i.e. 0s and 1s) is stored. This is used to report whether
all folds contain all classes and, when |
r |
a terra SpatRaster object. This defines the area that the model is going to predict; when
neither |
pred_points |
a simple features (sf) object of prediction points (optional). If provided, these are
used directly as the prediction locations instead of sampling from |
model_domain |
an sf polygon of the prediction area (optional). If provided (and |
k |
integer value. The number of desired folds for cross-validation. The default is |
maxp |
numeric; strictly between |
clustering |
character; the method used to group the points before allocating them to folds.
One of |
space |
character; |
hexagon |
logical. Creates hexagonal (default) spatial blocks when |
keep_blocks |
logical; if |
num_sample |
integer; the number of prediction points to sample from |
sampling |
either |
nk_len |
integer; the number of candidate groupings (numbers of clusters / block sizes) to explore. |
linkage |
character; the agglomeration method passed to |
scale |
logical; whether to scale the covariates when |
balance |
logical. When |
presence_bg |
logical; whether to treat |
biomod2 |
logical. Creates a matrix of folds that can be directly used in the biomod2 package as a CV.user.table for cross-validation. |
deg_to_metre |
integer. The conversion rate of metres to degree. See the details section for more information. |
seed |
integer; a random seed for reproducibility. |
num_bins |
integer; the number of quantile bins used to stratify a continuous numeric |
plot |
logical; whether to plot the distance distribution functions. Defaults to |
report |
logical; whether to print summary of records in each fold. Defaults to |
The method groups the sample points and assigns whole groups to folds, tuning the degree of
aggregation so that the resulting test-to-train nearest neighbour distance distribution
(\hat{G}_{j}^{*}) best matches the prediction-to-sample distribution (\hat{G}_{ij}). The
match is scored with the Wasserstein-1 distance (W in the output; the area between the two
empirical distribution functions), and the grouping with the smallest value is returned. Following
Linnenbrink et al. (2024), a one-sided Kolmogorov-Smirnov test is first used to check whether the
points are clustered relative to the prediction area; if they are not, a random cross-validation is
returned. When a clustering is needed, the intermediate groups are ordered along the first principal
component of the coordinates and distributed across the k folds, and only groupings in which
no fold holds more than maxp of the data are considered.
Three ways of generating the groups are available via clustering: "hierarchical" and
"kmeans" follow Linnenbrink et al. (2024), while "blocks" (the default) is a
blockCV-specific variant that groups the points with hexagonal (or square) spatial blocks, in
the spirit of cv_spatial. The "blocks" option is a blockCV extension and
is not part of the original kNNDM algorithm. When space = "feature" the distances are computed
in the (scaled) covariate space of r instead of the geographical space, and "blocks" is
not available.
When column is supplied and balance = TRUE, class balance is used as a validity gate during the
candidate scan: among groupings with every class present in every test fold, the one with the smallest
W is selected. If no class-complete grouping is available, the overall smallest-W
grouping is returned and the final records table reports the missing class(es). Note that this gate is
weaker than the balancing in cv_spatial: it only ensures every class is represented in every
test fold (no empty class), it does not equalise the class counts across folds. With balance = FALSE
the grouping with the overall smallest W is always returned and column is used only for the report.
For presence-background data (presence_bg = TRUE), column holds 1 for presences and
0 for background points – locations sampled across the study area to represent the available
conditions rather than confirmed absences. The distance matching is then computed on the presences only and
each background point inherits the fold of its nearest presence, so the prediction geometry reflects the
presence data rather than a random background.
An object of class S3. A list of objects including:
folds_list - a list containing the folds. Each fold has two vectors with the training (first) and testing (second) indices
folds_ids - a vector of values indicating the number of the fold for each observation (each number corresponds to the same point in x)
biomod_table - a matrix with the folds to be used in biomod2 package
k - number of the folds
column - the name of the column if provided
type - the clustering method used (or "random" if a random CV was returned)
space - whether distances were matched in geographical or feature space
q - the selected number of intermediate groups
W - the Wasserstein statistic of the selected folds (lower means a better match)
Gij - the prediction-to-sample nearest neighbour distances
Gj - the sample-to-sample (leave-one-out) nearest neighbour distances
Gjstar - the test-to-train nearest neighbour distances of the selected folds
blocks - the spatial blocks of the selected grouping, each tagged with its fold; only when clustering = "blocks" and keep_blocks = TRUE, otherwise NULL
records - a table with the number of points in each category of training and testing
Linnenbrink, J., Milà, C., Ludwig, M., & Meyer, H. (2024). kNNDM CV: k-fold nearest neighbour distance matching cross-validation for map accuracy estimation. Geoscientific Model Development, 17(15), 5897-5912. https://doi.org/10.5194/gmd-17-5897-2024
Milà, C., Mateu, J., Pebesma, E., & Meyer, H. (2022). Nearest neighbour distance matching leave-one-out cross-validation for map validation. Methods in Ecology and Evolution, 13(6), 1304-1316.
cv_nndm, cv_spatial, cv_cluster,
cv_spatial_autocor, and CAST::knndm() for the authors'
CAST implementation of kNNDM. Use cv_plot to visualise, and cv_distance and
cv_similarity to evaluate, the folds.
library(blockCV)
# import presence-absence species data
points <- read.csv(system.file("extdata/", "species.csv", package = "blockCV"))
# make an sf object from data.frame
pa_data <- sf::st_as_sf(points, coords = c("x", "y"), crs = 7845)
# load raster data
path <- system.file("extdata/au/bio_5.tif", package = "blockCV")
covar <- terra::rast(path)
knndm <- cv_knndm(x = pa_data,
column = "occ", # optional
r = covar,
k = 5,
num_sample = 5000)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.