fix(sugestii): inlocuirea de anvelope -> OE-8 + vot k-NN ponderat pe rang

Seed-ul Haiku eticheta sistematic "INLOCUIT ANVELOPE ..." cu OE-1 (223 vs 17
OE-8), desi RAR are cod dedicat OE-8 (inlocuire sezoniera anvelope), asa ca
votul k-NN propunea OE-1 pentru orice inlocuire de anvelope.

- tools/mapare-llm/fix_anvelope_oe8.py: re-etichetare deterministica (187
  randuri DB + seed JSON -> OE-8; regula exclude singular cu pozitie, D/R,
  janta, vulcanizare) + 13 intrari canonice curate manual pentru formularile
  sezoniere absente din corpus ("MONTAT CAUCIUCURI VARA" etc.); idempotent
- enrich_suggestions: ponderea votului = EMB_VOTE_DECAY^rang (0.7) in loc de
  similaritatea bruta — anizotropia modelului lasa zgomotul de coada (ex.
  INLOCUIT BECURII la 0.934 de INLOCUIRE ANVELOPE) sa invinga vecinii corecti
  de rang 1-2; LOO: precizie egala (93.1%), cod-gresit 4.67% -> 4.63%
- test_fix_anvelope_oe8: gardii pe regula + seed-ul din repo (regresie la
  regenerare); auditul k-NN al dezacordurilor nu a gasit alte erori
  sistematice (curatat=OE-2, reglat=OE-4, bujii/ulei=OE-3 raman apararabile)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-07-07 10:26:00 +00:00
parent 809823a8ae
commit 6674d0e3e1
5 changed files with 722 additions and 384 deletions

View File

@@ -10,9 +10,12 @@ NU ground-truth uman — valorile absolute sunt optimiste; comparatia RELATIVA
intre politici si calibrarea pragului raman valide (aceeasi tinta pentru toate).
Politici evaluate:
top1 — eticheta primului vecin (comportamentul curent din enrich_suggestions)
vote<k> — vot ponderat cu similaritatea pe top-k vecini peste prag;
NUL e eticheta proprie (castiga -> supresie)
top1 — eticheta primului vecin
vote<k> — vot ponderat pe rang (EMB_VOTE_DECAY^rang) pe top-k vecini peste
prag; NUL e eticheta proprie (castiga -> supresie). Politica
livrata in enrich_suggestions. Ponderarea cu similaritatea bruta
a fost respinsa: anizotropia modelului lasa zgomotul de coada
(sim ~0.93 pe vecini fara legatura) sa invinga rangurile 1-2.
Metrice (per politica x prag):
coverage — % din exemple pentru care se emite o predictie (cod sau NUL)
@@ -85,12 +88,13 @@ def predict_top1(nbr_labels: list[str], nbr_sims: np.ndarray, prag: float) -> st
def predict_vote(nbr_labels: list[str], nbr_sims: np.ndarray, prag: float) -> str | None:
"""Vot ponderat cu similaritatea pe vecinii peste prag."""
"""Vot ponderat pe rang (decay^rang) pe vecinii peste prag — politica din enrich."""
from app.mapping import EMB_VOTE_DECAY
scoruri: dict[str, float] = {}
for lab, sim in zip(nbr_labels, nbr_sims):
for rang, (lab, sim) in enumerate(zip(nbr_labels, nbr_sims), 1):
if sim < prag:
continue
scoruri[lab] = scoruri.get(lab, 0.0) + float(sim)
scoruri[lab] = scoruri.get(lab, 0.0) + EMB_VOTE_DECAY ** rang
if not scoruri:
return None
return max(scoruri, key=lambda k: scoruri[k])