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 leFonction 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()
la source
Réponses:
À titre de clarification, la variable
pcov
descipy.optimize.curve_fit
est 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
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
func
et les paramètres estiméspopt
qui ont la valeur la plus faible lors du calculCependant, 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.
la source