Подгонка данных с интегральной функцией

При использовании curve_fit из scipy.optimize, чтобы подогнать некоторые данные в python, сначала нужно определить подгонку функцию (например, полином 2-го порядка) следующим образом:

  1. def f(x, a, b): return a*x**2+b*x
  2. Затем приступаем к примерке popt, pcov = curve_fit(f,x,y)

Но теперь вопрос в том, как определить функцию в точке 1., если функция содержит интеграл (или дискретную сумму), например:

введите здесь описание изображения

Экспериментальные данные по-прежнему даны для x и f (x), поэтому пункт 2 будет аналогичен, я думаю, когда я смогу определить f (x) в python. Кстати, я забыл сказать, что предполагается, что g(t) имеет здесь хорошо известную форму и содержит подгоночные параметры, то есть такие параметры, как a и b, приведенные в полиномиальном примере. Любая помощь горячо приветствуется. Вопрос действительно должен быть общим, а функции, используемые в посте, являются просто случайными примерами.


person Community    schedule 19.05.2015    source источник
comment
Очевидный ответ: вам нужен способ вычислить этот интеграл либо путем нахождения решения в замкнутой форме, либо с помощью числовой квадратуры. Для этого нет универсального решения.   -  person cfh    schedule 19.05.2015
comment
@cfh о, я понимаю, это правда, но если у него нет решения в закрытой форме, что именно влечет за собой числовая квадратура? разве это не предполагает, что все параметры должны быть известны тогда?   -  person    schedule 19.05.2015
comment
Да, но во время вызова f вы знаете все параметры, поскольку они передаются в качестве аргументов.   -  person cfh    schedule 19.05.2015
comment
Разве это не то же самое в простом полиномиальном примере, который вы показали? Есть два параметра, a и b, которые вы пытаетесь подобрать, но используете их в формуле a*x**2+b*x.   -  person cfh    schedule 19.05.2015
comment
@cfh Конечно, но в этом примере мне не нужно было выполнять численное интегрирование, поэтому мне не нужно было знать a и b перед подгонкой. Но следуя вашему предложению сначала оценить интеграл, я должен был бы знать a и b до подгонки (чтобы выполнить интеграл численно), чего я не знаю...   -  person    schedule 19.05.2015
comment
Нет. Когда функция curve_fit вызывает ваш f, она всегда предоставляет определенные значения для a и b. Вы можете использовать их для вычисления полинома, вычисления интеграла, делать все, что захотите.   -  person cfh    schedule 19.05.2015
comment
@cfh оооо теперь я понимаю, что ты имел в виду, верно, верно! Не могли бы вы (или если бы у вас было время) показать простой пример для этого (т.е. численное интегрирование)?   -  person    schedule 19.05.2015
comment
Это действительно во многом зависит от функции, которую вы пытаетесь интегрировать. Некоторые функции для этого содержатся в scipy.integrate.   -  person cfh    schedule 19.05.2015


Ответы (2)


Вот пример подгонки кривой, заданной интегралом. Кривая представляет собой интеграл от 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, которое мы использовали как p при создании trueydata.

Обратите внимание, что мы используем numpy.vectorize в функции кривой для создания векторизованной версии, совместимой с scipy.optimize.curve_fit.

person Jay Kominek    schedule 23.05.2015
comment
это интересно, полезно и, по-моему, достаточно обобщенно, но можем ли мы сделать немного лучше, зная, что это интеграл? В вашем решении curve может быть чем угодно и не выигрывает от того, что оно целочисленное. Может, вопрос стоит изменить на fitting data with non-vectorized functions? - person dashesy; 23.05.2015

Иногда вам может повезти, и вы сможете вычислить интеграл аналитически. В следующем примере произведение h(t)=exp(-(t-x)**2/2) и полинома второй степени g(t) интегрируется от 0 до бесконечности. Sympy используется для оценки интеграла и создания функции, пригодной для 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()).

person Dietrich    schedule 24.05.2015