Files
EquationMiner/README.md
T
davideandClaude Sonnet 5.5 b8c8aeb60e Riscaldamento e raffreddamento esponenziali con c e tau condivisi; grafici per dominio nel report
- modelli per tipo di dominio ([fit.modelli_per_tipo])
- nei domini di riscaldamento c e tau fissati ai valori del raffreddamento
- un grafico dati/modelli per dominio e serie, incorporato in report.md

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-29 09:58:53 +01:00

7.4 KiB
Raw Blame History

fitseg

Legge un CSV t_ms,T_C,dT_C (temperatura di un sensore IR che si scalda e si raffredda), riconosce quando c'è riscaldamento (gradini di flusso in entrata) e quando c'è raffreddamento, divide il tempo in domini e trova per ogni dominio e ogni serie l'equazione che approssima meglio i dati, con minimi quadrati non lineari.

Risultato per ogni dominio: modello scelto, parametri con intervallo di confidenza al 95 %, metriche (RMSE, R², AICc, BIC, autocorrelazione dei residui), grafici e un report in Markdown.

Requisiti

  • Python ≥ 3.11
  • uv (consigliato): curl -LsSf https://astral.sh/uv/install.sh | sh
  • Dipendenze: numpy, scipy, matplotlib (più pytest e ruff per lo sviluppo)

Installazione

uv venv .venv
uv pip install -e ".[dev]"

Il programma si lancia con .venv/bin/fitseg (oppure source .venv/bin/activate e poi fitseg).

Dati di ingresso

Un CSV con intestazione, tempo crescente e una o più serie:

t_ms,T_C,dT_C
151,22.90,0.20
301,22.63,0.03

I nomi delle colonne, l'unità del tempo (ms o s) e il separatore sono in config.toml, sezione [dati].

I CSV di prova vengono dal generatore ../gen_data (repository separato). I test usano i seed 1, 2 e 3 in dati/ (cartella ignorata da git):

mkdir -p dati
for s in 1 2 3; do
  (cd ../gen_data && .venv/bin/python genera.py config.toml --seed $s -o ../EquationMiner/dati/gen_$s.csv)
done

Uso

fitseg domini dati/gen_1.csv        # solo i domini: tabella a schermo + lavoro/domini.toml
fitseg analizza dati/gen_1.csv      # domini + fit + scelta + report in lavoro/out/
fitseg modelli                      # catalogo dei modelli con equazioni e parametri
fitseg valuta lavoro/out/modello_finale.json --t 10 30 60    # valuta il modello a tratti in questi istanti

Le opzioni globali --config PATH (default config.toml) e --lavoro DIR (default lavoro) vanno prima del sottocomando:

fitseg --config altra.toml --lavoro prova1 analizza dati/gen_2.csv

Correggere i domini a mano

fitseg domini (e analizza) scrive la proposta automatica in lavoro/domini.toml:

[[dominio]]
tipo = "riscaldamento"   # riposo | riscaldamento | raffreddamento
t0_s = 15.8              # incluso
t1_s = 17.76             # escluso (l'ultimo dominio arriva a fine dati)

Modifica i tempi, aggiungi o togli blocchi [[dominio]] (devono restare contigui) e rilancia:

fitseg analizza dati/gen_1.csv --domini lavoro/domini.toml

Cosa produce

Tutto in lavoro/ (ignorata da git):

File Contenuto
domini.toml proposta dei domini (o quelli che hai usato)
dati.csv copia del CSV analizzato
out/report.md con i grafici incorporati (si vede bene in un visualizzatore Markdown); per dominio e serie: modello scelto, parametri ± IC 95 %, metriche, tabella di confronto di tutti i modelli
out/equazioni.md solo le equazioni scelte
out/modello_finale.json modello e parametri per dominio e serie (input di valuta)
out/risultati.json tutti i fit con tutte le metriche
out/fit_<serie>.png panoramica: dati, fit a tratti (un colore per tipo di dominio) e residui
out/dominio<k>_<serie>.png un grafico per dominio e serie: dati grezzi contro il modello scelto (rosso) e gli altri modelli validi (tratteggiati), più residui; i campioni esclusi dal fit sono in grigio

