我试着把曲线拟合到散点图的边界上。See this image for reference。
我已经完成了以下(简化)代码的拟合。它将数据帧分成小的垂直条带,然后在宽度为width
的条带中找到最小值,忽略{
def func(val):
""" returns some function of 'val'"""
return val * 2
for i in range(0, max_val, width)):
_df = df[(df.val > i) & (df.val < i + width)] # vertical slice
if np.isnan(np.min(func(_df.val)): # ignore nans
continue
xs.append(i + width)
ys.append(np.min(func(_df.val)))
然后我用scipy.optimize.curve_fit
进行拟合。我有没有一个更自然的方法来提高我的准确性呢?(例如,通过对具有更高密度点的散点图区域赋予更高权重?)在
我发现这个问题很有趣,所以决定试一试。我不知道pythonic或natural,但我认为我找到了一种更精确的方法,可以在使用来自每个点的信息时,将边缘拟合到像您这样的数据集。在
首先,让我们生成一个随机数据,它看起来像您所展示的那样。这一部分可以很容易地跳过,我发布它只是为了使代码是完整的和可复制的。我用了两个二元正态分布来模拟那些超敏感,并在它们上面撒上一层均匀分布的随机点。然后把它们加到一个类似于你的直线方程中,线下的一切都被截断,最终结果如下:
下面是制作它的代码片段:
现在我们有了数据和模型,我们可以集体讨论如何拟合点分布的边缘。常用的回归方法如非线性最小二乘法}之间的残差最小。非线性最小二乘法是一个迭代过程,它在每一步都试图改变曲线参数,以提高每一步的拟合度。很明显,这是我们不想做的一件事,因为我们希望我们的最小化程序尽可能远离最佳拟合曲线(但不要太远)。在
scipy.optimize.curve_fit
取数据值y
,并优化模型的自由参数,使y
和{因此,让我们考虑以下函数。也就是说,在每一步的迭代中,都会简单地将这些因子倒转。这样,曲线下面的点总是比上面的点多,这样每次迭代都会使曲线向下移动!一旦达到最低点,函数的最小值就被找到,散射的边缘也是如此。当然,这种方法假设曲线下没有异常值,但你的数据似乎不会受到太大影响。在
以下是实现此想法的功能:
^{pr2}$让我们看看如何查找上面的数据:
上面最重要的部分是对
leastsq
函数的调用。确保你对最初的猜测很小心-如果猜测没有落在分散上,模型可能无法正确收敛。在做出适当的猜测之后。。。在喂!边缘与真实的边缘完全吻合。在
这是一个有趣的问题,我也在尝试解决(并在python中实现它)
我认为,与其取
min
,不如取k
-最低(或k
-最高)数据点的平均值,然后拟合平均值(还应检查拟合参数是否鲁棒w.r.tk
)。 例如,您可以在supplements中找到这个想法 这件事 PNAS paper。在相关问题 更多 >
编程相关推荐