Files

58 lines
2.5 KiB
Python

"""Regola di scelta del modello (docs/algoritmi.md §6) su fit finti."""
from fitseg.analisi import scegli
def fit(nome, k, aicc, rmse=0.1, scala_residui=0.1, **extra):
base = {"modello": nome, "n_parametri": k, "aicc": aicc, "rmse": rmse, "scala_residui": scala_residui, "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 "nessun modello" in motivo
def test_preferisce_i_modelli_adeguati(cfg):
# b ha AICc molto migliore ma la scala dei residui supera soglia·σ; a è adeguato: vince tra gli adeguati
scelto, _, adeguato = scegli([fit("a", 1, -50.0, scala_residui=0.1), fit("b", 3, -500.0, scala_residui=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, scala_residui=1.0)], 0.1, cfg)
assert scelto["modello"] == "a" and adeguato is False
def test_adeguatezza_usa_la_scala_robusta_non_la_rmse(cfg):
# RMSE enorme per via degli scarti casuali, ma la scala robusta dei residui è vicina al rumore: adeguato
scelto, _, adeguato = scegli([fit("a", 3, -50.0, rmse=0.5, scala_residui=0.11)], 0.1, cfg)
assert scelto["modello"] == "a" and adeguato is True
def test_sigma_non_stimabile_adeguatezza_non_valutabile(cfg):
scelto, motivo, adeguato = scegli([fit("a", 1, -50.0)], None, cfg)
assert scelto["modello"] == "a" and adeguato is None and "non valutabile" in motivo
def test_motivo_senza_clausola_di_parsimonia_con_un_solo_candidato(cfg):
assert "meno parametri" not in scegli([fit("a", 1, -50.0)], 0.1, cfg)[1]
assert "meno parametri" in scegli([fit("a", 1, -50.0), fit("b", 3, -50.5)], 0.1, cfg)[1]