首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将抛物线形状拟合到数据(是否可以使用SciPy CurveFit的逻辑语句?)

将抛物线形状拟合到数据(是否可以使用SciPy CurveFit的逻辑语句?)
EN

Stack Overflow用户
提问于 2013-04-25 06:30:59
回答 1查看 6.1K关注 0票数 2

我试图用一个抛物线形状来拟合数据:Y(x) = a(1 - (x/b)^2)。Y(x) =0,否则和我加了两个额外的自由度,所以抛物线可以水平地和垂直地移动。

代码语言:javascript
运行
复制
from scipy.optimize import curve_fit

def parabolic(self, t, *p): 
    a, b, c, d = p        
    if abs(t) > b:
        return 0
    else:
        return a*(1-(((t-c)/b)**2)) + d

我试图从curve_fit中使用scipy.optimize,并创建了一个抛物线函数,然后尝试使用以下方法:

代码语言:javascript
运行
复制
coeff, cov = curve_fit(parabolic, data[:,0], data[:,1], p0) #Return co-effs for fit and      covariance, p0 = user given seed fitting parameters

脚本返回一个错误,尽管与在我的抛物线拟合定义中使用逻辑有关。当我删除逻辑语句,只适合于整个数据(这是一个背景噪声水平与抛物线形状在中心),结果是可怕的,因为拟合试图包括背景噪声水平。

欢迎所有建议。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-25 09:42:15

我可能会这样做:

代码语言:javascript
运行
复制
from __future__ import division
from __future__ import print_function
from scipy.optimize import curve_fit
import numpy as np

def parabola(t, *p): 
    a, b, c, d = p
    y = np.zeros(t.shape)
    indices = np.abs(t) < b
    y[indices] = (a*(1-(((t[indices]-c)/b)**2)) + d)
    return y

p0 = [1, 2, 3, 4]
x = np.linspace(-10, 10, 20)
y = parabola(x, *p0)
coeff, cov = curve_fit(parabola, x, y, p0)
print(coeff)

更新

有了所提供的数据(请参阅注释中的链接),情况开始变得更加清晰:

  • 就其行为而言,这是一个棘手的数据。许多“零”数据将无助于拟合函数,因为实际函数的权重随着数据的增加而变得越来越少。通常,最好的方法是减少一些,集中精力于相关的数据(一旦有了这些数据,就可以尝试用最好的参数来匹配所有的数据)。
  • 这个标准是不正确的:它的中心是零,而不是数据的峰值(c)。
  • 在函数和索引准则中都有参数bc会使事情变得更加困难:函数的线性行为越来越少。我使用一个固定的标准找到了初始的最佳参数,这是下面的注释行。
  • 提供良好的启动参数。[1, 2, 3, 4]只是非常通用的,在非线性最小二乘的情况下,很难适应。

因此,考虑到以上所有因素,我想出了如下结论:

代码语言:javascript
运行
复制
from __future__ import division
from __future__ import print_function
from scipy.optimize import curve_fit
import numpy as np
from matplotlib import pyplot as plt

def parabola(t, *p): 
    a, b, c, d = p
    y = np.zeros(t.shape)
    # The indices criterion was first fixed to values that appeared reasonably; 
    # otherwise the fit would completely fail.
    # Once decent parameters were found, I replaced 28 and 0.3 with the center `c` 
    # and the width `b`.
    #indices = np.abs(t-28) < 0.3
    indices = np.abs(t-c) < b
    y[indices] = (a*(1-(((t[indices]-c)/b)**2)) + d)
    return y

out = np.loadtxt('data.dat')
# Limit the data to only the interesting part of the data
# Once we have the fit correct, we can always attempt a fit to all data with 
# good starting parameters
xdata = out[...,0][450:550]
ydata = out[...,1][450:550]
# These starting parameters are either from trial fitting, or from theory
p0 = [2, 0.2, 28, 6.6]
coeff, cov = curve_fit(parabola, xdata, ydata, p0)
plt.plot(xdata, ydata, '.')
xfit = np.linspace(min(xdata), max(xdata))
yfit =  parabola(xfit, *coeff)
plt.plot(xfit, yfit, '-')
plt.show()

请注意,得到的b参数仍然表示不合适。我猜这些数据和这个函数的组合是很棘手的。一种选择是迭代各种合理的b值(例如,在0.2到0.3之间),并找到最佳的降维平方。

但是,我也注意到数据并不是以抛物线的形式出现的。最初,当我看到完整的数据图片时,我以为是“高斯”,但也不是这样。它看上去就像一个箱体功能。如果你有一个很好的理论模型,说它是一个抛物线,那么要么数据被关闭,要么模型可能不正确。如果您只是在寻找一个描述性函数,也可以尝试一些其他函数。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16207890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档