Подгонка параметрических кривых в Python
У меня есть экспериментальные данные вида (X,Y)
и теоретическая модель формы (x(t;*params),y(t;*params))
где t
является физической (но ненаблюдаемой) переменной, и *params
параметры, которые я хочу определить. t
является непрерывной переменной, и существует соотношение 1:1 между x
а также t
и между y
а также t
в модели.
В идеальном мире я бы знал ценность T
(реальное значение параметра) и будет в состоянии сделать чрезвычайно простые наименьших квадратов, чтобы найти значения *params
, (Обратите внимание, что я не пытаюсь "соединить" значения x
а также y
в моем графике, как в 31243002 или 31464345.) Я не могу гарантировать, что в моих реальных данных скрытое значение T
является монотонным, так как мои данные собираются за несколько циклов.
Я не очень опытен в подборе кривых вручную, и мне приходится использовать чрезвычайно грубые методы без легкого доступа к основной функции scipy. Мой основной подход включает в себя:
- Выберите значение
*params
и применить его к модели - Взять массив
t
значения и положить его в модель, чтобы создать массивmodel(*params) = (x(*params),y(*params))
- интерполировать
X
(значения данных) вmodel
получитьY_predicted
- Запустите сравнение наименьших квадратов (или другое) между
Y
а такжеY_predicted
- Сделайте это снова для нового набора
*params
- В конце концов, выберите лучшие значения для
*params
Есть несколько очевидных проблем с этим подходом.
1) Я не достаточно опытен в кодировании, чтобы разработать очень хорошее "сделай это снова", кроме "попробуй все в пространстве решений", возможно,"попробуй все в грубой сетке", а затем "попробуй все снова немного более тонкая сетка в горячих точках грубой сетки ". Я пытался использовать методы MCMC, но я не нашел оптимальных значений, в основном из-за проблемы 2
2) Шаги 2-4 супер неэффективны сами по себе.
Я пробовал что-то вроде (напоминает псевдокод; реальные функции составлены). При использовании широковещательной рассылки на А, В можно сделать много незначительных споров, но они менее важны, чем проблема необходимости интерполировать каждый отдельный шаг.
Люди, которых я знаю, рекомендовали использовать какой-то алгоритм максимизации ожиданий, но я не знаю достаточно об этом, чтобы кодировать его с нуля. Я действительно надеюсь, что есть какой-то потрясающий алгоритм scipy (или иным образом с открытым исходным кодом), который я не смог найти, который охватывает всю мою проблему, но на данный момент я не надеюсь.
import numpy as np
import scipy as sci
from scipy import interpolate
X_data
Y_data
def x(t,A,B):
return A**t + B**t
def y(t,A,B):
return A*t + B
def interp(A,B):
ts = np.arange(-10,10,0.1)
xs = x(ts,A,B)
ys = y(ts,A,B)
f = interpolate.interp1d(xs,ys)
return f
N = 101
lsqs = np.recarray((N**2),dtype=float)
count = 0
for i in range(0,N):
A = 0.1*i #checks A between 0 and 10
for j in range(0,N):
B = 10 + 0.1*j #checks B between 10 and 20
f = interp(A,B)
y_fit = f(X_data)
squares = np.sum((y_fit - Y_data)**2)
lsqs[count] = (A,b,squares) #puts the values in place for comparison later
count += 1 #allows us to move to the next cell
i = np.argmin(lsqs[:,2])
A_optimal = lsqs[i][0]
B_optimal = lsqs[i][1]
1 ответ
Если я правильно понимаю вопрос, параметры являются константами, которые одинаковы в каждом образце, но t
варьируется от образца к образцу. Так, например, может быть, у вас есть целая куча точек, которые, по вашему мнению, были взяты из круга
x = a+r cos(t)
y = b+r sin(t)
при разных значениях t
,
В этом случае я бы исключил переменную t
чтобы получить связь между x
а также y
-- в этом случае, (x-a)^2+(y-b)^2 = r^2
, Если ваши данные идеально соответствуют модели, вы бы (x-a)^2+(y-b)^2 = r^2
на каждой из ваших точек данных. С некоторой ошибкой вы все равно можете найти (a,b,r)
минимизировать
sum_i ((x_i-a)^2 + (y_i-b)^2 - r^2)^2.
Команда Mathematica Eliminate может автоматизировать процедуру устранения t в некоторых случаях.
PS Вы могли бы сделать лучше в stats.stackexchange, math.stackexchange или mathoverflow.net. Я знаю, что у последнего страшная репутация, но мы не кусаемся, правда!