我在 python 中有一个简单的优化问题,我需要经常重新运行(超过 10,000 次)。
大多数计算可以使用 numpy 完成,并且 n 维数组非常有效,但是,当涉及到优化时,我迷失了方向,因为我必须切换到 scipy.optimize.minimize。
有没有一种方法可以立即运行优化?
目前我正在遍历每一行 - 请参见下面的代码:
#%% imports
import numpy as np
from scipy import optimize
import time
#%% functions
def square(x, a, cov):
return (x-a).dot(cov).dot(x-a)
def minimization(args):
f, x, a, cov, beta, bnds = args
con_beta = {'type': 'eq', 'fun': lambda x, beta: np.sum(x*beta) - 1, 'jac': lambda x, beta: beta, 'args': (beta, ) }
res = optimize.minimize(f, x, bounds=bnds, method='SLSQP', args=(a, cov), constraints = con_beta)
return res.x
#%% initialize data
numberOfRuns = 260 * 100
numberOfAssets = 4
corr = np.ones((numberOfAssets,numberOfAssets))*0.8 + np.eye(numberOfAssets)*0.2
cov = (np.eye(numberOfAssets)*0.15).dot(corr).dot(np.eye(numberOfAssets)*0.15)
mu = np.zeros(numberOfAssets)
cov_n = np.zeros((numberOfRuns, numberOfAssets, numberOfAssets))
bm_n = np.zeros((numberOfRuns, numberOfAssets))
guess_n = np.ones((numberOfRuns, numberOfAssets))/(numberOfAssets-1)
bm_n[:,0] = 1
guess_n[:,0] = 0
bnds = [(0, None) for _ in range(numberOfAssets)]
bnds[0] = (0,0)
for i in range(numberOfRuns):
cov_n[i,:,:] = np.cov(np.random.multivariate_normal(mu, cov/260, 260).T)*260
beta_n = cov_n[:,0,:]/cov_n[:,0,0][:,np.newaxis]
#%% Run 1
tic = time.time()
for i in range(numberOfRuns):
res = minimization((square, guess_n[i,:], bm_n[i,:], cov_n[i,:,:], beta_n[i,:], bnds))
toc= time.time()
tictoc1 = toc - tic
print(tictoc1) #21.678 seconds
#%% Run 2
tic = time.time()
args = [(square, guess_n[i,:], bm_n[i,:], cov_n[i,:,:], bnds) for i in range(numberOfRuns)]
p = Pool(4)
res = p.map(minimization, args)
toc = time.time()
tictoc2 = toc - tic
print(toc - tic) #~11 seconds
#%% The End
有没有更优雅、更有效的方法而不是循环遍历?
PS:我曾尝试使用“Pool”,但这“只是”一半的时间 - 循环仍然存在同样的问题。