Ошибка Scipy Несовместимые ограничения неравенства (Выход из режима 4) - PullRequest
0 голосов
/ 08 июля 2020

Я решаю задачу оптимизации, чтобы выполнить ограниченную нелинейную регрессию с использованием экспериментальных данных. Я использую 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...