【问题标题】:Scipy optimization with matrix multiplication使用矩阵乘法进行 Scipy 优化
【发布时间】:2019-10-08 01:19:46
【问题描述】:

我尝试使用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]])

也就是说我的函数可以正确地做矩阵乘法,那么这里的代码有什么问题呢?

【问题讨论】:

  • 始终包含完整的 Traceback
  • 这部分x.T * sigma * x 是(尺寸)[(1,3) x (3,3) x (1,3)] 从左到右产生 (1,3) x ( 3,3) >> (1,3) 现在它尝试将 (1,3) 乘以 (1,3)

标签: python-3.x scipy-optimize


【解决方案1】:

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])

查看我输入的 cmets,了解您需要做什么。

【讨论】:

    猜你喜欢
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    相关资源
    最近更新 更多