Cap regional failure oversampling
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-29 17:51:32 +02:00
parent 38a7c62de7
commit a56df8b1ed
4 changed files with 91 additions and 7 deletions
@@ -55,7 +55,7 @@ def test_sampling_repeats_only_failed_region_train_tiles() -> None:
"background": {"pure_empty_false_positives": 2},
}
paths, metadata = MODULE.build_sampling(
summary=summary, manifest=manifest, assessment=assessment
summary=summary, manifest=manifest, assessment=assessment, max_region_share=1.0
)
assert paths.count(str(Path("/tmp/fl-pos.png").resolve())) == 3
assert paths.count(str(Path("/tmp/fl-neg.png").resolve())) == 4
@@ -87,7 +87,7 @@ def test_sampling_can_use_calibration_before_test_is_opened() -> None:
"background": None,
}
paths, metadata = MODULE.build_sampling(
summary=summary, manifest=manifest, assessment=assessment
summary=summary, manifest=manifest, assessment=assessment, max_region_share=1.0
)
assert len(paths) == 3
assert metadata["failure_evidence_source"] == "calibration"
@@ -120,6 +120,7 @@ def test_precision_correction_can_balance_positive_and_negative_tiles() -> None:
assessment=assessment,
precision_positive_repeat=2,
negative_repeat=3,
max_region_share=1.0,
)
assert paths.count(str(Path("/tmp/fl-pos.png").resolve())) == 2
@@ -157,7 +158,9 @@ def test_sampling_targets_failed_calibration_contexts_without_using_protected_ti
},
}
paths, metadata = MODULE.build_sampling(summary=summary, manifest=manifest, assessment=assessment)
paths, metadata = MODULE.build_sampling(
summary=summary, manifest=manifest, assessment=assessment, max_region_share=1.0
)
assert paths.count(str(Path("/tmp/industry-pos.png").resolve())) == 5
assert paths.count(str(Path("/tmp/industry-neg.png").resolve())) == 6
@@ -165,3 +168,42 @@ def test_sampling_targets_failed_calibration_contexts_without_using_protected_ti
assert not any("protected" in path for path in paths)
assert metadata["weak_recall_contexts"] == ["flanders:industrial"]
assert metadata["weak_precision_contexts"] == ["flanders:industrial"]
def test_region_cap_drops_only_repeats_and_preserves_every_unique_tile() -> None:
manifest = {"samples": [
{"sample_slug": "fl", "split": "train", "region": "flanders", "context": "industrial"},
{"sample_slug": "wa", "split": "train", "region": "wallonia", "context": "rural-town"},
{"sample_slug": "br", "split": "train", "region": "brussels", "context": "dense-urban"},
]}
summary = {"tiles": [
{"sample_slug": "fl", "split": "train", "label_count": 2, "image_path": f"/tmp/fl-{index}.png"}
for index in range(4)
] + [
{"sample_slug": "wa", "split": "train", "label_count": 2, "image_path": f"/tmp/wa-{index}.png"}
for index in range(2)
] + [
{"sample_slug": "br", "split": "train", "label_count": 2, "image_path": f"/tmp/br-{index}.png"}
for index in range(2)
]}
assessment = {
"status": "continue_training_loop",
"gates": {"min_region_f1": .45, "min_region_precision": .5, "min_region_recall": .4,
"max_pure_empty_false_positives": 0},
"calibration": {"regions": {
"flanders": {"f1": .2, "precision": .3, "recall": .2},
"wallonia": {"f1": .6, "precision": .6, "recall": .6},
"brussels": {"f1": .6, "precision": .6, "recall": .6},
}},
}
paths, metadata = MODULE.build_sampling(
summary=summary, manifest=manifest, assessment=assessment,
positive_repeat=5, max_region_share=.65,
)
assert all(str(Path(f"/tmp/fl-{index}.png").resolve()) in paths for index in range(4))
assert metadata["pre_cap_entries_by_region"]["flanders"] == 20
assert metadata["sampled_entries_by_region"]["flanders"] == 7
assert metadata["dropped_region_repeat_count"] == 13
assert metadata["sampled_entries_by_region"]["flanders"] / len(paths) <= .65