Come leggere il report

  • Scelto: il modello con meno parametri tra quelli equivalenti per AICc (ΔAICc ≤ 2) e validi (convergenti, parametri lontani dai limiti, identificabili).
  • modello non adeguato: l'RMSE supera 1.3 volte il rumore stimato. Il modello migliore disponibile non spiega tutto: guarda l'ACF1 dei residui.
  • Indeterminato: nessun modello è valido, oppure il dominio ha meno di n_min_punti campioni.
  • Nel raffreddamento, τ è la costante di tempo e c la temperatura asintotica (≈ ambiente per T_C, ≈ 0 per dT_C).

Come funziona

  1. Domini: un salto positivo tra due campioni consecutivi sopra soglia_gradino_c è un gradino di riscaldamento. Prima del primo gradino il dominio è riposo, tra due gradini riscaldamento, dopo l'ultimo raffreddamento.
  2. Fit: in ogni dominio, con il tempo traslato a t' = t − t0, si fittano i modelli del suo tipo con scipy.optimize.least_squares e perdita robusta. Riscaldamento e raffreddamento sono esponenziali; nel riscaldamento c e τ sono fissati ai valori del raffreddamento (i tratti sono troppo corti per stimarli) e si stima solo l'ampiezza.
  3. Scelta: regola automatica (SPEC §5.3), senza intervento umano.

Dettagli, modelli e limiti: docs/SPEC.md. Uso esteso: docs/USO.md.

Modelli

Id Equazione
costante y = a
lineare y = a + b·t'
quadratico y = a + b·t' + c·t'²
esp_decad y = c + A·exp(−t'/τ)
esp_doppio y = c + A1·exp(−t'/τ1) + A2·exp(−t'/τ2)
logistica y = c + A / (1 + exp(−(t'−t_m)/w))

Per aggiungerne uno: nuova voce in MODELLI di src/fitseg/modelli.py, nuova riga in SPEC §4 e nome nelle liste di [fit.modelli_per_tipo] dei tipi di dominio in cui va provato.

Configurazione

Tutti i valori sono in config.toml; non c'è nessun default nel codice (chiave mancante = errore). Quelle che conviene conoscere:

Chiave Effetto
[domini] soglia_gradino_c salto minimo che segna un gradino (20 °C); da adattare se i gradini reali sono più piccoli
[domini] scarta_dopo_salto_n campioni esclusi all'inizio di un dominio dopo un gradino (transizione del sensore)
[domini] n_min_punti campioni minimi per dominio
[fit.modelli_per_tipo] modelli provati per tipo di dominio (riposo: costante/lineare/esponenziale; riscaldamento e raffreddamento: esponenziale)
[fit] riscaldamento_fissa_da_raffreddamento parametri dei domini di riscaldamento fissati al valore del raffreddamento (["c", "tau"]; [] = liberi)
[fit] soglia_delta_aicc entro questa differenza vince il modello con meno parametri
[fit] rmse_vs_rumore_max soglia di «adeguato» (RMSE ≤ valore × σ rumore)
[fit] seed seme delle partenze multiple: stessi dati e stessa config danno gli stessi risultati

Test

.venv/bin/pytest                     # tutti
.venv/bin/pytest -k raffreddamento   # uno solo

I test verificano, sui seed 1–3, che i domini siano riposo, riscaldamento, riscaldamento, raffreddamento, che nel raffreddamento vinca esp_decad con τ entro il 10 % di 15.9 s, che nel riscaldamento sia esp_decad con c e τ del raffreddamento e che il riposo sia costante. Richiedono dati/gen_1.csv, gen_2.csv, gen_3.csv (vedi sopra).

Codici di uscita

0 ok · 2 uso errato · 3 configurazione non valida · 4 CSV illeggibile o non valido · 6 domini non validi.

Limiti noti

  • Nel raffreddamento i residui sono autocorrelati (ACF1 ≈ 0.7) per scarti casuali e deriva lenta del sensore: i parametri sono buoni, ma gli intervalli di confidenza sono troppo stretti e il dominio risulta «non adeguato».
  • I domini di riscaldamento sono corti (2–4 s): τ non è identificabile da solo e viene preso dal raffreddamento; gli IC di A sono condizionati a quei valori fissi.
  • Ogni dominio è fittato in modo indipendente: nessun vincolo di continuità tra domini.
  • Provato su 3 seed; non su file senza gradini o con un solo gradino.