Вопрос по scipy, curve-fitting, python – Разница между алгоритмом Левенберга-Марквардта и ODR

1

Я смог подогнать кривые к набору данных х / у, используяПик-O-MAT, как показано ниже. Это линейный фон и 10 лоренцевских кривых. Peak-o-mat results

Так как мне нужно подогнать много похожих кривых, я написал скриптовую процедуру подгонки, используяmpfit.py, который является алгоритмом Левенберга-Марквардта. Однако подгонка занимает больше времени и, на мой взгляд, менее точна, чем результат пиковой нагрузки:

Starting values Starting values

Fit result with fixed linear background (значения для линейного фона взяты из пикового результата) Fit fixed

Fit result with all variables free Fit free

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

Результат еще хуже для полной свободной подгонки.

Peak-o-mat, кажется, используетscipy.odr.odrpack, Теперь, что более вероятно:

I did some implementation error? odrpack is more suitable for this particular problem?

Подгонка к более простой задаче (линейные данные с одним пиком посередине) показывает очень хорошую корреляцию между вершинами и моим сценарием. Также я не нашел много о ordpack.

Edit: Кажется, я мог бы ответить на вопрос сам, однако ответ немного тревожит. Использование scipy.odr (которое позволяет использовать метод odr или leastsq) позволяет получить результат как peak-o-mat, даже без ограничений.

На рисунке ниже снова показаны данные, начальные значения (почти идеальные), а затем значения odr и leastsq. Кривые компонентов для одра

scipy.odr

Я переключусь на odr, но это все равно оставляет меня расстроенным. Методы (mpfit.py, scipy.optimize.leastsq, scipy.odr в режиме leastsq) «должны»; дают одинаковые результаты.

И для людей, спотыкающихся об этом посте: для подбора odr должна быть указана ошибка для значений x и y. Если ошибки нет, используйте маленькие значения с sx & lt; & lt; с.

linear = odr.Model(f)
mydata = odr.RealData(x, y, sx = 1e-99, sy = 0.01)
myodr = odr.ODR(mydata, linear, beta0 = beta0, maxit = 2000)
myoutput1 = myodr.run() 
Пик-о-мат является открытым исходным кодом, так что вы можете в принципе понять, как он работает. pv.

Ваш Ответ

1   ответ
1

Вы также можете использовать peak-o-mat для написания сценариев. Проще всего было бы создать проект, содержащий все данные, которые вы хотите подогнать, через графический интерфейс, очистить его, преобразовать и присоединить (т.е. выбрать модель, дать начальное предположение и подогнать) базовую модель к одному из наборов. Затем вы можете (глубоко) скопировать эту модель и прикрепить ее ко всем другим наборам данных. Попробуй это:

from peak_o_mat.project import Project
from peak_o_mat.fit import Fit
from copy import deepcopy

p = Project()
p.Read('in.lpj')

base = p[2][0]    # this is the set which has been fit already

for data in p[2][1:]: # all remaining sets of plot number 2

    mod = deepcopy(base.mod)
    data.mod = mod

    f = Fit(data, data.mod)
    res = f.run()

    pars = res[0]
    err = res[1]

    data.mod._newpars(pars, err)

    print data.mod.parameters_as_table()

p.Write('out')

Пожалуйста, скажите мне, если вам нужно больше деталей.

Просто нашел это. Это не логическое значение, а список. Чтобы получить пределы первого набора использованияbase.limits, Чтобы применить эти ограничения ко всем другим наборам перед установкой, добавьтеdata._set_limits(base.limits) внутри для цикла. Для изменения максимальных итераций используйтеf = Fit(data, data.mod, maxiter=200) (на 200 итераций). user334287
Привет, я не проверял давно. Большое спасибо за ваш комментарий. Это очень полезно, чтобы увидеть, как писать скрипт пиковой нагрузки. Это очень удобно. Одна проблема, с которой я столкнулся, заключается в том, что приведенный выше код не копирует параметры подгонки (ограничение подгонки для видимого диапазона, максимальное количество итераций). Как установить этот параметр? user334287
Btw. Полные документы odrpack можно найти здесь:docs.scipy.org/doc/external/odrpack_guide.pdf

Похожие вопросы