Scipy, дифференциальная эволюция

дело в том, что я пытаюсь разработать процедуру подгонки для своих целей и хочу использовать алгоритм дифференциальной эволюции scipy в качестве общей оценки начальных значений, которые затем будут использоваться в алгоритме LM для лучшей подгонки. Функция, которую я хочу минимизировать с помощью DE, - это наименьшие квадраты между аналитически определенной нелинейной функцией и некоторыми экспериментальными значениями. Точка, в которой я застрял, - это дизайн функции. Как говорится в ссылке scipy:" функция должна находиться в форма f (x, *args) , где x-аргумент в виде 1-D массива, а args-кортеж любых дополнительных фиксированных параметров, необходимых для полного указания функции"

есть уродливый пример кода, который я написал просто для примера:

def func(x, *args):
    """args[0] = x
       args[1] = y"""
    result = 0
    for i in range(len(args[0][0])):
        result += (x[0]*(args[0][0][i]**2) + x[1]*(args[0][0][i]) + x[2] - args[0][1][i])**2   
    return result**0.5

if __name__ == '__main__':
    bounds = [(1.5, 0.5), (-0.3, 0.3), (0.1, -0.1)]
    x = [0,1,2,3,4]
    y = [i**2 for i in x]
    args = (x, y)
    result = differential_evolution(func, bounds, args=args)
    print(func(bounds, args))

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

1 ответов


это своего рода простое решение, которое показывает идею, также код не очень питонический, но для простоты я думаю, что это достаточно хорошо. Хорошо, в качестве примера мы хотим подогнать уравнение вида y = ax^2 + bx + c к данным, полученным из уравнения y = x^2. Очевидно, что параметр a = 1 и b, c должен быть равен 0. Поскольку алгоритм дифференциальной эволюции находит минимум функции, мы хотим найти минимум среднеквадратичного отклонения (опять же, для простоты) аналитического решения общего уравнение (y = ax^2 + bx + c) с заданными параметрами (обеспечивая некоторую начальную догадку) против "экспериментальных" данных. Итак, к коду:

from scipy.optimize import differential_evolution

def func(parameters, *data):

    #we have 3 parameters which will be passed as parameters and
    #"experimental" x,y which will be passed as data

    a,b,c = parameters
    x,y = data

    result = 0

    for i in range(len(x)):
        result += (a*x[i]**2 + b*x[i]+ c - y[i])**2

    return result**0.5

if __name__ == '__main__':
    #initial guess for variation of parameters
    #             a            b            c
    bounds = [(1.5, 0.5), (-0.3, 0.3), (0.1, -0.1)]

    #producing "experimental" data 
    x = [i for i in range(6)]
    y = [x**2 for x in x]

    #packing "experimental" data into args
    args = (x,y)

    result = differential_evolution(func, bounds, args=args)
    print(result.x)