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)