2026-10-29 10:44:41 +01:00
|
|
|
"""Regola di scelta del modello (docs/algoritmi.md §6) su fit finti."""
|
2026-10-29 10:13:01 +01:00
|
|
|
|
|
|
|
|
from fitseg.analisi import scegli
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fit(nome, k, aicc, rmse=0.1, **extra):
|
|
|
|
|
base = {"modello": nome, "n_parametri": k, "aicc": aicc, "rmse": rmse, "convergenza": True,
|
|
|
|
|
"parametri_a_limite": [], "non_identificabile": False}
|
|
|
|
|
return {**base, **extra}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_vince_meno_parametri_entro_delta(cfg):
|
|
|
|
|
scelto, _, _ = scegli([fit("a", 1, -100.0), fit("b", 3, -101.0)], 0.1, cfg) # ΔAICc = 1 < 2
|
|
|
|
|
assert scelto["modello"] == "a"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_vince_il_migliore_oltre_delta(cfg):
|
|
|
|
|
scelto, _, _ = scegli([fit("a", 1, -100.0), fit("b", 3, -110.0)], 0.1, cfg)
|
|
|
|
|
assert scelto["modello"] == "b"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_scarta_non_validi(cfg):
|
|
|
|
|
fits = [fit("a", 1, -200.0, non_identificabile=True), fit("b", 2, -100.0),
|
|
|
|
|
fit("c", 2, -300.0, parametri_a_limite=["tau"]), fit("d", 2, -400.0, convergenza=False)]
|
|
|
|
|
assert scegli(fits, 0.1, cfg)[0]["modello"] == "b"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_nessun_valido_indeterminato(cfg):
|
|
|
|
|
scelto, motivo, adeguato = scegli([fit("a", 1, -1.0, non_identificabile=True)], 0.1, cfg)
|
|
|
|
|
assert scelto is None and not adeguato and "indeterminato" in motivo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_preferisce_i_modelli_adeguati(cfg):
|
|
|
|
|
# b ha AICc molto migliore ma RMSE oltre soglia·σ; a è adeguato: vince tra gli adeguati
|
|
|
|
|
scelto, _, adeguato = scegli([fit("a", 1, -50.0, rmse=0.1), fit("b", 3, -500.0, rmse=1.0)], 0.1, cfg)
|
|
|
|
|
assert scelto["modello"] == "a" and adeguato
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_nessun_adeguato_lo_segnala(cfg):
|
|
|
|
|
scelto, _, adeguato = scegli([fit("a", 1, -50.0, rmse=1.0)], 0.1, cfg)
|
|
|
|
|
assert scelto["modello"] == "a" and not adeguato
|