Scipy Minimize Ignores the Constraints
I want to estimate the parameters of a model using maximum-likelihood method. The model has 6 parameters A, n, B, w1, w2, and w3 and I know that the true values of them are 180, 0.5, 1.5, 0.35, 0.45, and 0.2, respectively. w1, w2, and w3 should be between 0 and 1; Also, w1+w2+w3=1. I added a constraint for the sum of w1, w2, and w3 but the code just ignores my constraint. can anyone please help me? Here is my dataset and below is my code.
from scipy.optimize import minimize
import numpy as np
n1 = df['drops']
def MLE(params):
SI=10
B = params[0]
A = params[1]
n = params[2]
w1 = params[3]
w2 = params[4]
w3 = params[5]
F=df['failure']
SI1=w1*df['SIs1']+w2*df['SIs2']+w3*df['SIs3']
nu=n1*(SI1/SI)**n
PDF = (B*nu**(B-1))/(A*SI**-n)**B
R = np.exp(-(nu/(A*SI**-n))**B)
logLik = np.log ((PDF**F)*R)
return(-sum(logLik[:]))
start_pos = [1.5, 130, 0.20,0.3, 0.4, 0.2]
bnds = [(1,4), (100, 300), (0.2, 1),(0,1),(0,1),(0,1)]
cons = ({'type': 'eq','fun' : lambda params: np.array([params[3]+params[4]+params[5]-1])})
results = minimize(MLE, start_pos, method='L-BFGS-B', constraints=cons, bounds=bnds)
print(str("B="+str(round(results.x[0],2))+", A="+str(round(results.x[1],2))+",
n="+str(round(results.x[2],2))+", w1="+str(round(results.x[3],2))+", w2="+str(round(results.x[4],2))+", w3="+str(round(results.x[5],2))))
Solution 1:
The L-BFGS-B method doesn't support general constraints, it only supports simple bounds on the variables, so your code should usually raise a warning. You can use the SLSQP
or trust-constr
method instead. Note also that SLSQP
is chosen automatically if you don't provide a method and your problem has bounds and constraints.