我试图使用scipy的curve_fit
将一个具有两个自变量a
和k
的函数拟合成指数曲线。我已经定义了函数,并试图像这样计算它:
print(np.min(x_data))
1
print(np.max(x_data))
44098
print(x_data.dtype)
int64
print(np.size(x_data))
44098
print(np.min(y_data))
-0.44383433
print(np.max(y_data))
1.0
print(y_data.dtype)
float32
print(np.size(y_data))
44098
def exponential(x, a, k, b):
return a*np.exp(x*k) + b
popt, pcov = scipy.optimize.curve_fit(exponential, x_data, y_data, p0=[1, -0.5, 1])
print(popt)
[ 1.28765636e+00 -3.27620187e-04 -8.91012481e-02]
/software/repo/python/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:6: RuntimeWarning: overflow encountered in exp
/software/repo/python/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:6: RuntimeWarning: overflow encountered in multiply
这会导致一个警告,因为我的数据太大了。将数据类型一直更改到complex256
仍然不够大。所以我试着更新边界;设定足够大的边界可以克服误差,但我不知道我这样做是否正确,因为拟合变量变得依赖于我选择的边界。
popt, pcov = scipy.optimize.curve_fit(exponential, x_data, y_data, bounds=([1, -1e100, 1], [1e100, 1, 1e100]))
print(popt)
[ 5.e+99 -5.e+99 5.e+99]
popt, pcov = scipy.optimize.curve_fit(exponential, x_data, y_data, bounds=([1, -1e1000, 1], [1e1000, 1, 1e1000]))
print(popt)
[ 1.00448191 -5.15058477 1. ]
这是怎么回事?我需要做什么才能正确地适应此功能?我还修补了Decimal
模块,但没有成功。谢谢大家!
1条答案
按热度按时间kkbh8khc1#
具有float 64值(这是numpy的默认值)的
exp(a)
从值~1溢出。e308至numpy.Inf
,a
〉709。75左右。对于您的情况,这意味着您的
k
值必须满足x*k <=709
。由于x
的值会增加到44098
的值,因此k
允许的最大值应该大约为0。016.如果期望k
总是负值,则可以给予最大值0。FWIW,
exp
将在a
的值低于-709时下溢。75.在这种情况下,结果变为0,这不会导致异常,但可能使拟合困难。您可以将问题转换为使用
float128
,这将提高溢出的阈值,但我相信这对大多数曲线拟合例程都不起作用-它们使用float 64值,并且在您的情况下是否真的需要这一点值得怀疑。