No soy muy bueno en estadística, así que pido disculpas si esta es una pregunta simplista. Estoy ajustando una curva a algunos datos, y a veces mis datos se ajustan mejor a una exponencial negativa en la forma $a * e^{(-b * x)} + c$, y a veces el ajuste se acerca más a $a * e^{(-b * x^2)} + c$. Sin embargo, a veces ambos fallan, y me gustaría recurrir a un ajuste lineal. Mi pregunta es, ¿cómo puedo determinar qué modelo se ajusta mejor a un conjunto de datos en particular a partir de la matriz de varianza-covarianza resultante que se devuelve de la función scipy.optimize.curve_fit()? Creo que la varianza está en una de las diagonales de esta matriz, pero no estoy seguro de cómo interpretar eso.
ACTUALIZACIÓN: Basándome en una pregunta similar, espero que la matriz de varianza-covarianza pueda decirme cuál de los tres modelos que estoy intentando se ajusta mejor a los datos (estoy intentando ajustar muchos conjuntos de datos a uno de estos tres modelos).
Las matrices resultantes se ven así para el ejemplo dado:
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]]
Aquí hay un ejemplo de lo que estoy haciendo:
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="Datos originales")
plt.plot(x, linear_func(x, *popt_lin), 'r-', label='lineal')
plt.plot(x, exp_func(x, *popt_exp), 'b-', label='exponencial')
plt.plot(x, exp_squared_func(x, *popt_exp_2), 'g-', label='exponencial cuadrada')
plt.legend()
plt.show()
if __name__ == '__main__':
main()
0 votos
Es excelente que enlaces a esa pregunta de CV y, en consecuencia, al importante hilo de comentarios (entre Rolando2, Frank Harrell, ...) cuestionando si es apropiado seleccionar el modelo post facto basado en su ajuste. Tal vez sea mejor utilizar el conocimiento previo del sistema para seleccionar el modelo.
0 votos
Esta otra pregunta en CV puede ser útil: stats.stackexchange.com/questions/50830/…
0 votos
¿Podría ser útil para entender cómo interpretar la matriz de covarianza stats.stackexchange.com/questions/10795/… - Yo diría que el valor de los terceros modelos es más pequeño, lo que indica menos desviación.