天天看点

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

最近,使用curve_fit时遇到一个问题,百思不得其解,看了官网,上网查都没有找到这种问题所在,最后通过一些实验确定:应该是由于我这个问题中的数值存在较小值,如果在function中使用了除法会导致数值计算的问题,所以不正确。 接下来具体描述下我遇到的问题,和得出我这种猜测的支撑依据。

1.问题描述

在做交通流三参数模型拟合时,我使用了scipy的curve_fit函数。数据大概是这个样子的:

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

然后我使用下面的代码:

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

拟合出的曲线是这样的:

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

但是如果我将代码改成这样:

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

拟合结果就变成了:

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

我用spss做了验证,拟合出来的结果是完全一致的。所以说可以确定问题就是出在我定义的function里面,一个是定义成 v s = v f ∗ ( 1 − k / k j ) v_s=v_f*(1-k/k_j) vs​=vf​∗(1−k/kj​),另一个是定义成 v s = a ∗ k + b v_s=a*k+b vs​=a∗k+b,我们可以知道这两个式子是完全等效的,但是拟合结果是天差地别,让人费解,接下来我就来简单探究下问题。

2.简单实验

2.1排除公式因素

首先,我猜测会不会是因为除法所带来的呢,因为两个式子中唯一的区别就是一个式子带有除法另一个没有除法。我做了如下的实验,代码为:

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议
python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

可以发现确实不是除法所带来的,这边用了和上述失败的公式一模一样的公式,可是却拟合成功了。

2.2数值计算问题

于是进一步猜测应该是由于数值计算的原因所带来的。在我这个例子中k都是很小的数值,基本在0.01左右,甚至更小,而vs一般大于20。因此猜测引入除法会带来数值计算上的bug。于是用下述代码进行实验。

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议
python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

果然拟合失败了。

然后做一个对照实验,来确认问题原因。

python curve_fit拟合失败1.问题描述2.简单实验3.总结建议
python curve_fit拟合失败1.问题描述2.简单实验3.总结建议

只需稍微将k(自变量)的值变大一些就可以拟合成功了,所以应该就是由于数值计算问题所带来的。

3.总结建议

所以说,总的来说curve_fit中的函数定义应该是没有限制的,但是建议是使用乘法,少用除法,因为除法更容易出现问题,如舍入误差、数值计算等,除法都有可能在有极小值时出现bug。若出现拟合问题,可以考虑下是不是由于数据里存在很小或很大的值所带来的。