循环内的优化函数和另一个函数
我正在尝试用不同的随机值反复求解最佳值。所以我把最小化的函数放在一个循环和一个函数里面,然后调用这个函数。然而,它总是给我不同的答案。
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()
这是它给出的结果:
正确的答案应该是不同的,因为每次循环都会生成一组新的随机值。如果我去掉这个函数,只用循环,结果就正常了:
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
在循环和另一个函数里面使用最小化函数一定是出了什么问题。
2 个回答
1
问题在于,你在函数 get_opt_x
里面定义了变量 Y
,然后希望在函数 Ln
中也能看到这个变量,但Python不允许这样做。当你去掉 get_opt_x
这个函数时,变量 Y
就可以在全局范围内使用,因此 Ln
函数也能看到它。
你需要在 get_opt_x
的开头告诉Python Y
是一个全局变量:
def get_opt_x():
global Y
1
在函数 get_opt_x()
中的变量 X
和 Y
是局部变量,也就是说它们只在这个函数里面有效,和函数 Ln
中的 X
和 Y
是不一样的。你从 get_opt_x()
得到的结果都是一样的,因为它使用的是你上一次运行循环时的值(通过去掉你的函数来实现的)。为了证明这一点,你可以尝试关闭你的会话,然后先运行第一段代码,再运行第二段代码,你会看到一个错误,提示 X
没有被初始化。
解决办法:
把 X
和 Y
作为额外的参数传递给 minimize
函数。
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()