边界的微小变化会改变 scipy.optimize.curve_fit 的曲线拟合

问题描述 投票:0回答:1

我需要将曲线拟合到数据,并且首先在我自己创建的图上测试

scipy.optimize.curve_fit
。令人担忧的是,仅仅稍微改变边界就会影响曲线参数的估计,这并不能激发人们对实际数据正确估计的信心。为什么会发生这种情况?我可以使用 curve_fit 的替代方案吗?

我正在测试它的函数(最终需要适应数据)是

y = a*(x/b)**9
。我在下面的代码中绘制了
a = 0.03
b = 0.007
,然后使用 curve_fit 来估计 a 和 b。如果我设定了界限
0 < a < 0.1
,它就会高估
a
0.0429
。如果我设定界限
0 < a < 0.04
,它就会低估
a
0.0222
。我的实际数据有很多幂 (
d
),所以我不仅会估计
d = 9
,还会估计一系列
d
。如果它们都被低估或高估,最终将会产生很大的影响。有什么办法可以解决这个问题吗?

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

d = 9

def func(x,a,b):
    return a*(x/b)**d

x = np.logspace(-3.2,-2,20)

a = 0.03
b = 0.007
print(f"a = {a}, b = {b}")

y = func(x,a,b) 
plt.loglog(x,y)
plt.savefig("test.png")
plt.show()

popt, pcov = curve_fit(func,x,y, bounds = ([0,0.005],[0.04,0.009]))
print(f'a ≈ {popt[0]}, b ≈ {popt[1]}')

python scipy curve-fitting scipy-optimize
1个回答
0
投票

这个方程有无数个解,因为 a 和 b 参数做同样的事情。

您可以通过对方程两边取对数并简化来看到这一点:

log(y) = d*x - d*log(b) + log(a)

例如,如果有解a、b,则可以将a除以1000,将b除以1000的9次方根,这就是等价解。

a2 = a / 1000
b2 = b / (1000 ** (1/d))
y = func(x,a,b)
plt.plot(x, y)
y = func(x,a2,b2)
plt.plot(x, y)
print(f'a ≈ {a2}, b ≈ {b2}')

如果您的方程有多个等效拟合,则 curve_fit 可能会选择其中任何一个。

© www.soinside.com 2019 - 2024. All rights reserved.