agentleFS
esmailhussienesmailhussien/terraproof/skills/accuracy-assessment/SKILL.md

accuracy-assessment

Skill0 starsChanged 24 days agoMITView on GitHub

Design and analyze a statistically defensible accuracy assessment for a classified or change map, covering probability sampling stratified by map class, the response design, area-weighted confusion matrices, overall/user's/producer's accuracy with confidence intervals, and stratified area-adjusted class areas; use whenever a land-cover or change map's accuracy or class areas will be reported.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 5 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use a probability sampling design: every unit in the population has a known, non-zero inclusion probability [S1, S4].

    line 32
  2. Distinctive:

    Do not reuse training, calibration or hand-picked "clear" points.

    line 41
  3. Distinctive:

    Keep the sampling seed, frame, strata raster and unit list, so the sample can be regenerated.

    line 50
  4. Distinctive:

    If the strata are not the map classes being assessed (e.g.

    line 53
  5. Distinctive:

    When strata are the map classes (simple random, systematic or stratified random sampling), estimate each cell as a proportion of area [S1, …

    line 77
  6. Very specific:

    Keep the counts matrix, A_m,i per stratum, CRS/area method and the code version with the results so that the numbers can be recomputed.

    line 156

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Accuracy assessment and area estimation

Report estimates, not pixel counts

A map's class pixel counts are not an unbiased estimate of class area: every omission and commission error shifts area between classes, and rare classes (such as change) are often affected most. Good practice is to estimate area from the reference classification of a probability sample, using the map to stratify, and to report confidence intervals for accuracy and area [S1, S2].

Worked example (counts from Olofsson et al. 2014, Table 8, recomputed with the estimator in the reference): the map shows 18,000 ha of deforestation; the stratified estimate is 21,158 ha ± 6,158 ha (95 % CI). Reporting 18,000 ha as "the area" hides both the bias and the uncertainty.

The workflow has three parts, each documented in the report: sampling design, response design and analysis [S1, S3, S4]. Use statistical analysis for general statistics and time series and change for producing change maps. Shared rules: engineering, simplicity, security.

Sampling design: stratified random by map class

Use a probability sampling design: every unit in the population has a known, non-zero inclusion probability [S1, S4]. Stratified random sampling with the final map classes as strata is the common choice for change and rare classes, because it guarantees samples in small strata [S1, S2].

  • Draw the sample from the final map that will be reported, within the exact reporting region. Record every stratum's mapped area A_m,i (in an equal-area CRS or with true per-pixel areas; see CRS and units).
  • Do not reuse training, calibration or hand-picked "clear" points; they are not a probability sample and give unknown bias.
  • Allocation: equal allocation favours user's accuracy of rare classes; proportional allocation usually gives smaller standard errors for overall and producer's accuracy. A compromise with a minimum per stratum is suggested [S2]. FAO cites a minimum of 20 to 100 samples per stratum (Congalton and Green) [S2].
  • Size the sample from a target standard error and anticipated user's accuracies, following the sample-size section of Olofsson et al. (after Cochran 1977) [S1, S2]. No sample size makes a biased (non-probability) sample valid.
  • Keep the sampling seed, frame, strata raster and unit list, so the sample can be regenerated.

If the strata are not the map classes being assessed (e.g. a stratification from an older map), the estimators below do not apply directly; use the estimator for strata that differ from map classes [S5].

Response design: how reference labels are decided

The response design specifies the spatial assessment unit (pixel, block or polygon), the reference data sources, the labeling protocol and the definition of agreement [S1, S2, S4].

  • The reference classification must be more accurate than the map: a better source (finer resolution, field data) or a more careful process (expert visual interpretation of the same imagery) [S2].
  • Reference data should be temporally coincident with the map (for change: cover both dates); otherwise area estimates refer to the reference date [S2].
  • Define the minimum mapping unit, rules for mixed units and the agreement rule before labeling [S2]. Interpret blind to the map label where feasible.
  • Record interpreter, source image/date and confidence per unit; evaluate reference-label variability rather than assuming the reference is perfect [S1].

Confusion matrix in proportion of area

Rows are map classes (strata) i, columns reference classes j, n_ij sample counts, n_i· the row total, W_i = A_m,i / A_tot the mapped area proportion. When strata are the map classes (simple random, systematic or stratified random sampling), estimate each cell as a proportion of area [S1, S2]:

p_ij = W_i * n_ij / n_i·

Report this estimated matrix (in area proportions), not only raw counts [S1]. Raw-count matrices from a stratified sample over-represent rare strata and give biased overall and producer's accuracies if used directly.

Overall, user's and producer's accuracy

From the area-proportion matrix [S1, S2]:

overall accuracy      O   = Σ_j p_jj
user's accuracy       U_i = p_ii / p_i·      (= n_ii / n_i· under this design)
producer's accuracy   P_j = p_jj / p_·j
commission error      = 1 - U_i
omission error        = 1 - P_j

User's accuracy answers "if the map says class i, how often is it i?"; producer's accuracy answers "of the true class j area, how much is mapped as j?" [S2]. Report all three with confidence intervals (variances in the reference) [S1].

Kappa is not recommended as an accuracy measure [S2, S6]; do not report it as a substitute for these estimates.

Area-adjusted estimates with confidence intervals

Estimate the area of reference class k from the column of the area-proportion matrix, with the stratified-estimator standard error [S1, S2]:

p_·k      = Σ_i W_i * n_ik / n_i·
A_k       = A_tot * p_·k
SE(p_·k)  = sqrt( Σ_i W_i² * (n_ik / n_i·) * (1 - n_ik / n_i·) / (n_i· - 1) )
SE(A_k)   = A_tot * SE(p_·k)
95 % CI   = A_k ± 1.96 * SE(A_k)

A_tot and A_m,i must be true areas (or pixel counts in an equal-area grid multiplied by pixel area). The 1.96 factor is the large-sample normal approximation used in the guidance [S2]; with very small strata or proportions near 0 or 1, state that the interval is approximate. For a random-start systematic sample, these variance formulas are approximate and typically overestimate uncertainty [S1]. They assume pixel units with hard map/reference labels; polygon units or mixed labels require other estimators.

A stratum needs at least 2 sample units (division by n_i· - 1); a class with no reference sample has an estimated area of zero with an uninformative SE, which is a design gap to report, not evidence of absence.

Compute the estimates

Full, tested Python for accuracy, variances and areas, with the worked example above, is in references/stratified-estimator.md. Minimal area estimate:

import numpy as np

def stratified_area(counts, mapped_area, z=1.96):
    n = np.asarray(counts, dtype=float)        # rows: map strata, cols: reference
    a_map = np.asarray(mapped_area, dtype=float)
    n_i = n.sum(axis=1)
    if np.any(n_i < 2):
        raise ValueError("every stratum needs at least 2 sample units")
    w = a_map / a_map.sum()
    frac = n / n_i[:, None]
    area = a_map.sum() * (w[:, None] * frac).sum(axis=0)
    se = a_map.sum() * np.sqrt((w[:, None] ** 2 * frac * (1 - frac)
                                / (n_i[:, None] - 1)).sum(axis=0))
    return area, z * se

Keep the counts matrix, A_m,i per stratum, CRS/area method and the code version with the results so that the numbers can be recomputed.

Report checklist

  • Sampling design (strata, allocation, sample size rationale, seed) and the map version sampled.
  • Response design (unit, sources and dates, labeling protocol, agreement rule, interpreter procedure) and any deviations from good practice [S1].
  • Estimated error matrix in area proportions; overall, user's and producer's accuracy with 95 % CIs.
  • Mapped area and stratified area estimate with 95 % CI per class; say which one any downstream number uses.
  • Limitations: reference-label uncertainty, strata/class mismatch, missing strata.

Verify with Terraproof

Existing checks help with the inputs, not with the statistics:

python -m terraproof check classified_map.tif --operation area
python -m terraproof check sample_points.gpkg

crs.defined, crs.consistent and raster.nodata_declared check map/sample metadata; geometry.valid, geometry.non_empty, geometry.type_consistent and scope.record_count check the sample file. With --operation area, crs.metric_operation fails geographic/geocentric CRSs and passes projected metre/foot CRSs; it does not confirm an equal-area projection.

python -m terraproof check classified_map.tif --accuracy-samples samples.json --class-areas areas.json --min-per-class 50 --estimates-requested

samples.json contains reference records with map_class, ref_class and optional stratum_weight; areas.json maps each map class to its mapped area in consistent units. accuracy.sample_design checks class coverage, counts and declared weights. The default minimum of 50 per class is a configurable design convention, not a precision guarantee. accuracy.estimates computes the area-weighted matrix, accuracy estimates and approximate intervals, plus area-adjusted class areas. It does not compare an external published report's claims with those estimates.

Not checked automatically: whether the sample was truly probability-based, whether reference labels are correct or temporally coincident, response-design rules, and whether reported numbers are used correctly downstream. See verification.

Sources

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.