Python 拟合阶跃函数

Python 拟合阶跃函数,python,scipy,curve-fitting,best-fit-curve,Python,Scipy,Curve Fitting,Best Fit Curve,我正在尝试使用scipy.optimize.leastsq拟合步长函数。考虑下面的例子: import numpy as np from scipy.optimize import leastsq def fitfunc(p, x): y = np.zeros(x.shape) y[x < p[0]] = p[1] y[p[0] < x] = p[2] return y errfunc = lambda p, x, y: fitfunc(p, x)

我正在尝试使用scipy.optimize.leastsq拟合步长函数。考虑下面的例子:

import numpy as np
from scipy.optimize import leastsq

def fitfunc(p, x):
    y = np.zeros(x.shape)
    y[x < p[0]] = p[1]
    y[p[0] < x] = p[2]
    return y

errfunc = lambda p, x, y: fitfunc(p, x) - y # Distance to the target function

x = np.arange(1000)
y = np.random.random(1000)

y[x < 250.] -= 10

p0 = [500.,0.,0.]
p1, success = leastsq(errfunc, p0, args=(x, y))

print p1
当第一个参数设置为250,第二个参数设置为-10时,将是最佳的

有人知道为什么这可能不起作用,以及如何让它起作用吗

如果我跑

print np.sum(errfunc(p1, x, y)**2.)
print np.sum(errfunc([250.,-10.,0.], x, y)**2.)
我发现:

12547.1054663
320.679545235

其中,第一个数字是leastsq正在查找的值,第二个是它应该查找的实际最优函数的值。

最有可能的是,您的优化陷入了局部极小值。我不知道leastsq的工作原理是什么,但是如果你给它一个(0,0,0)的初始估计值,它也会被卡住


你可以在初始估计值处用数字检查梯度(在+/-epsilon处计算一个非常小的epsilon,然后除以bei 2*epsilon,取差),我打赌它将是0左右的某个值。

事实证明,如果我将epsfcn=参数添加到leastsq中,拟合会更好:

p1, success = leastsq(errfunc, p0, args=(x, y), epsfcn=10.)
结果是

[ 248.00000146   -8.8273455     0.40818216]

我的基本理解是,第一个自由参数的移动必须大于相邻点之间的间距,才能影响残差的平方,而epsfcn与找到梯度所用的步长有关,或者类似的东西。

我不认为最小二乘拟合是获得一个近似值的方法。我不相信它会给你一个不连续的令人满意的描述。在解决这个问题时,最小二乘法并不是我的第一个想法

为什么不使用傅里叶级数近似呢?在不连续处,你总是会被吉布斯现象所困扰,但是函数的其余部分可以被近似,就像你和你的CPU所能承受的那样


你到底要用这个干什么?一些上下文可能会有所帮助。

我建议近似阶跃函数。而不是 在“变化点”处的有限坡度使其在上方呈线性 一个x距离(示例中为1.0)。例如,如果x 函数的参数xp被定义为中点 在这一行中,xp-0.5处的值是较低的y值 xp+0.5处的值是较高的y值和 中函数的中间值 区间[xp-0.5;xp+0.5]是线性的 这两点之间的插值

如果可以假设阶跃函数(或其 近似值)从较低的值变为较高的值 然后我想最后两个参数的初始猜测 应为最低y值和最高y值 分别代替0.0和0.0


我有两处更正:

1) random.random()返回范围内的随机数 0.0到1.0。因此,平均值为+0.5,也是 第三个参数(而不是0.0)。第二个参数呢 然后是-9.5(+0.5-10.0),而不是-10.0

因此

应该是

print np.sum(errfunc([250.,-9.5,0.5], x, y)**2.)
2) 在原始fitfunc()中,如果x为,则y的一个值变为0.0 正好等于p[0]。因此,它不是一个阶跃函数 这种情况(更像是两步函数之和)。例如,这个
当第一个参数的起始值为500时发生。

是否确定“将是最佳的”?对于返回的p1,errfunc的值是多少?对于您希望得到的
[250,随便,-10]
,errfunc的值是多少?将此信息添加到原始帖子中(而不是在这里,因为注释中的代码被弄乱了)曲线拟合的另一种方法是使用小波技术进行特征提取。我发现数据随着时间的变化会出现线性漂移。在某个时间t0,漂移突然跳跃并具有不同的斜率,并且它也发生了第二次。所以我真正想要的是在三个不同的范围内拟合三条线。问题是,跳跃时间事先不知道,我需要对数千个数据集这样做,所以我希望跳跃时间、直线的斜率和截距都是自由参数。我只是想从一个更简单的例子开始。如果它是时间相关的数据,就更有理由使用傅里叶变换。也许FFT会更有用。SciPy有FFT功能:这种方法对我也适用;我建议接受它作为答案。
print np.sum(errfunc([250.,-10.,0.], x, y)**2.)
print np.sum(errfunc([250.,-9.5,0.5], x, y)**2.)