其他分享
首页 > 其他分享> > 曲线拟合拟合高度相关的数据的问题

曲线拟合拟合高度相关的数据的问题

作者:互联网

对于我的学士学位论文,我正在一个项目中进行数据拟合.问题有点复杂,但是我尝试在此处将问题最小化:

我们有三个数据点(几乎没有理论数据可用),但是这些点是高度相关的.

如上图所示,使用curve_fit拟合这些点,我们得到了可怕的拟合结果. (可以通过手动更改拟合参数来轻松提高拟合度).

我们的拟合结果具有相关性(蓝色)和被忽略的相关性(橙色):

enter image description here

当我们使用更多参数时,结果会变得更好(因为拟合的行为本质上就像那时的解算).

我的问题:为什么会发生这种现象? (对于特定的问题,我们使用自己的最小二乘算法,但是它也遇到相同的问题).这是一个数字问题,还是curve_fit有充分的理由显示此解决方案?

我很高兴有一个很好的解释,说为什么我们不能使用“仅2个”参数来适应这些高度相关的3个数据点.

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
plt.rcParams['lines.linewidth'] = 1

y = np.array([1.1994, 1.0941, 1.0047])
w = np.array([1, 1.08, 1.16])
cor = np.array([[1, 0.9674, 0.8812],[0.9674, 1, 0.9523], [0.8812, 0.9523, 1]])
s = np.array([0.0095, 0.0104, 0.0072])

def f(x, a, b):
    return a + b*x

cov = np.zeros((3,3))
for i in range(3):
    for j in range(3):
        cov[i,j] = cor[i,j] * s[i] * s[j]

A1, B1 = curve_fit(f, w, y, sigma=cov)
A2, B2 = curve_fit(f, w, y)

plt.plot(w, f(w, *A1))
plt.plot(w, f(w, *A2))

plt.scatter(w, y)
plt.show()

解决方法:

这不是一个数字问题. “问题”是协方差矩阵的非对角项均为正且相对较大.这些决定了拟合误差之间的相关性,因此,如果所有项均为正,则表示所有误差均呈正相关.如果其中一个较大,则其他相同的符号也往往也较大.

这是一个与您相似的示例,带有协方差矩阵

        [2.0  1.3  0.0]
sigma = [1.3  2.0  1.3]
        [0.0  1.3  2.0]

(此矩阵的条件数为23.76,因此我们不应期望任何数值问题.)

尽管第一点和第三点之间的协方差为0,但第一点和第二点之间的协方差是1.3,第二点和第三点之间的协方差是1.3,而1.3是方差的一个相对较大的比例,都为2.因此,不足为奇如果拟合模型中的所有错误都具有相同的符号.

该脚本对三个点进行拟合,并绘制数据和拟合线.

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt


def f(x, a, b):
    return a + b*x


x = np.array([1, 2, 3])
y = np.array([2, 0.75, 0])
sig = np.array([[2.0, 1.3, 0.0],
                [1.3, 2.0, 1.3],
                [0.0, 1.3, 2.0]])

params, pcov = curve_fit(f, x, y, sigma=sig)

y_errors = f(x, *params) - y

plt.plot(x, y, 'ko', label="data")
plt.plot(x, f(x, *params), linewidth=2.5, label="fitted curve")
plt.vlines(x, y, f(x, *params), 'r')

for k in range(3):
    plt.annotate(s=r"$e_{%d}$" % (k+1), xy=(x[k]-0.05, y[k]+0.5*y_errors[k]), ha='right')

plt.xlabel('x')
plt.ylabel('y')
plt.axis('equal')
plt.grid()
plt.legend(framealpha=1, shadow=True)
plt.show()

plot

如您在图中所见,所有错误都有相同的符号.

我们可以通过考虑另一个协方差矩阵来确认这种推理,

        [ 2.0   1.3  -1.0]
sigma = [ 1.3   2.0  -1.3]
        [-1.0  -1.3   2.0]

在这种情况下,所有非对角项的大小都相对较大.第一个和第二个误差之间的协方差为正,第二个和第三个之间以及第一个和第三个之间的协方差为负.如果这些非对角线项相对于方差足够大,那么我们应该期望前两个点的误差的符号相同,而第三个误差的符号与前两个的符号相反.

这是将sig更改为上述矩阵时脚本生成的图:

plot

错误显示预期的模式.

标签:scipy,data-science,curve-fitting,physics,python
来源: https://codeday.me/bug/20191111/2018342.html