Come posso interpretare la matrice di covarianza da un adattamento di curva?


15

Non sono troppo bravo nelle statistiche, quindi mi scuso se questa è una domanda semplicistica. Sto adattando una curva ad alcuni dati, e talvolta i miei dati si adattano meglio a un esponenziale negativo nella forma , e talvolta l'adattamento è più vicino a . Tuttavia, a volte entrambi falliscono e mi piacerebbe tornare a un adattamento lineare. La mia domanda è: come posso determinare quale modello si adatta a un determinato set di dati il ​​meglio dalla matrice di varianza-covarianza risultante che viene restituita dalla funzione scipy.optimize.curve_fit () ? Credo che la varianza sia su una delle diagonali di questa matrice, ma non sono sicuro di come interpretarlo.un'*e(-B*X)+cun'*e(-B*X2)+c

AGGIORNAMENTO: Sulla base di una domanda simile , spero che la matrice varianza-covarianza possa dirmi quale dei tre modelli che sto tentando si adatta meglio ai dati (sto cercando di adattare molti set di dati a uno di questi tre modelli).

Le matrici risultanti appaiono così per l'esempio dato:

pcov_lin 
[[  2.02186921e-05  -2.02186920e-04]
 [ -2.02186920e-04   2.76322124e-03]]
pcov_exp
[[  9.05390292e+00  -7.76201283e-02  -9.20475334e+00]
 [ -7.76201283e-02   6.69727245e-04   7.90218415e-02]
 [ -9.20475334e+00   7.90218415e-02   9.36160310e+00]]
pcov_exp_2 
[[  1.38338049e-03  -7.39204594e-07  -7.81208814e-04]
 [ -7.39204594e-07   8.99295434e-09   1.92970700e-06]
 [ -7.81208814e-04   1.92970700e-06   9.14746758e-04]]

Ecco un esempio di quello che sto facendo:

import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
import scipy.optimize

def exp_func(x, a, b, c):
    return a * np.exp(-b * x) + c

def exp_squared_func(x, a, b, c):
    return a * np.exp(-b * x*x*x) + c

def linear_func(x, a, b):
    return a*x + b

def main():
    x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], np.float)
    y = np.array([1, 1, 1, 1, 0.805621, 0.798992, 0.84231, 0.728796, 0.819471, 0.570414, 0.355124, 0.276447, 0.159058, 0.0762189, 0.0167807, 0.0118647, 0.000319948, 0.00118267, 0, 0, 0], np.float)

    p0 = [0.7746042467213462, 0.10347274384077858, -0.016253458007293588]
    popt_lin, pcov_lin      = scipy.optimize.curve_fit(linear_func, x, y)
    popt_exp, pcov_exp      = scipy.optimize.curve_fit(exp_func, x, y)
    popt_exp_2, pcov_exp_2  = scipy.optimize.curve_fit(exp_squared_func, x, y)

    plt.figure()
    plt.plot(x, y, 'ko', label="Original data")
    plt.plot(x, linear_func(x, *popt_lin), 'r-', label='linear')
    plt.plot(x, exp_func(x, *popt_exp), 'b-', label='exponential')
    plt.plot(x, exp_squared_func(x, *popt_exp_2), 'g-', label='exponential squared')
    plt.legend()
    plt.show()

if __name__ == '__main__':
    main()

È bello che tu ti colleghi a quella domanda CV e, di conseguenza, all'importante thread di commenti (b / n rolando2, Frank Harrell, ...) chiedendoti se è appropriato scegliere il modello post facto in base all'adattamento. Forse è meglio usare una conoscenza precedente del sistema per scegliere il modello.
Aman,

Quest'altra domanda sul CV potrebbe essere utile: stats.stackexchange.com/questions/50830/…
Aman,

Potrebbe essere utile capire come interpretare le matrici di co-varianza stats.stackexchange.com/questions/10795/… - Direi che il valore dei terzi modelli è più piccolo, indicando una minore deviazione.
user4581

Risposte:


4

A titolo di chiarimento, la variabile pcovdi scipy.optimize.curve_fitè la covarianza stimata della stima dei parametri, vale a dire vagamente, dati i dati e un modello, quante informazioni ci sono nei dati per determinare il valore di un parametro nel modello dato. Quindi non ti dice davvero se il modello scelto è buono o no. Si veda anche questo .

Il problema di ciò che è un buon modello è davvero un problema difficile. Come sostenuto dagli statistici

Tutti i modelli sono sbagliati, ma alcuni sono utili

Pertanto, i criteri da utilizzare in confronto a diversi modelli dipendono da ciò che si desidera ottenere.

Ad esempio, se si desidera una curva che sia "il più vicino possibile" ai dati, è possibile selezionare un modello che fornisca il residuo più piccolo . Nel tuo caso sarebbe il modello funce i parametri stimati poptche hanno il valore più basso durante il calcolo

numpy.linalg.norm(y-func(x, *popt))

Tuttavia, se si seleziona un modello con più parametri, il residuo diminuirà automaticamente , a scapito della maggiore complessità del modello. Quindi torna a quello che l'obiettivo del modello è.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.