Python 为什么我不能使用scipy.optimize.curve\u fit将sigmoid函数拟合到此数据?

Python 为什么我不能使用scipy.optimize.curve\u fit将sigmoid函数拟合到此数据?,python,numpy,scipy,Python,Numpy,Scipy,使用下面的代码,我无法将sigmoid函数适配到我的数据集。 但是,如果我在下面的代码中添加一个偏移量t=x+50-x0,它会非常适合 x0是否应注意配件 你遇到了一个初始条件敏感的典型案例。curve\u fit函数接受关键字参数p0,它允许您为函数的自由参数选择初始“猜测”(在您的情况下,x0,k,和y0) 当未提供任何p0时,scipy假设所有参数均为。对于函数,这意味着sigmoid的分母将非常接近于零,因此函数值将放大。这会混淆解算器并导致较差的解 不幸的是,这个问题没有单一的解决方

使用下面的代码,我无法将sigmoid函数适配到我的数据集。 但是,如果我在下面的代码中添加一个偏移量
t=x+50-x0
,它会非常适合

x0
是否应注意配件



你遇到了一个初始条件敏感的典型案例。
curve\u fit
函数接受关键字参数
p0
,它允许您为函数的自由参数选择初始“猜测”(在您的情况下,
x0
k
,和
y0

当未提供任何
p0
时,scipy假设所有参数均为。对于函数,这意味着sigmoid的分母将非常接近于零,因此函数值将放大。这会混淆解算器并导致较差的解


不幸的是,这个问题没有单一的解决方案,因为它需要了解您试图拟合的函数的动力学。在您的情况下,提供
p0
(-30,1,0)
将允许解算器收敛到一个合适的解决方案。

您遇到了初始条件敏感的典型情况。
curve\u fit
函数接受关键字参数
p0
,它允许您为函数的自由参数选择初始“猜测”(在您的情况下,
x0
k
,和
y0

当未提供任何
p0
时,scipy假设所有参数均为。对于函数,这意味着sigmoid的分母将非常接近于零,因此函数值将放大。这会混淆解算器并导致较差的解


不幸的是,这个问题没有单一的解决方案,因为它需要了解您试图拟合的函数的动力学。在您的情况下,提供
p0
(-30,1,0)
将允许解算器收敛到一个合适的解决方案。

这是因为问题涉及大量数字,使得曲线拟合算法快速发散

curve\u fit
的(默认)初始猜测是所有猜测的数组:

p0:无、标量或M长度序列 参数的初始猜测。如果没有,则初始值为 值将全部为1(如果函数的参数数 可以使用内省来确定,否则将导致ValueError )

对于您的问题,这意味着
[1,1,1]
。使用第一个x0值,
-110
,这将导致指数的参数为:
-1*(-110-1)
,结果是
np.exp(111)
,这是一个巨大的数字,远远大于它所加的常数1。即使对于
x0
的初始猜测的微小变化,结果将是与
y0
相加的分数几乎为零。这就是为什么对于您的问题,
popt
将返回
[1,1,51]
:算法没有发现
x0
中的微小变化对结果有任何显著影响(
y


解决办法确实是提供一个合理的猜测。算法用于参数的变化也取决于这些参数的大小。提供
[-45,1,1]
也将产生一个好的解决方案,对于
x0
,初始猜测
-90
:只需确保水平偏移量至少“接近”独立变量的值(在您的情况下,
listA
的值)。

这是因为问题涉及大量数字,使曲线拟合算法快速发散

curve\u fit
的(默认)初始猜测是所有猜测的数组:

p0:无、标量或M长度序列 参数的初始猜测。如果没有,则初始值为 值将全部为1(如果函数的参数数 可以使用内省来确定,否则将导致ValueError )

对于您的问题,这意味着
[1,1,1]
。使用第一个x0值,
-110
,这将导致指数的参数为:
-1*(-110-1)
,结果是
np.exp(111)
,这是一个巨大的数字,远远大于它所加的常数1。即使对于
x0
的初始猜测的微小变化,结果将是与
y0
相加的分数几乎为零。这就是为什么对于您的问题,
popt
将返回
[1,1,51]
:算法没有发现
x0
中的微小变化对结果有任何显著影响(
y


解决办法确实是提供一个合理的猜测。算法用于参数的变化也取决于这些参数的大小。提供
[-45,1,1]
也将产生一个好的解决方案,对于
x0
,初始猜测
-90
:只需确保水平偏移至少“接近”独立变量的值(在您的情况下,
listA
的值)。

感谢perimosocordiae。。。。。。这是有道理的。。是否有一个R平方或回归scoe输出,我可以从中获得曲线拟合,这将帮助我猜测这样的问题。
p0
的假设是不正确的,这将导致错误的分析。但是,您的陈述“初始条件敏感性的经典案例”以及最后一段都是正确的。@Vivekbeck是的,请始终检查
pcov
的值。如果是
inf
,则出现问题。谢谢perimosocordiae。。。。。。这是有道理的。。是否有一个R平方或回归scoe输出,我可以从中得到曲线拟合,这将帮助我猜测这样的问题…假设
import numpy as np
import pylab
from scipy.optimize import curve_fit

listA = np.array([-110,-105,-100,-95,-90,-85,-80,-75,-70,-65,-60,-55,-50,-45])
listB = np.array([1,1,1,1,0.926470588,0.852941176,0.616803279,0.371212121,
                  0.191066998,0.088565022,0.06684492,0.019855596,0.015517241,0])

def sigmoid(x,x0,k,y0):
    t = x -x0                 
    y = y0-1/(1 + np.exp(-k*t))
    return y

popt, pcov = curve_fit(sigmoid, listA, listB)
print popt ,pcov    

x = np.linspace(-110,-45,50)

y = sigmoid(x, *popt)

pylab.plot(listA, listB, 'o', label='data')
pylab.plot(x,y, label='fit')
pylab.ylim(-0.05, 1.05)
pylab.legend(loc='best')
pylab.show()