Как оптимизировать или минимизировать функцию для нескольких массивов в Python? - PullRequest
0 голосов
/ 24 марта 2020

У меня есть несколько массивов, которым я хотел бы соответствовать показательной функции в форме, приведенной ниже:

y = A \ times e ^ {Ex} \ times M ^ {m} \ times N ^ {n}

У меня есть пять массивов в MWE, y1, y2, y3 ..., y5; с M и N принимает значения, показанные в MWE. Теперь я хотел бы найти оптимальное значение A, E, m и n, такое, чтобы остатки были минимизированы.

MWE, приведенный ниже, делает это индивидуально для каждого массива y1, или y2, или y3; давая мне (A1, E1, m1, n1), (A2, E2, m2, n2), ... (A5, E5, m5, n5). Как я могу применить оптимизацию для всех массивов таким образом, чтобы для определенного значения A, E, m и n (т. Е. Одинаковых значений A, E, m и n) я получал наименьшую ошибку?

MWE

from __future__ import division
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
def f(params, y, M, N):
    A, E, m, n, = params
    residuals = y - (A * np.exp(E*x/1000) * (M ** m) * (N ** n))
    objective = (residuals**2).sum()
    return objective

x = np.array([1.170, 1.194, 1.223, 1.255, 1.282, 1.325, 1.358, 1.389, 1.435, 1.471])
y_1 = np.array([16.96, 18.45, 20.58, 21.62, 27.22, 33.98, 41.32, 55.64, 72.66, 95.68])
y_2 = np.array([22.74, 25.69, 34.54, 35.77, 40.88, 45.53, 60.12, 72.65, 91.54, 102.58])
y_3 = np.array([26.11, 21.99, 26.88, 31.63, 41.06, 45.47, 59.04, 60.11, 79.79, 97.79])
y_4 = np.array([33.73, 36.01, 35.12, 35.94, 47.02, 56.55, 63.94, 66.78, 96.06, 116.07])
y_5 = np.array([30.87, 33.09, 32.51, 41.72, 42.75, 54.52, 63.02, 78.15, 89.02, 102.54])

M = np.array([40, 20, 20, 15, 12])
N = np.array([0.5, 0.5, 1.0, 1.0, 1.5])

result = optimize.minimize(f, [45, 2000, -1.0, -0.5], y_1)
A1, E1, m1, n1 = result.x
y_predicted_1 = (A1 * np.exp(E1*x/1000) * (40 ** m1) * (0.50 ** n1))

result = optimize.minimize(f, [45, 2000, -1.0, -0.5], y_2)
A2, E2, m2, n2 = result.x
y_predicted_2 = (A2 * np.exp(E2*x/1000) * (40 ** m2) * (0.50 ** n2))

result = optimize.minimize(f, [45, 2000, -1.0, -0.5], y_3)
A3, E3, m3, n3 = result.x
y_predicted_3 = (A3 * np.exp(E3*x/1000) * (40 ** m3) * (0.50 ** n3))

result = optimize.minimize(f, [45, 2000, -1.0, -0.5], y_4)
A4, E4, m4, n4 = result.x
y_predicted_4 = (A4 * np.exp(E4*x/1000) * (40 ** m4) * (0.50 ** n4))

result = optimize.minimize(f, [45, 2000, -1.0, -0.5], y_5)
A5, E5, m5, n5 = result.x
y_predicted_5 = (A5 * np.exp(E5*x/1000) * (40 ** m5) * (0.50 ** n5))

1 Ответ

0 голосов
/ 25 марта 2020

Ты на самом деле почти там. Просто используйте несколько аргументов в качестве аргумента (работает из-за того, как вы спроектировали f):

result = optimize.minimize(f, [45, 2000, -1., -.5], [y_1, y_2, y_3, y_4, y_5])
A_, E_, m_, n_ = result.x
y_predicted_all = (A_ * np.exp(E_*x/1000) * (40 ** m_) * (0.50 ** n_))

Тогда вы получите следующие остатки:

Residuals (overall): 
1: 1361.14349
2: 107.87036
3: 165.67150
4: 713.73400
5: 358.97836

Residuals (individual): 
1: 53.10579
2: 72.27874
3: 76.72340
4: 206.37223
5: 60.04984

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

enter image description here enter image description here

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