Scipy 矩阵乘法优化

Scipy optimization with matrix multiplication

我试过用spicy.optimize.minimize解决一个矩阵乘法优化问题,但是,结果给我一个维数错误,谁能帮我解决一下?

import numpy as np
from scipy.optimize import minimize

# define known variables, mu, sigma, rf
mu = np.matrix([[0.12], 
                [0.08], 
                [0.05]])

sigma = np.matrix([[0.5, 0.05, 0.03],
                   [0.05, 0.4, 0.01],
                   [0.03, 0.01, 0.2]])

rf = 0.02

def objective_fun(x):
'''
This is the objective function
'''
    s = np.sqrt(x.T * sigma * x)/(mu.T * x - rf)
    return s

def constraint(x):
    con = 1 
    for i in np.arange(0,3):
        con = con - x[i] 
    return con

# set up the boundaries for x
bound_i = (0, np.Inf)
bnds = (bound_i, bound_i, bound_i)

#set up the constraints for x
con = {'type':'eq', 'fun':constraint}

# initial guess for variable x
x = np.matrix([[0.5],
               [0.3],
               [0.2]])

sol = minimize(objective_fun, x, method = 'SLSQP', bounds = bnds, constraints = con)

错误给我:

ValueError                                Traceback (most recent call last)
<ipython-input-31-b8901077b164> in <module>
----> 1 sol = minimize(objective_fun, x, method = 'SLSQP', bounds = bnds, constraints = con)

e:\Anaconda3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    606     elif meth == 'slsqp':
    607         return _minimize_slsqp(fun, x0, args, jac, bounds,
--> 608                                constraints, callback=callback, **options)
    609     elif meth == 'trust-constr':
    610         return _minimize_trustregion_constr(fun, x0, args, jac, hess, hessp,

e:\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, **unknown_options)
    397 
    398             # Compute objective function
--> 399             fx = func(x)
    400             try:
    401                 fx = float(np.asarray(fx))

e:\Anaconda3\lib\site-packages\scipy\optimize\optimize.py in function_wrapper(*wrapper_args)
    324     def function_wrapper(*wrapper_args):
    325         ncalls[0] += 1
--> 326         return function(*(wrapper_args + args))
    327 
    328     return ncalls, function_wrapper

<ipython-input-28-b1fb2386a380> in objective_fun(x)
      3     This is the objective function
      4     '''
----> 5     s = np.sqrt(x.T * sigma * x)/(mu.T * x - rf)
      6     return s

e:\Anaconda3\lib\site-packages\numpy\matrixlib\defmatrix.py in __mul__(self, other)
    218         if isinstance(other, (N.ndarray, list, tuple)) :
    219             # This promotes 1-D vectors to row vectors
--> 220             return N.dot(self, asmatrix(other))
    221         if isscalar(other) or not hasattr(other, '__rmul__') :
    222             return N.dot(self, other)

ValueError: shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)

但是,我写的每一个函数我都单独尝试过,最后都没有错误,比如,如果在代码中定义了x矩阵之后,我只是运行 objective_fun(x)在控制台中,我立即得到了答案:

optimize_fun(x)
matrix([[5.90897598]])

这意味着我的函数可以正确地进行矩阵乘法,那么这里的代码有什么问题吗?

minimize() 的文档说 x0 应该是 (n,) 形状的数组,但您试图将其视为 (3,1) 数组。我不确定 minimize() 的内部工作原理,但我怀疑当它跨过拟合参数的不同值时,它会转换为它认为需要的格式。无论如何,以下小的更正使代码有效。

import numpy as np
from scipy.optimize import minimize

# define known variables, mu, sigma, rf
mu = np.matrix([[0.12], 
                [0.08], 
                [0.05]])

sigma = np.matrix([[0.5, 0.05, 0.03],
                   [0.05, 0.4, 0.01],
                   [0.03, 0.01, 0.2]])

rf = 0.02

def objective_fun(x):
  '''
  This is the objective function
  '''
  x = np.expand_dims(x, 1) # convert the (3,) shape to (3,1). Then we can do our normal matrix math on it
  s = np.sqrt(x.T * sigma * x)/(mu.T * x - rf) # Transposes so the shapes are correct
  return s

def constraint(x):
  con = 1 
  for i in np.arange(0,3):
      con = con - x[i] 
  return con

# set up the boundaries for x
bound_i = (0, np.Inf)
bnds = (bound_i, bound_i, bound_i)

#set up the constraints for x
con = {'type':'eq', 'fun':constraint}

# initial guess for variable x

x = np.array([0.5, 0.3, 0.2]) # Defining the initial guess as an (3,) array)

sol = minimize(objective_fun, x, method = 'SLSQP', bounds = bnds, constraints = con)
print(sol) # and the solution looks reasonable

输出

     fun: 5.86953830952583
     jac: array([-1.70555401, -1.70578796, -1.70573896])
 message: 'Optimization terminated successfully.'
    nfev: 32
     nit: 6
    njev: 6
  status: 0
 success: True
       x: array([0.42809911, 0.29522438, 0.27667651])

查看我添加的评论,了解您需要做什么。