Skip to content

manaakiwhenua/spatial-stratified-sampling

Repository files navigation

Spatial stratified sampling

manaakiwhenua-standards

Utilities for creating a (validated) stratified sample from a GeoDataFrame and preparing it for manual map-accuracy checks.

How it works

For each unique value in --groupby-column (a "stratum" — e.g. a land-use class), the script:

  1. Computes a sample size n using the standard formula for estimating a proportion at a given confidence level (--confidence-z) and margin of error (--margin-error), with a finite-population correction for that stratum's size N.
  2. Clips n to [--min-samples, N]:
    • Floor (--min-samples): every stratum gets at least this many samples, even if the formula says fewer would do — so rare classes still get a statistically useful sample for accuracy checking. Small strata are therefore sampled at a higher rate than large ones.
    • Cap (N): you can never sample more rows than exist — if a stratum has fewer than --min-samples features, the entire stratum is taken.
  3. Draws n features from the stratum, optionally weighted by --bias-column (with an optional --fractional-power transform of those weights), so e.g. larger polygons are more likely to be picked.

The combined sample is then passed through map_accuracy_prep (adds mapped/truth/checked/comment columns for review) and sample_group (splits the output into --n-groups review batches).

Installation

Requires Python 3.9+. Once published, install from PyPI:

pip install spatial-stratified-sampling

This installs the stratified-sample command-line tool. To install from a local clone instead (e.g. for development), run pip install -e . (or pip install -e ".[dev]" to also pull in test dependencies) from the project root. Alternatively, install just the runtime dependencies with pip install -r requirements.txt and run python stratified_sample.py directly without installing the package.

geopandas depends on GDAL/GEOS/PROJ; if pip install fails to build these, installing geopandas via conda/mamba (e.g. conda install -c conda-forge geopandas) is usually easier — install the remaining dependencies afterwards.

Usage

Run with named flags, either via the installed command or the script directly (equivalent):

stratified-sample \
  --input input.gpkg \
  --output output.gpkg \
  --groupby-column lu_coden \
  --n-groups 3

python stratified_sample.py \
  --input input.gpkg \
  --output output.gpkg \
  --groupby-column lu_coden \
  --n-groups 3

See stratified-sample --help for full details, or the examples below.

Key options

  • --input / -i (required): input vector (GeoPackage, Shapefile, etc.)
  • --output / -o (required): output vector path to write sampled features
  • --groupby-column / -g (required): column name to stratify by
  • --n-groups (default 1): number of sample groups to assign (for review batching), written to a sample_group column
  • --bias-column / -b (default: none): optional column name to bias sampling by (use area to bias by geometry area)
  • --fractional-power / -f (default: none): power transform applied to bias weights, must be < 1 (use 0 for a log1p transform)
  • --random-state / -r (default: random): random seed for reproducible sampling. If omitted, a random seed is generated and printed so the run can be reproduced later
  • --confidence-z (default 1.96): z-score for the desired confidence level
  • --margin-error (default 0.05): acceptable margin of error for the sample-size calculation
  • --min-samples (default 30): minimum number of samples drawn from each stratum
  • --no-explode: by default, multipart geometries are split into single-part features before sampling; pass this flag to skip that step

Examples

Plain stratified sample — default 95% confidence / 5% margin of error, at least 30 features per class, split into 3 review batches:

python stratified_sample.py \
  --input input.gpkg \
  --output output.gpkg \
  --groupby-column lu_coden \
  --n-groups 3

Reproducible sample — if --random-state is omitted, a random seed is generated and printed to the console (e.g. pass --random-state 123456789 to reproduce this sample). To get a fresh random sample, just omit --random-state; to reproduce a previous run exactly, pass the seed it printed:

python stratified_sample.py \
  --input input.gpkg \
  --output output.gpkg \
  --groupby-column lu_coden \
  --n-groups 3 \
  --random-state 123456789

Area-weighted sample with a fourth-root transform — bigger polygons are more likely to be picked, but the transform (power 0.25) dampens the bias so very large polygons don't dominate the sample. Also uses a wider 10% margin of error:

python stratified_sample.py \
  --input input.gpkg \
  --output output.gpkg \
  --groupby-column lu_coden \
  --n-groups 3 \
  --bias-column area \
  --fractional-power 0.25 \
  --margin-error 0.1 \
  --min-samples 30

Area-weighted sample with a log transform — a milder alternative to a fractional power; use --fractional-power 0 for log1p(area) weights:

python stratified_sample.py \
  --input input.gpkg \
  --output output.gpkg \
  --groupby-column lu_coden \
  --bias-column area \
  --fractional-power 0

Quick spot-check — a small, single-batch sample for a fast sanity check rather than a full accuracy assessment (lower --min-samples, no review batching):

python stratified_sample.py \
  --input input.gpkg \
  --output output.gpkg \
  --groupby-column lu_coden \
  --min-samples 10

Tighter confidence requirements — a 99% confidence interval (z = 2.576) with a 3% margin of error, for a more rigorous accuracy assessment (larger n per stratum):

python stratified_sample.py \
  --input input.gpkg \
  --output output.gpkg \
  --groupby-column lu_coden \
  --confidence-z 2.576 \
  --margin-error 0.03 \
  --min-samples 50

Output columns

In addition to the sampled features' original attributes, the output contains:

  • mapped: the stratification class the feature was originally mapped as
  • truth: initially a copy of mapped; intended to be edited during review to record the correct class
  • checked: review status flag, initialised to -1
  • comment: free-text review comment, initially empty
  • sample_group: review batch index (0 to --n-groups - 1)

Tests

pip install -e ".[dev]"
pytest

About

Draw a validated stratified sample from a vector dataset and prepare it for manual map-accuracy review

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages