Comment interpréter la matrice de covariance à partir d'un ajustement de courbe?

15

Je ne suis pas trop doué en statistiques, donc je m'excuse s'il s'agit d'une question simpliste. J'ajuste une courbe à certaines données, et parfois mes données correspondent le mieux à une exponentielle négative sous la forme , et parfois l'ajustement est plus proche de a e ( - b x 2 ) + c . Cependant, parfois ces deux échouent, et je voudrais revenir à un ajustement linéaire. Ma question est, comment puis-je déterminer quel modèle correspond le mieux à un ensemble de données particulier à partir de la matrice de variance-covariance qui est renvoyée par leunee(-bX)+cunee(-bX2)+cFonction scipy.optimize.curve_fit () ? Je crois que la variance est sur l'une des diagonales de cette matrice, mais je ne sais pas comment interpréter cela.

MISE À JOUR: Sur la base d'une question similaire , j'espère que la matrice de variance-covariance pourra me dire lequel des trois modèles que j'essaye correspond le mieux aux données (j'essaie d'adapter de nombreux jeux de données à l'un de ces trois modèles).

Les matrices résultantes ressemblent à ceci pour l'exemple donné:

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]]

Voici un exemple de ce que je fais:

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()
Jason Martens
la source
C'est formidable que vous vous connectiez à cette question CV et, par conséquent, au fil de commentaire important (n / b rolando2, Frank Harrell, ...) se demandant s'il est approprié de choisir le modèle post facto en fonction de l'ajustement. Il est peut-être préférable d'utiliser les connaissances préalables du système pour choisir le modèle.
Aman
Cette autre question sur le CV pourrait être utile: stats.stackexchange.com/questions/50830/…
Aman
Cela pourrait-il être utile pour comprendre comment interpréter la matrice de co-variance stats.stackexchange.com/questions/10795/… - Je dirais que la valeur des troisièmes modèles est plus petite, indiquant moins d'écart.
user4581

Réponses:

4

À titre de clarification, la variable pcovde scipy.optimize.curve_fitest la covariance estimée de l'estimation du paramètre, c'est-à-dire, étant donné les données et un modèle, la quantité d'informations contenues dans les données pour déterminer la valeur d'un paramètre dans le modèle donné. Il ne vous dit donc pas vraiment si le modèle choisi est bon ou non. Voir aussi ceci .

Le problème qu'est un bon modèle est en effet un problème difficile. Comme le soutiennent les statisticiens

Tous les modèles sont faux, mais certains sont utiles

Les critères à utiliser pour comparer différents modèles dépendent donc de ce que vous souhaitez réaliser.

Par exemple, si vous voulez une courbe qui soit la plus proche possible des données, vous pouvez sélectionner un modèle qui donne le plus petit résidu . Dans votre cas, ce serait le modèle funcet les paramètres estimés poptqui ont la valeur la plus faible lors du calcul

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

Cependant, si vous sélectionnez un modèle avec plus de paramètres, le résidu diminuera automatiquement , au prix d'une complexité de modèle plus élevée. Alors, cela revient à l'objectif du modèle.

hakanc
la source