fix(ai): bind model scope to immutable geometry
This commit is contained in:
@@ -21,11 +21,8 @@ const DETECTION_PAGE_SIZE_OPTIONS = [25, 50, 100] as const
|
||||
const DEFAULT_DETECTION_PAGE_SIZE = 50
|
||||
|
||||
function detectionQualityInterpretation(f1: number | null | undefined): string {
|
||||
if (typeof f1 !== 'number' || !Number.isFinite(f1)) return 'Nog geen gevalideerde kwaliteitsmeting.'
|
||||
if (f1 >= 0.85) return 'Sterk resultaat; steekproefcontrole blijft vereist.'
|
||||
if (f1 >= 0.70) return 'Bruikbaar met gerichte handmatige controle.'
|
||||
if (f1 >= 0.50) return 'Verkennend resultaat; beoordeel fouten voor operationeel gebruik.'
|
||||
return 'Onvoldoende betrouwbaar voor operationeel gebruik.'
|
||||
if (typeof f1 !== 'number' || !Number.isFinite(f1)) return 'Nog geen onafhankelijke kwaliteitsmeting beschikbaar.'
|
||||
return `Historische F1 ${f1.toFixed(3)} is alleen kalibratiecontext. Een actuele, ruimtelijk onafhankelijke QA-run bepaalt of dit resultaat lokaal bruikbaar is.`
|
||||
}
|
||||
|
||||
function detectionStatusLabel(status: string): string {
|
||||
@@ -311,8 +308,8 @@ export function DetectionLab({
|
||||
<p>{yoloRuntimeReady ? `${yoloPreflight?.runtime.cuda_available ? 'GPU' : 'CPU'} · lokaal model gevonden` : 'Controleer de modelconfiguratie onder beheer.'}</p>
|
||||
</div>
|
||||
<div className="ai-user-summary-card">
|
||||
<span>Validatiescope</span>
|
||||
<strong>{selectedOperatorProfile ? `F1 ${selectedOperatorProfile.f1.toFixed(3)}` : 'Nog niet gekoppeld'}</strong>
|
||||
<span>Bewijsstatus</span>
|
||||
<strong>{selectedOperatorProfile ? `Historische F1 ${selectedOperatorProfile.f1.toFixed(3)}` : 'Nog niet gekoppeld'}</strong>
|
||||
<p>{selectedOperatorProfile ? selectedOperatorProfile.validationScope : 'Kies een modelprofiel met gedocumenteerd evaluatiebewijs.'}</p>
|
||||
</div>
|
||||
<div className={rasterDatasets.length > 0 ? 'ai-user-summary-card ai-user-summary-card-ready' : 'ai-user-summary-card'}>
|
||||
|
||||
@@ -141,7 +141,7 @@ export function DetectionModelManagement({
|
||||
{selectedModelAsset ? 'model gekozen' : 'geen model gekozen'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="operator-profile-grid" aria-label="Gevalideerde YOLO-profielen">
|
||||
<div className="operator-profile-grid" aria-label="Historische YOLO-controleprofielen">
|
||||
{DETECTION_OPERATOR_PROFILES.map((profile) => {
|
||||
const profileAsset = modelAssets.find((asset) => asset.model_asset_id === profile.modelAssetId)
|
||||
const profileSelected =
|
||||
@@ -154,18 +154,18 @@ export function DetectionModelManagement({
|
||||
>
|
||||
<div className="operator-profile-card-header">
|
||||
<strong>{profile.displayName}</strong>
|
||||
<span className={profile.defaultApproved ? 'status-badge status-badge-ready' : 'status-badge'}>
|
||||
{profile.defaultApproved ? 'standaardprofiel' : 'kandidaat, extra controle vereist'}
|
||||
<span className="status-badge">
|
||||
{profile.independentTestProven ? 'onafhankelijk getoetst' : 'historisch, geen releasebewijs'}
|
||||
</span>
|
||||
</div>
|
||||
<p>{profile.description}</p>
|
||||
<div className="operator-profile-metrics">
|
||||
<span>drempel {profile.confidenceThreshold.toFixed(2)}</span>
|
||||
<span>precisie {profile.precision.toFixed(3)}</span>
|
||||
<span>herkenningsgraad {profile.recall.toFixed(3)}</span>
|
||||
<span>F1 {profile.f1.toFixed(3)}</span>
|
||||
<span>testgebieden {profile.positiveSampleCount}</span>
|
||||
<span>max. achtergrondfouten {profile.maxBackgroundDetections}</span>
|
||||
<span>historische precisie {profile.precision.toFixed(3)}</span>
|
||||
<span>historische herkenningsgraad {profile.recall.toFixed(3)}</span>
|
||||
<span>historische F1 {profile.f1.toFixed(3)}</span>
|
||||
<span>positieve controles {profile.positiveSampleCount}</span>
|
||||
<span>gemeten achtergrondfouten {profile.maxBackgroundDetections}</span>
|
||||
</div>
|
||||
<p className="field-guidance">{profile.limitationMessage}</p>
|
||||
<button
|
||||
|
||||
@@ -3,8 +3,7 @@ export interface DetectionOperatorProfile {
|
||||
displayName: string
|
||||
modelAssetId: string
|
||||
confidenceThreshold: number
|
||||
defaultApproved: boolean
|
||||
promotionRecommendation: 'none' | 'promote_candidate'
|
||||
independentTestProven: boolean
|
||||
precision: number
|
||||
recall: number
|
||||
f1: number
|
||||
@@ -21,51 +20,48 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [
|
||||
displayName: 'Aanbevolen controleprofiel kleine gebouwen',
|
||||
modelAssetId: 'geointel-building-yolov8s-smallbld-minpx3-img640-ft30-pt',
|
||||
confidenceThreshold: 0.15,
|
||||
defaultApproved: true,
|
||||
promotionRecommendation: 'promote_candidate',
|
||||
independentTestProven: false,
|
||||
precision: 0.6140895327792112,
|
||||
recall: 0.6062221049337548,
|
||||
f1: 0.6068607646002744,
|
||||
positiveSampleCount: 7,
|
||||
maxBackgroundDetections: 0,
|
||||
validationScope: '7 onafhankelijke testgebieden in Mol en de Kempen',
|
||||
validationScope: 'historische operatorcontrole in Mol en de Kempen; ruimtelijke onafhankelijkheid niet bewezen',
|
||||
description:
|
||||
'Aanbevolen profiel met een evenwicht tussen gevonden en gemiste kleine gebouwen, opnieuw gemeten over zeven onafhankelijke testgebieden in Mol en de Kempen.',
|
||||
'Historisch controleprofiel met een evenwicht tussen gevonden en gemiste kleine gebouwen. Gebruik dit als startpunt voor lokale QA, niet als vrijgavebewijs.',
|
||||
limitationMessage:
|
||||
'De drie lege-achtergrondtests zijn geslaagd. Postel blijft met 47,5% F1 het moeilijkste testgebied; behandel elke detectie als een controlekandidaat en niet als grondwaarheid.',
|
||||
'Slechts drie pure-achtergrondbeelden en geen onafhankelijke hold-out ondersteunen deze historische meting. Postel bleef het moeilijkste gebied; behandel elke detectie als controlekandidaat en niet als grondwaarheid.',
|
||||
},
|
||||
{
|
||||
id: 'expanded-balanced-review',
|
||||
displayName: 'Voorgaand gebalanceerd controleprofiel',
|
||||
modelAssetId: 'geointel-building-yolov8s-aoi1024expandedminpx4vis035e50-pt',
|
||||
confidenceThreshold: 0.15,
|
||||
defaultApproved: true,
|
||||
promotionRecommendation: 'promote_candidate',
|
||||
independentTestProven: false,
|
||||
precision: 0.6470590036169351,
|
||||
recall: 0.4699913836847832,
|
||||
f1: 0.5432865390636915,
|
||||
positiveSampleCount: 7,
|
||||
maxBackgroundDetections: 0,
|
||||
validationScope: '7 onafhankelijke testgebieden in Mol en de Kempen',
|
||||
description: 'Voorgaand profiel voor controles waarbij minder foutieve vondsten belangrijker zijn dan maximale dekking.',
|
||||
validationScope: 'historische operatorcontrole in Mol en de Kempen; ruimtelijke onafhankelijkheid niet bewezen',
|
||||
description: 'Historisch profiel voor lokale controles waarbij minder foutieve vondsten belangrijker zijn dan maximale dekking.',
|
||||
limitationMessage:
|
||||
'De lege-achtergrondtest is geslaagd. Dit profiel vindt minder onterechte objecten, maar mist meer kleine gebouwen dan het aanbevolen profiel.',
|
||||
'Dit profiel vond historisch minder onterechte objecten, maar miste meer kleine gebouwen. De meting is geen onafhankelijke productbenchmark.',
|
||||
},
|
||||
{
|
||||
id: 'conservative-review',
|
||||
displayName: 'Conservatief controleprofiel',
|
||||
modelAssetId: 'geointel-building-yolov8s-aoi1024bg512r3e50-pt',
|
||||
confidenceThreshold: 0.35,
|
||||
defaultApproved: true,
|
||||
promotionRecommendation: 'promote_candidate',
|
||||
independentTestProven: false,
|
||||
precision: 0.840006,
|
||||
recall: 0.202135,
|
||||
f1: 0.32086574003576274,
|
||||
positiveSampleCount: 7,
|
||||
maxBackgroundDetections: 0,
|
||||
validationScope: '7 onafhankelijke testgebieden in Mol en de Kempen',
|
||||
description: 'Profiel met hoge precisie voor controles waarbij zo weinig mogelijk foutieve vondsten zwaarder wegen dan volledige dekking.',
|
||||
validationScope: 'historische operatorcontrole in Mol en de Kempen; ruimtelijke onafhankelijkheid niet bewezen',
|
||||
description: 'Historisch profiel voor lokale controles waarbij zo weinig mogelijk foutieve vondsten zwaarder wegen dan volledige dekking.',
|
||||
limitationMessage:
|
||||
'Goedgekeurd na de lege-achtergrondtest. Resultaten in dun bebouwde context blijven altijd controlebewijs en geen automatische waarheid.',
|
||||
'De historische precisie gaat samen met zeer lage herkenningsgraad. Resultaten blijven controlebewijs en geen automatische waarheid of releasebewijs.',
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user