Непрямая сплайн-интерполяция в Scipy / Python

Мне нужно сопоставить данные довольно косвенным образом. Исходные данные, подлежащие восстановлению при подгонке, представляют собой некоторую линейную функцию с небольшими колебаниями и дрейфами на ней, которые я хотел бы идентифицировать. Назовем это f (t). Мы не можем записать этот параметр в эксперименте напрямую, а только косвенно, скажем, как g (f) = sin (a f (t)). (Реальная функция передачи более сложна, но она не должна играть здесь роли)

Итак, если f (t) меняет направление в сторону поворотных точек функции sin, это трудно идентифицировать, и я попробовал альтернативный подход для восстановления f (t), чем просто обратная функция g и некоторые предположения, продолжающие данные:

Я создаю модельную функцию fm (t), которая претерпевает ту же известную передаточную функцию g () и подгоняет g (fm (t)) к данным. Поскольку набор данных огромен, я делаю это по частям для последовательных порций данных, гарантируя непрерывность fm по всему набору.

Первой попыткой было использовать линейные функции с помощью optimize.leastsq, где оценка ошибки выводится из g (fm). Это не совсем удовлетворительно, и я думаю, что было бы гораздо лучше подогнать сплайн к данным, чтобы получить fspline (t) в качестве модели для f (t), гарантирующей непрерывность данных и их производной.

Проблема в том, что подгонка сплайна из пакета интерполяции работает с данными напрямую, поэтому я не могу обернуть сплайн с помощью g (fspline) и выполнить интерполяцию сплайна на этом. Есть ли способ сделать это в scipy?

Есть другие идеи?

Я пробовал квадратичные функции и исправлял смещение и наклон так, чтобы они соответствовали параметрам предыдущего подогнанного блока данных, поэтому есть только один подгоночный параметр, кривизна, которая очень быстро начинает отклоняться.

Спасибо


person eaglebauer    schedule 05.07.2012    source источник


Ответы (2)


Вам понадобится матрица базисных функций сплайна, b (t), чтобы вы могли аппроксимировать f (t) как линейную комбинацию базисной функции сплайна.

f(t) = np.dot(b(t), coefs)

а затем оцените коэффициенты, coef, с помощью optimize.leastsq.

Однако, насколько мне известно, базовые функции сплайна не всегда доступны в python (если вы не заимствуете экспериментальные сценарии или не просматриваете код некоторых пакетов).

Вместо этого вы также можете использовать многочлены, например

b(t) = np.polynomial.chebvander(t, order) 

и используйте полиномиальную аппроксимацию вместо сплайнов.

Структура этой проблемы очень похожа на обобщенные линейные модели, где g - известная вам функция связи, и аналогична индексным задачам в эконометрике.

Можно было бы использовать scipy splines косвенным образом, если бы вы создали искусственные данные

y_i = f(t_i) 

где f (t_i) - это сплайны scipy.interpolate, а y_i - параметры, которые необходимо оценить при оптимизации по методу наименьших квадратов. (Вольно основанный на сценарии, который я видел некоторое время назад, который использовал это для создания другого вида сглаживающих сплайнов, чем scipy версия. Я не помню, где я это видел.)

person Josef    schedule 07.07.2012

Спасибо за эти комментарии. Я опробовал предложенный выше полиномиальный базис, но полиномы не подходят для моих нужд, они, как правило, вызывают звон, который трудно обусловить.

Решение по использованию шлицев, которое я сейчас нашел, довольно простое и понятное, и я думаю, это именно то, что вы имели в виду, говоря «косвенное использование шлицев».

Функция аппроксимации f (t) получается функцией interpolate.splev (x, (t, c, k)), но предоставляет коэффициенты сплайна c функцией omptimize.leastsq. Таким образом, f (t) не является прямым сплайном (как обычно получается с помощью функции splrep (x, y)), но косвенно оптимизируется при подгонке, и поэтому для него можно использовать функцию связи g. Первоначальное предположение для c может быть получено путем одной оценки splrep (xinit, yinit, t = knots) на данных модели.

Один из приемов состоит в том, чтобы ограничить количество узлов для сплайна ниже количества точек данных, явно указав их во время вызова функции splrep () и предоставив этот сокращенный набор во время оценки с помощью splev ().

person eaglebauer    schedule 13.07.2012