Я решаю задачу оптимизации, чтобы выполнить ограниченную нелинейную регрессию с использованием экспериментальных данных. Я использую scipy minim, и он работает с исходными данными, но не работает, когда я выполняю простое преобразование данных. Для преобразованных данных я использую решение Excel для той же проблемы, что и начальное условие, поэтому оно должно работать, но не могу понять, почему это не так. Пожалуйста, приветствуется любая помощь. Заранее спасибо, кстати.
Вот код с исходными данными (работает) и преобразованием (не работает)
import numpy as np
from scipy.optimize import Bounds, minimize
def yp(x, time, mode = 'fit'):
y1 = x[0] + x[1]*time
y2 = x[2] + (x[3] - x[2])*np.exp(-x[5]*(time - x[4])/(x[3] - x[2]))
comparison = time < x[4]
yp = y1*comparison + y2*(~comparison)
if mode == 'fit':
return yp
elif mode == 'calc':
return y1, y2
else:
print('Unsupported mode, returning default behavior for fitting data')
return yp
def objective(x, time, y):
ypred = yp(x, time)
z = sum((ypred - y)**2)
return z
#***********************
#Original data
#***********************
data_x = np.array([0,30,60,90,120,150,180,210,240,270,300,330,360,420,480,540,600,720,840])
data_y = np.array([11.06468023,10.03242418,9.771158736,8.873720137,8.618127786,
8.397702515,7.581607582,7.131636821,6.537043245,6.358885017,
5.898468977,5.25275811,4.983989976,4.141791045,2.602472349,
2.07395813,1.078129376,0.551764193,0.480052971])
x0 = [11.5, -0.0211, 0.6, 3.26, 400, 0.01919]
lbound = [9, -0.1, 0.3, 1, 200, 0]
ubound = [14, -1e-5, 1, 4, 800, 0.1]
bounds = Bounds(lbound,ubound)
constraint = dict(type = 'ineq',
fun = lambda x: 0.1 - abs(x[0] + x[1]*x[4] - x[3]))
res = minimize(fun = objective,
x0 = x0,
args = (data_x, data_y),
method = 'SLSQP',
constraints = constraint,
options = {'disp':True},
bounds = bounds)
print(res)
Optimization terminated successfully (Exit mode 0)
Current function value: 0.6681037696841838
Iterations: 20
Function evaluations: 149
Gradient evaluations: 20
fun: 0.6681037696841838
jac: array([ 1.19826198e-03, 5.93313336e-01, 9.38165262e-02, 6.77183270e-04,
1.15633011e-05, -3.35602835e-02])
message: 'Optimization terminated successfully'
nfev: 149
nit: 20
njev: 20
status: 0
success: True
x: array([ 1.06185481e+01, -1.59476490e-02, 3.00000000e-01, 3.86162000e+00,
4.29964822e+02, 2.80661182e-02])
#***********************
#Transformed data
#***********************
data_y_rel = data_y/data_y[0]
x0_rel = [1, -0.00207571, 0.03, 0.359269446, 313.497571, 0.001970666]
lbound_rel = [1, -0.1, 0.03, 0.1, 200, 0]
ubound_rel = [1, -1e-5, 0.1, 0.4, 800, 0.1]
bounds_rel = Bounds(lbound_rel,ubound_rel)
constraint_rel = dict(type = 'ineq',
fun = lambda x: 0.01 - abs(x[0] + x[1]*x[4] - x[3]))
res_rel = minimize(fun = objective,
x0 = x0_rel,
args = (data_x, data_y_rel),
method = 'SLSQP',
constraints = constraint_rel,
options = {'disp':True},
bounds = bounds_rel)
print(res_rel)
Inequality constraints incompatible (Exit mode 4)
Current function value: 0.1593965203706159
Iterations: 1
Function evaluations: 7
Gradient evaluations: 1
fun: 0.1593965203706159
jac: array([ nan, -2.88985475e+02, -1.53672213e-01, -1.13128023e+00,
-1.58630125e-03, 5.45240970e+01])
message: 'Inequality constraints incompatible'
nfev: 7
nit: 1
njev: 1
status: 4
success: False
x: array([ 1.00000000e+00, -2.07571000e-03, 3.00000000e-02, 3.59269446e-01,
3.13497571e+02, 1.97066600e-03])
C:\Users\username\Anaconda3\lib\site-packages\scipy\optimize\_numdiff.py:519: RuntimeWarning: invalid value encountered in true_divide
J_transposed[i] = df / dx