0

I'm trying to solve for optimal values repeatedly with different random values. So the minimize function is included inside a loop and a function, then I call that function. However, it always gives me different answer.

import numpy as np
from scipy.optimize import minimize
def Ln(theta): # Every loop tries to minimize this value
    error = Y - np.maximum(0, theta[0] + X.dot(theta[1:]))
    error_total = np.absolute(error).sum()
    return error_total
theta_true = np.array([-6,3,3,3])
Y = np.array(10)
def get_opt_x():
    for i in range(10):
        X = np.random.standard_normal([10,3]) # generate random values
        u = X[:,0]**2*np.random.standard_normal(10)
        Y_star = theta_true[0] + X.dot(theta_true[1:]) + u
        Y = np.maximum(0, Y_star)
        theta0 = np.ones(4)
        result = minimize(Ln, theta0, method='BFGS')
        print result.x
    return 
get_opt_x()

This is what it gives:

enter image description here

The correct answer is supposed to be different, since for every loop, a new set of random values are generated. If I get rid of the function, and just do the loop everything works fine:

for i in range(10):
    X = np.random.standard_normal([10,3])
    u = X[:,0]**2*np.random.standard_normal(10)
    Y_star = theta_true[0] + X.dot(theta_true[1:]) + u
    Y = np.maximum(0, Y_star)
    theta0 = np.ones(4)
    result = minimize(Ln, theta0, method='BFGS')
    print result.x

enter image description here

There must be something wrong with using minimize function inside a loop and another function.

2 Answers 2

1

Variable X and Y within get_opt_x() are local to get_opt_x() and are different from X and Y in function Ln. The results from get_opt_x() are all the same because it is using the values from the last loop u ran (by getting rid of your function). To prove that try closing your session and run your first block of code before running the second block, you'll get an error saying X is not initialized.

Solution: pass X and Y as extra arguments to the minimize routine

def Ln(theta, X, Y): # Every loop tries to minimize this value
    error = Y - np.maximum(0, theta[0] + X.dot(theta[1:]))
    error_total = np.absolute(error).sum()
    return error_total

theta_true = np.array([-6,3,3,3])
Y = np.array(10)

def get_opt_x():
    for i in range(10):
        X = np.random.standard_normal([10,3]) # generate random values
        u = X[:,0]**2*np.random.standard_normal(10)
        Y_star = theta_true[0] + X.dot(theta_true[1:]) + u
        Y = np.maximum(0, Y_star)
        theta0 = np.ones(4)
        result = minimize(Ln, theta0, (X, Y), method='BFGS')
        print result.x
    return 

get_opt_x()
Sign up to request clarification or add additional context in comments.

Comments

1

The problem is that you're defining the variable Y inside the function get_opt_x and then expecting it to be visible to the function Ln, which Python disallows. When you remove the get_opt_x function, the value Y is then available in the global scope and thus visible to the Ln function.

You need to tell Python that Y is a global variable at the beginning of get_opt_x:

def get_opt_x():
    global Y

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.