Python: метод наименьших квадратов с боковыми условиями для параметров подгонки - PullRequest
0 голосов
/ 12 марта 2012

У меня есть временной ряд, который я хочу приспособить для работы с использованием Scipy.optimize.leastsq.

fitfunc= lambda a, x:     a[0]+a[1]*exp(-x/a[4])+a[2]*exp(-x/a[5])+a[3]*exp(-x    /a[6])    
errfunc lambda a,x,y:     fitfunc(a,x) - y

Далее я передам errfunc в leastsq, чтобы минимизировать его. Функция подгонки, которую я использую, представляет собой сумму экспонент, убывающих с различными временными шкалами a (4: 6) и разными весами (a (0: 4)). (в качестве дополнения: могу ли я использовать leastsq с более чем 1 массивом параметров? Мне не удалось это сделать ....)

Вопрос: Как я могу задать дополнительные побочные условия для параметров, входящих в функцию соответствия. Я хочу, например, эту сумму (а (0: 4)) = 1,0

Ответы [ 2 ]

3 голосов
/ 12 марта 2012

Просто используйте

import numpy as np

def fitfunc(p, x):
    a = np.zeros(7)
    a[1:7] = p[:6]
    a[0] = 1 - a[1:4].sum()
    return a[0] + a[1]*exp(-x/a[4]) + a[2]*exp(-x/a[5]) + a[3]*exp(-x/a[6])

def errfunc(p, x, y1, y2):
    return np.concatenate((
        fitfunc(p[:6], x) - y1,
        fitfunc(p[6:12], x) - y2
    ))

Обычно лямбда-функции считаются плохим стилем (и они ничего не добавляют в ваш код).Чтобы иметь несколько функций в наименьшем квадрате, вы можете просто добавить функции, как я указал, используя np.concatenate.Это не имеет большого смысла, если ни один из параметров не коррелирован, однако.Это только замедлит сходимость алгоритма.Запрашиваемое вами побочное условие реализуется путем простого вычисления одного веса на основе заданного вами ограничения (см. 1 - a [1: 4] .sum ()).

0 голосов
/ 14 марта 2012

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

Например, если вам нужна эта сумма (sin (p [i]) == 1, вы можете сделать следующее:

constraint_func = lambda a: sin(a).sum()-1

def fitfunc (a,x):
    np.concatenate((a[0]+a[1]*exp(-x/a[4])+a[2]*exp(-x/a[5])+a[3]*exp(-x /a[6]),
                   [constraint_func(a)]))

def errfunc(a,x,y):
    tolerance = 1e-10
    return np.concatenate((fitfunc(a,x) - y, [tolerance]))

Очевидно, что сходимость будет медленнее, но все равно будет гарантирована.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...