Я пытаюсь оптимизировать SSE (сумму квадратов ошибок) функции, используя scipy.optimize. Чтобы проверить, я создал простую задачу, как показано ниже.
Но оптимизированные параметры, выводимые scipy, никогда не делают SSE = 0. Может кто-нибудь помочь мне понять, где я ошибаюсь.
Я попытался перепроверить SSE, рассчитанный моим кодом, с вычисленным в Excel. Это совпало. Затем я использовал функцию минимизации, чтобы минимизировать эту функцию SSE, вычисленные Scipy, не совпадают с рассчитанными вручную. Функция, к которой я привык, имеет вид (y=ax+b). Ниже приведен код
import numpy as np
from scipy.optimize import minimize
e=np.array([0,2])
sig1=np.array([0,200])
k = [10,10]
#n = 0.2
coe=np.array([k[0],k[1]])
def sig2(e):
v=(k[0]*e)+ k[1]
SEzip = zip(sig1, v)
sse = 0
for y in SEzip:
sse += np.power((y[0] - y[1]),2)
return sse
print (sig2(e))
def f(coe):
print(coe)
return f
result = minimize(sig2,coe,method='Nelder-Mead',callback=(f),options = {'xtol': 1e-6,'ftol':1e-06,'maxiter':50000,'disp': True,'adaptive' : True})
print(result)





Вы печатали свой x0 ака coe здесь, я отредактировал ваш код и сократил вашу целевую функцию sig2() в одну строку, а затем отредактировал ваш обратный вызов, чтобы отобразить тестируемую переменную и ее эквивалентное значение целевой функции. Теперь вы можете ясно видеть, что sse=0 достигнуто.
import numpy as np
from scipy.optimize import minimize
# for prettier numpy prints
np.set_printoptions(precision = 6)
# init
e = np.array([0,2])
sig1 = np.array([0,200])
k = [10, 10]
coe = np.array([k[0], k[1]])
# define objective function
def sig2(e):
return sum([np.power((y[0] - y[1]), 2) for y in zip(sig1, (k[0]*e)+ k[1])])
# define callback
def f(e):
print("e: %25s | sig2(e): %5s" % (e,round(sig2(e), 6)))
# optimize
result = minimize(sig2,
coe,
method = 'Nelder-Mead',
callback = f,
options = {'xtol': 1e-6,'ftol':1e-06,
'maxiter':50000,'disp': True,'adaptive' : True})
print(result)
Выход:
...
e: [-1.000053 18.999751] | sig2(e): 6e-06
e: [-1.000062 19.000109] | sig2(e): 2e-06
e: [-1.000062 19.000109] | sig2(e): 2e-06
e: [-1.000062 19.000109] | sig2(e): 2e-06
e: [-0.999934 18.999981] | sig2(e): 0.0
e: [-1.000049 18.999979] | sig2(e): 0.0
e: [-1.000027 19.000044] | sig2(e): 0.0
e: [-0.999986 18.999996] | sig2(e): 0.0
e: [-0.999986 18.999996] | sig2(e): 0.0
e: [-0.999986 18.999996] | sig2(e): 0.0
e: [-1.000009 18.999993] | sig2(e): 0.0
e: [-1.000009 18.999993] | sig2(e): 0.0
e: [-0.999995 19. ] | sig2(e): 0.0
e: [-0.999995 19. ] | sig2(e): 0.0
e: [-1.000003 18.999998] | sig2(e): 0.0
e: [-1. 19.000002] | sig2(e): 0.0
e: [-0.999998 19. ] | sig2(e): 0.0
e: [-1.000001 18.999999] | sig2(e): 0.0
e: [-1. 19.000001] | sig2(e): 0.0
e: [-0.999999 19. ] | sig2(e): 0.0
e: [-1. 19.] | sig2(e): 0.0
e: [-1. 19.] | sig2(e): 0.0
e: [-1. 19.] | sig2(e): 0.0
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 56
Function evaluations: 110
final_simplex: (array([[-1., 19.],
[-1., 19.],
[-1., 19.]]), array([6.221143e-12, 1.914559e-11, 1.946860e-11]))
fun: 6.2211434216849394e-12
message: 'Optimization terminated successfully.'
nfev: 110
nit: 56
status: 0
success: True
x: array([-1., 19.])
Спасибо за ваш ответ. Но я вижу, что предсказанный оптимум неверен. Хотя вывод Scipy показывает sse=0, если я заменю предсказанные значения, sse=33850.. Оптимальное значение должно быть (100,0).
Куда подставляете значения? sig2(np.array([-1, 19])) = 0 и sig2(np.array([100, 0])) = 1056200 ?
Да, я вручную подставляю в то же уравнение, чтобы перепроверить результаты. Я также проверил в листе excel
В этом случае ваша реализация sig2() не соответствует вашей функции, которую вы заменяете. Удачи.
когда я печатаю sig2(), первое значение идеально соответствует ручному расчету. Это означает, что функция правильная.
То, что одно значение каким-то образом совпадает, не означает, что оно правильное. Вы должны проверить как минимум 3 случайных значения.
Я пробовал со многими случайными парами для k[0] & k[1] и print(sig2(e). все значения вычисляются правильно. Чего-то не хватает в функции scipy.optimize.minimze?
Спасибо большое за вашу поддержку. Я передал в функцию неправильную переменную. sig2(e) должен быть sig2(k). Теперь работает идеально!!!
Будет очень полезно, если кто-нибудь поможет мне решить эту проблему.