I'm trying to use scipy.optimize.minimize to do simulated method of moments estimation.
Here is my code:
import numpy as np
from scipy.optimize import minimize
import matplotlib as plt
n = 10000
c = np.tile(np.random.normal(size=(n,1)),(1,2))
k = np.random.normal(size=(n,2))
def generate_moments(params,c,k):
mu = params[0]
sigma = params[1]
util = mu + (sigma*c) + k
choice = util > 0
#a = np.zeros((2,1))
#a[0,0] = np.mean(choice[choice[:,0]==0,1])
#a[1,0] = np.mean(choice[choice[:,0]==1,1])
#return a
return (np.mean(choice[choice[:,0]==0,1]),np.mean(choice[choice[:,0]==1,1]))
#moments: p(choice|prior not-choice) = .07; p(choice|prior choice) = .35
def SMM_obj(params,W,c,k):
sim_moments = generate_moments(params,c,k)
diff = sim_moments - np.array([0.07,0.35])
return np.matmul(np.matmul(diff,W),diff)
W = np.identity(2)
estimates = minimize(SMM_obj,[0,1],args=(W,c,k),options={'disp':True})
But the output I get is:
Optimization terminated successfully.
Current function value: 0.167197
Iterations: 0
Function evaluations: 4
Gradient evaluations: 1
estimates
Out[108]:
fun: 0.16719656582010595
hess_inv: array([[1, 0],
[0, 1]])
jac: array([0., 0.])
message: 'Optimization terminated successfully.'
nfev: 4
nit: 0
njev: 1
status: 0
success: True
x: array([0., 1.])
Where minimize has stopped immediately and spit out my x0.
One thing I was worried about was that my objective function isn't smooth (as mentioned in prior threads like this: Scipy Optimize is only returning x0, only completing one iteration)
However, I tested that in the following way:
mu_values = np.linspace(-3,3,500)
y_values = np.zeros_like(mu_values)
for i in range(len(mu_values)):
mu = mu_values[i]
params = [mu,1]
y = obj(params,W,c,k)
y_values[i] = y
plt.pyplot.scatter(mu_values,y_values)
sigma_values = np.linspace(0,5,500)
y_values = np.zeros_like(sigma_values)
for i in range(len(sigma_values)):
sigma = sigma_values[i]
params = [0,sigma]
y = obj(params,W,c,k)
y_values[i] = y
plt.pyplot.scatter(sigma_values,y_values)
Producing the following (pretty smooth-looking) figures, showing that (0,1) is clearly not the optimum:
Any thoughts on how to diagnose the problem here?