Сципи минимизирует ограничение в пандах df - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь запустить процесс минимизации, найденный в этой публикации .Уравнение видно на странице 6 документа 16 в формате pdf.

У меня есть кадр данных, который выглядит следующим образом:

 df = pd.DataFrame({'h_t':[7.06398,6.29948,5.04570,6.20774,4.80106],           
'p_atm':[101057.772801,101324.416001,101857.702401,101724.380801,101991.024001],
    'q_p':[5.768132,3.825600,2.772215,5.830429,2.619304],
    'q_s':[2.684433,3.403679,2.384275,1.008078,2.387106],
    'tdg_f':[117.678100,110.131579,108.376963,103.669725,113.594771],
    'tdg_tw':[121.052635,119.710907,114.921463,112.156868,115.444900],
    'temp_water':[11.92,19.43,16.87,7.45,11.83]})

У меня есть ограничение, которое говорит, что нижеприведенная функция должна бытьположительные, где b1 и b3 - коэффициенты, которые я оптимизирую.

def q_ge(q_p,q_s,b1,b3):   
    return min(q_p,(b1*q_s+b3))

Я написал свое ограничение ниже, но я не уверен, правильно ли оно.

def constraint_q_ge(x):
    b1,b2,b3=x
    power_flow = df.apply(lambda x:q_ge(x['q_p'],x['q_s'],b1,b3), axis = 1)
    const = power_flow<0
    return -const.sum()

Это правильно?Я запускаю функцию на всех строках и проверяю, не меньше ли 0, и суммирую это.Отрицательное значение этой суммы должно быть больше или равно 0. Если хотя бы одно значение меньше 0, это ограничение не выполняется.

РЕДАКТИРОВАТЬ:

Ниже приведена полная проблема.

from scipy.constants import g as gravity
from sklearn.metrics import mean_squared_error
from math import sqrt
from scipy.optimize import minimize
import warnings

try:
    from numpy import any as _any
except ImportError:
    def _any(arg):
        if arg is True:
            return True
        if arg is False:
            return False
        return any(arg)

def water_density(T=None, T0=None, units=None, a=None,
                  just_return_a=False, warn=True):
    if units is None:
        K = 1
        m = 1
        kg = 1
    else:
        K = units.Kelvin
        m = units.meter
        kg = units.kilogram
    if T is None:
        T = 298.15*K
    m3 = m**3
    if a is None:
        a = (-3.983035*K,  # C
             301.797*K,  # C
             522528.9*K*K,  # C**2
             69.34881*K,  # C
             999.974950*kg/m3)
    if just_return_a:
        return a
    if T0 is None:
        T0 = 273.15*K
    t = T - T0
    if warn and (_any(t < 0*K) or _any(t > 40*K)):
        warnings.warn("Temperature is outside range (0-40 degC)")
    return a[4]*(1-((t + a[0])**2*(t + a[1]))/(a[2]*(t + a[3])))


def celsius_to_kelvin(t_celsius):
    return t_celsius+273.15


def tailwater(h_t, temp_water, p_atm):
    t_water_kelvin = celsius_to_kelvin(temp_water)
    rho = water_density(t_water_kelvin)
    g = gravity
    return (1+(rho*g*h_t)/(2*p_atm))

def tailwater_tdg(q_s,q_p,x, h_t,temp_water,p_atm,tdg_f):
    b1,b2,b3=x
    A = ((q_s+b1*q_s+b3)/(q_s+q_p))
    B = tailwater(h_t, temp_water, p_atm)
    C = ((q_p-b1*q_s-b3)/(q_s+q_p))

    return 100*A*B*b2+tdg_f*C

def q_ge(q_p,q_s,b1,b3):
    return min(q_p,(b1*q_s+b3))


def rmse(y, y_hat):
    return sqrt(mean_squared_error(y,y_hat))

def objective(x):
    y_hat = df.apply(lambda r:tailwater_tdg(q_s=r['q_s'],q_p=r['q_p'],x=x, h_t=r['h_t'],temp_water=r['temp_water'],p_atm=r['p_atm'],tdg_f=r['tdg_f']), axis = 1)
    y = df['tdg_tw']
    return rmse(y, y_hat)

#constraints and bounds for optimization model.  See reference for more information
def constraint_q_ge(x):
    b1,b2,b3=x
    power_flow = df.apply(lambda x:q_ge(x['q_p'],x['q_s'],b1,b3), axis = 1)
    const = power_flow<0
    return -const.sum()

constraints = [{'type':'ineq', 'fun':constraint_q_ge}]          
bounds = [(-500,10000),(.00001,10000),(-500,10000)]
x0=[1,1,1]
sol = minimize(objective, x0, method = 'SLSQP',constraints = constraints, bounds = bounds,options={'disp':True, 'maxiter':100})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...