Я не слишком хорош в статистике, поэтому извиняюсь, если это упрощенный вопрос. Я подгоняю кривую к некоторым данным, и иногда мои данные лучше всего соответствуют отрицательной экспоненте в виде , а иногда подгонка ближе к a ∗ e ( - b ∗ x 2 ) + с . Однако иногда оба из них терпят неудачу, и я хотел бы вернуться к линейной подгонке. Мой вопрос заключается в том, как определить, какая модель лучше всего подходит для конкретного набора данных, из полученной матрицы дисперсии-ковариации, которая возвращается изфункция scipy.optimize.curve_fit () ? Я полагаю, что дисперсия находится на одной из диагоналей этой матрицы, но я не уверен, как это интерпретировать.
ОБНОВЛЕНИЕ: Основываясь на аналогичном вопросе , я надеюсь, что матрица дисперсии-ковариации может сказать мне, какая из трех моделей, которые я пытаюсь использовать, наилучшим образом соответствует данным (я пытаюсь подогнать множество наборов данных к одной из этих трех моделей).
Полученные матрицы выглядят так для данного примера:
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]]
Вот пример того, что я делаю:
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()
источник
Ответы:
В качестве пояснения, переменная
pcov
fromscipy.optimize.curve_fit
- это оценочная ковариация оценки параметра, то есть, говоря свободно, учитывая данные и модель, сколько информации содержится в данных для определения значения параметра в данной модели. Таким образом, он на самом деле не говорит вам, хорошая модель или нет. Смотрите также это .Проблема в том, что хорошая модель действительно сложная. Как утверждают статистики
Таким образом, критерии для использования при сравнении разных моделей зависят от того, чего вы хотите достичь.
Например, если вам нужна кривая, максимально приближенная к данным, вы можете выбрать модель, которая дает наименьший остаток . В вашем случае это будет модель
func
и оценочные параметры,popt
которые имеют наименьшее значение при вычисленииОднако, если вы выберете модель с большим количеством параметров, остаток будет автоматически уменьшаться за счет более высокой сложности модели. Итак, все возвращается к цели модели.
источник