用积分函数拟合数据

Posted

技术标签:

【中文标题】用积分函数拟合数据【英文标题】:Fitting data with integral function 【发布时间】:2015-07-31 15:45:26 【问题描述】:

当使用scipy.optimize中的curve_fit在python中拟合一些数据时,首先定义拟合函数(例如二阶多项式)如下:

    def f(x, a, b): return a*x**2+b*x 然后进行拟合popt, pcov = curve_fit(f,x,y)

但现在的问题是,如何定义第 1 点中的函数。如果函数包含积分(或离散和),例如:

仍然给出了 x 和 f(x) 的实验数据,所以第 2 点会是相似的,我想一旦我可以在 python 中定义 f(x)。顺便说一句,我忘了说这里假设 g(t) 有一个众所周知的形式,并且包含拟合参数,即多项式示例中给出的参数,如 a 和 b。任何帮助深表感谢。这个问题真的应该是一个通用的问题,帖子中使用的函数只是随机示例。

【问题讨论】:

显而易见的答案是:您需要一种方法来评估该积分,要么通过找到封闭形式的解,要么通过使用数值求积。对此没有通用的解决方案。 @cfh 哦,我明白了,这是真的,但如果它没有任何封闭形式的解决方案,那么数值求积究竟意味着什么?不是假设所有参数都应该知道吗? 是的,但是在调用f 时,您知道所有参数,因为它们是作为参数传递的。 在您展示的简单多项式示例中不完全一样吗?有两个参数,ab,您试图拟合它们,但您在公式 a*x**2+b*x 中使用它们。 @cfh 当然可以,但在那个例子中我不必进行数值积分,所以我不必在拟合之前知道 a 和 b。但是按照你的“首先评估积分”的建议,我必须在拟合之前知道 a 和 b (以数字方式进行积分),我没有...... 【参考方案1】:

这是一个拟合根据积分定义的曲线的示例。该曲线是sin(t*w)/t+pt 从 0 到 Pi 的积分。我们的 x 数据点对应于 w,我们正在调整 p 参数以使数据适合。

import math, numpy, scipy.optimize, scipy.integrate

def integrand(t, args):
    w, p = args
    return math.sin(t * w)/t + p

def curve(w, p):
    res = scipy.integrate.quad(integrand, 0.0, math.pi, [w, p])
    return res[0]

vcurve = numpy.vectorize(curve, excluded=set([1]))

truexdata = numpy.asarray([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])
trueydata = vcurve(truexdata, 1.0)

xdata = truexdata + 0.1 * numpy.random.randn(8)
ydata = trueydata + 0.1 * numpy.random.randn(8)

popt, pcov = scipy.optimize.curve_fit(vcurve,
                                      xdata, ydata,
                                      p0=[2.0])
print popt

这将打印出相当接近 1.0 的内容,这是我们在创建 trueydata 时使用的 p

请注意,我们在曲线函数上使用numpy.vectorize 来生成与scipy.optimize.curve_fit 兼容的矢量化版本。

【讨论】:

这很有趣,很有用,我认为足够通用,但是知道这是不可分割的,我们能做得更好吗?在您的解决方案中,curve 可以是任何东西,并且不会从它是不可分割的事实中受益。也许问题应该改为fitting data with non-vectorized functions【参考方案2】:

有时您可能很幸运,并且能够分析地评估积分。在以下示例中,h(t)=exp(-(t-x)**2/2) 和二阶多项式 g(t) 的乘积从 0 积分到无穷大。 Sympy 用于评估 Integral 并生成可用于 curve_fit() 的函数:

import sympy as sy
sy.init_printing()  # LaTeX-like pretty printing of IPython


t, x = sy.symbols("t, x", real=True)

h = sy.exp(-(t-x)**2/2)

a0, a1, a2 = sy.symbols('a:3', real=True)  # unknown coefficients
g = a0 + a1*t + a2*t**2

gh = (g*h).simplify()  # the intgrand
G = sy.integrate(gh, (t, 0, sy.oo)).simplify()  # integrate from 0 to infinty

# Generate numeric function to be usable by curve_fit()
G_opt = sy.lambdify((x, t, a0, a1, a2), G)

print(G_opt(1, 2, 3, 4, 5))  # example usage

请注意,通常问题通常是不适定的,因为积分不一定会收敛于解的足够大的邻域(由curve_fit() 假设)。

【讨论】:

以上是关于用积分函数拟合数据的主要内容,如果未能解决你的问题,请参考以下文章

将高斯积分函数拟合到数据

在matlab中通过带有未知参数的可变限制积分拟合数据

自适应Simpson积分

如何用matlab求积分

c语言 求定积分的通用函数

辛普森 matlab