Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么稍微改变函数会导致scipy中的指数曲线拟合出现如此大的差异?_Python_Scipy_Curve Fitting - Fatal编程技术网

Python 为什么稍微改变函数会导致scipy中的指数曲线拟合出现如此大的差异?

Python 为什么稍微改变函数会导致scipy中的指数曲线拟合出现如此大的差异?,python,scipy,curve-fitting,Python,Scipy,Curve Fitting,使用scipy中的曲线拟合函数,我得到了一些非常好的结果。我的功能稍有改变就会更好。但我不知道为什么。 这就是代码不起作用的原因: def func(x, A1, t1, y0): return A1 * np.exp(x/t1) + y0 x_data = np.array(data['tau']) y_data = np.array(data['magnitude']) p0 = [1000, 4, 0] popt, pcov = curve_fit(func, x_data

使用scipy中的曲线拟合函数,我得到了一些非常好的结果。我的功能稍有改变就会更好。但我不知道为什么。 这就是代码不起作用的原因:

def func(x, A1, t1, y0):
    return A1 * np.exp(x/t1) + y0

x_data = np.array(data['tau']) 
y_data = np.array(data['magnitude'])

p0 = [1000, 4, 0] 
popt, pcov = curve_fit(func, x_data, y_data, p0)
print(popt)

y_fited = func(x_data, *popt)

plt.plot(x_data, y_data, 'b-', label='data') 
plt.plot(x_data, y_fited, 'r-', label='fited')
输出图如下所示:

在我将func的t1从除法改为乘法后,一切似乎都变好了

def func(x, A1, t1, y0):
    return A1 * np.exp(x*t1) + y0

为什么会这样?我不明白为什么我的第一个func不能很好地工作,它不是一个线性函数,我从Origin的指数拟合工具借用它。提前谢谢

这是我的x_数据:

[4.9063e-03 4.5800e-03 4.2538e-03 3.9275e-03 3.6012e-03 3.2750e-03 2.9487e-03 2.6224e-03 2.2961e-03 1.9699e-03 1.6436e-03 1.3173e-03 9.9107e-04 6.6480e-04 3.3853e-04 1.2266e-05]

和y_数据:

[1038.3 921.93 865.19 878.07 1141.9 1043.3 1167.2 1030.5 1174.8 1331.5 1549.7 1379.8 2134.8 1992.5 2218.8 2505.7]


这里有几个问题。显然,这是一种非线性拟合,因此始终存在局部极小值的可能性。显然这里有一个。那么问题是:为什么?我们必须看看底层算法在做什么。只要看看
t1
我们就会发现,如果我们从
t1=1开始,两个版本都会给出相同的答案。现在数据清楚地表明这是衰减,所以结果应该是负的。因此,
…*t1
的情况需要变小并变为负值。这是由局部误差的梯度控制的。现在很可能
../t1
情况也希望朝更小的因子方向发展,但这意味着增加
t1
,因此它将朝错误的方向发展。如果在整个装配过程中打印
t1
的值,则可以观察到此行为。实际上,在某一点上,它克服了负数的“障碍”。然而,在这一点上,其他参数已经有这样的异常值,它返回到正

具体地说,这取决于启动参数,
[5000,1,0]
将起作用

最后,我认为这个例子是关于如何准备fit功能的一个很好的教训:

  • 尽量使符号正确,即
    exp(-x*t1)
    会更好,因为它显然是衰减的
  • 如果某个参数可能会改变符号,请注意,如果该参数变为零,则不会出现任何偏差。这就是这里发生的事情
  • 如果可能,请重新缩放,以便缩放
    1
    上的所有参数。这在某种程度上相当于提供良好的起始值。在这里,像
    1000*a*exp(-1000*t*x)+1000*c
    这样的拟合函数将在不提供起始值的情况下快速收敛

    • 这里有几个问题。显然,这是一种非线性拟合,因此始终存在局部极小值的可能性。显然这里有一个。那么问题是:为什么?我们必须看看底层算法在做什么。只要看看
      t1
      我们就会发现,如果我们从
      t1=1开始,两个版本都会给出相同的答案。现在数据清楚地表明这是衰减,所以结果应该是负的。因此,
      …*t1
      的情况需要变小并变为负值。这是由局部误差的梯度控制的。现在很可能
      ../t1
      情况也希望朝更小的因子方向发展,但这意味着增加
      t1
      ,因此它将朝错误的方向发展。如果在整个装配过程中打印
      t1
      的值,则可以观察到此行为。实际上,在某一点上,它克服了负数的“障碍”。然而,在这一点上,其他参数已经有这样的异常值,它返回到正

      具体地说,这取决于启动参数,
      [5000,1,0]
      将起作用

      最后,我认为这个例子是关于如何准备fit功能的一个很好的教训:

      • 尽量使符号正确,即
        exp(-x*t1)
        会更好,因为它显然是衰减的
      • 如果某个参数可能会改变符号,请注意,如果该参数变为零,则不会出现任何偏差。这就是这里发生的事情
      • 如果可能,请重新缩放,以便缩放
        1
        上的所有参数。这在某种程度上相当于提供良好的起始值。在这里,像
        1000*a*exp(-1000*t*x)+1000*c
        这样的拟合函数将在不提供起始值的情况下快速收敛

      您使用的拟合方法是一种迭代方法,从参数的“猜测”初始值开始。问题可能来自参数的初始值。如果它们离正确的值太远,迭代过程的收敛可能会失败,或者太慢或不稳定

      如果使用不需要“猜测”初始值的非迭代方法,则可以避免这种情况。本文对这种方法进行了解释

      非常简单的演算如下所示:

      注:


      您可以使用上述参数的近似值作为软件中的初始值,并检查它们是否正确计算参数的优化值。

      您使用的拟合方法是一种迭代方法,从参数的“猜测”初始值开始。问题可能来自参数的初始值。如果它们离正确的值太远,迭代过程的收敛可能会失败,或者太慢或不稳定

      如果使用不需要“猜测”初始值的非迭代方法,则可以避免这种情况。本文对这种方法进行了解释

      非常简单的演算如下所示:

      注:

      您可以使用上述参数的近似值,如下所示: