用积分函数拟合数据
Fitting data with integral function
当使用curve_fit
from scipy.optimize
拟合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。任何帮助深表感谢。这个问题实际上应该是一个通用问题,post 中使用的函数只是随机示例。
下面是一个根据积分定义的曲线拟合示例。该曲线是 sin(t*w)/t+p
在 t
从 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
兼容的矢量化版本。
有时你很幸运,你能够分析地评估积分。在下面的示例中,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()
假设)。
当使用curve_fit
from scipy.optimize
拟合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。任何帮助深表感谢。这个问题实际上应该是一个通用问题,post 中使用的函数只是随机示例。
下面是一个根据积分定义的曲线拟合示例。该曲线是 sin(t*w)/t+p
在 t
从 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
兼容的矢量化版本。
有时你很幸运,你能够分析地评估积分。在下面的示例中,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()
假设)。