如何从曲线拟合中解释协方差矩阵?

机器算法验证 方差 模型选择 Python 曲线拟合 协方差矩阵
2022-02-12 04:05:27

我不太擅长统计,所以如果这是一个简单的问题,我深表歉意。我正在为一些数据拟合曲线,有时我的数据最适合表格中的负指数ae(bx)+c, 有时拟合更接近ae(bx2)+c. 然而,有时这两种方法都失败了,我想回到线性拟合。我的问题是,如何从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()
1个回答

澄清一下,变量pcovfromscipy.optimize.curve_fit是参数估计的估计协方差,松散地说,给定数据模型,数据中有多少信息可以确定给定模型中参数的值。所以它并不能真正告诉你选择的模型是否好。另请参阅

什么是好模型这个问题确实是一个难题。正如统计学家所说

所有模型都是错误的,但有些是有用的

因此,用于比较不同模型的标准取决于您想要实现的目标。

例如,如果您想要一条与数据“尽可能接近”的曲线,您可以选择一个给出最小残差的模型。在您的情况下,模型func和估计参数popt在计算时具有最低值

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

但是,如果选择参数较多的模型,残差会自动减小,代价是模型复杂度较高。然后回到模型的目标。