Python非线性拟合自定义函数参数(对标MATLAB-nlinfit函数)


一、前言

本文使用到了 Python 中的 scipy 包和 pycse 包,可使用如下命令下载:

pip install -i https://mirrors.aliyun.com/pypi/simple scipy pycse

我的 Python 版本为 Python3.9.7,系统为 Ubuntu21.10


二、curve_fit 函数

使用方法:

from scipy.optimize import curve_fit
popt, pcov = curve_fit(func, xdata, ydata, bounds = (0, (1., 1.)))

其中 xdataydata 为等长的数组,bounds 为参数限制范围。例如拟合曲线 a e − b ∗ x + c ae^{-b * x} + c aebx+c 中的参数 a, b, c

def func(x, a, b, c):
	return a * np.exp(-b * x) + c

拟合数据如下:

xdata = np.linspace(0, 4, 50)
y = func(xdata, 2.5, 1.3, 0.5)
rng = np.random.default_rng()
y_noise = 0.2 * rng.normal(size=xdata.size)
ydata = y + y_noise
popt, pcov = curve_fit(func, xdata, ydata)

拟合效果如下:

In [25]: popt
Out[25]: array([2.56274217, 1.37268521, 0.47427475])

其中 popt 列表里储存的便分别是 a, b, c 参数的值。


三、nlinfit 函数

这是 pycse 包中提供的函数,对标 MATLAB 中的 nlinfit 函数,但是其底层还是基于 scipy 中的 curve_fit 函数:

from pycse import nlinfit
pars, pint, se = nlinfit(func, xdata, ydata, coeffs, alpha = 0.05)

这里的 coeffs 值为我们给定的 func 函数的初始参数值,需要我们自己给出解释,alpha 值为置信水平(默认 95%)。

coeffs = np.array([2., 1., 0])
pars, pint, se = nlinfit(func, xdata, ydata, coeffs, alpha = 0.05)

输出如下:

In [28]: pars
Out[28]: array([2.49689418, 1.38830888, 0.57077955])

四、对比

虽然两个函数都可以解非线性拟合,但是效果却不同,例如我最近在拟合如下函数参数时:

n ( x ) = 1 + B 1 x x − C 1 + B 2 x x − C 2 + B 3 x x − C 3 n(x) = 1 + \dfrac{B_1x}{x- C_1}+ \dfrac{B_2x}{x - C_2}+ \dfrac{B_3x}{x- C_3} n(x)=1+xC1B1x+xC2B2x+xC3B3x

若我使用 curve_fit 函数拟合,效果是非常差的,不是拟合不出来就是结果误差到根本没法使用,而若使用 nlinfit 函数,在给定初始参数为 [0.1, 0.1, 0.1, 0.1, 0.1, 0.1] 后,拟合效果还是非常好的。


五、总结

注:pycse 中的 nlinfit 函数和 MATLAB 的还是有很大区别的,例如初始参数不能与精确值差太多,不然便求解不出来。

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z.Q.Feng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值