Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.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 - Fatal编程技术网

Python 为什么Scipy如此不适合这条曲线?

Python 为什么Scipy如此不适合这条曲线?,python,scipy,Python,Scipy,我正在尝试使此函数适合某些数据 这是我的职责: def first_deriv(xlist, L, k, x0): return [k*L*(math.e**(-k*(x+x0)))/(1+math.e**(-k*(x+x0)))**2 for x in xlist] 这就是函数的外观,所以我希望得到一个非常好的拟合。 这是使函数适合数据的代码 popt = curve_fit(first_deriv, list(range(len(data))), data, bounds=((0

我正在尝试使此函数适合某些数据

这是我的职责:

def first_deriv(xlist, L, k, x0):
    return [k*L*(math.e**(-k*(x+x0)))/(1+math.e**(-k*(x+x0)))**2 for x in xlist]
这就是函数的外观,所以我希望得到一个非常好的拟合。

这是使函数适合数据的代码

popt = curve_fit(first_deriv, list(range(len(data))), data, bounds=((0, -np.inf, -np.inf), (10**(9), +np.inf, 0)), maxfev=10000)
我就是这样画的:

xdata = list(np.linspace(-100, 100, 2000))    
plt.scatter(xdata, first_deriv(xdata, popt[0][0], popt[0][1], popt[0][2]), s=1)
边界的存在使得答案合理,但即使我将所有边界设为无限,它仍然给出了一个可怕的拟合

这太不合身了

我很惊讶曲线拟合似乎完全搞砸了。
有人能解释一下原因吗?

优化过程可能会陷入局部极大值(当参数的任何更改首先会使拟合变得更差,然后再变得更好)。为了避免此问题(并加快计算),允许您使用
p0
关键字参数指定参数的最佳猜测


因此,您应该将用于上述函数绘图的参数值作为起点传递到
曲线拟合()

您的示例存在两个问题

一个小问题

curve\u fit
需要的是,而上面的代码给出的是
列表(范围(len(data))
,它将产生从0到
数据
长度的整x值。您会注意到散点图点只会上升到~50。我猜这就是原因

相反,您应该给出观察到
数据
点的自变量值列表。根据
数据
的生成/收集方式(您的问题中没有提供此信息),这可能是
扩展数据

对于第二个图如何与第一个图相匹配,我也有点困惑。y刻度似乎与蓝线不匹配。我猜这些图是根据不同参数值的不同示例生成的。我将忽略它们

真正的问题

并非所有优化方法都同样适用于所有问题。
曲线拟合
能够使用三种方法,
'lm
'trf'
'dogbox'
。默认值为
lm
,除非给出了边界,否则在这种情况下,将使用
'trf'
,这是一种方法

稍微玩弄一下这个例子,我发现
'lm'
表现得很好,而
'trf'
则没有

例如,以以下代码为例:

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

def first_deriv(xlist, L, k, x0):
    return [k*L*(math.e**(-k*(x+x0)))/(1+math.e**(-k*(x+x0)))**2 for x in xlist]

xdata = list(np.linspace(-100, 100, 2000))
real_parameters = (320000.0, 0.1, -30.0)

fakedata = first_deriv(xdata, *real_parameters)
plt.plot(xdata, fakedata)
这将生成上面示例中的曲线(ish):

通过对这三种方法的比较,可以确认
'lm'
看起来是最好的,并恢复了原始参数:

lm_parameters = curve_fit(first_deriv, xdata, fakedata)[0]
trf_parameters = curve_fit(first_deriv, xdata, fakedata, method='trf')[0]
dogbox_parameters = curve_fit(first_deriv, xdata, fakedata, method='dogbox')[0]

plt.scatter(xdata, first_deriv(xdata, *lm_parameters), s=1, label='lm')
plt.scatter(xdata, first_deriv(xdata, *trf_parameters), s=1, label='trf')
plt.scatter(xdata, first_deriv(xdata, *dogbox_parameters), s=1, label='dogbox')
plt.legend()

一个有趣的问题(可能值得发表自己的帖子)是为什么会这样。虽然我没有资格进行精确的数学论证,但玩弄函数的参数却暗示了一些粗略的想法

例如,函数的“加宽峰值”似乎允许所有方法都能很好地执行。

毫无疑问,改变参数改变了“适应度景观”,使信赖域方法得以成功

'trf'
'dogbox'
方法本身的某些参数也可能产生更好的结果。这需要对这些方法有更深入的了解


话虽如此,
'lm'
似乎是解决此特定问题的最佳方法。了解您使用的方法,并针对每个新问题尝试不同的方法,这一点始终很重要,特别是如果您得到的结果不好。

什么是
数据
变量?它是如何生成的?我无法运行您的cod如上所述,也许你可以提供一个MWE-你正在传递一组不同的x值到拟合与绘图…初始猜测在这里非常重要。对于高斯分布,我推荐Jean-Jacquelin的方法。是的,肯定比我在这里写的要多得多。在这种情况下,lm似乎可以很好地处理默认的初始猜测,虽然在其他情况下使用不同的初始猜测会有好处,但我敢肯定。它应该有自己的帖子,我想非常感谢!