Python 使用scipy进行优化

Python 使用scipy进行优化,python,scipy,Python,Scipy,我正试图建立一个有效的边界,就像马科维茨问题一样。 我已经写了下面的代码,但是我得到了错误“ValueError:Objective function必须返回标量”。我用一些值测试了“乐趣”,例如,我输入到控制台: W = np.ones([n])/n # start optimization with equal weights cov_matrix = returns.cov() fun = 0.5*np.dot(np.dot(W, cov_matrix), W) # var

我正试图建立一个有效的边界,就像马科维茨问题一样。 我已经写了下面的代码,但是我得到了错误“ValueError:Objective function必须返回标量”。我用一些值测试了“乐趣”,例如,我输入到控制台:

W = np.ones([n])/n     # start optimization with equal weights
cov_matrix = returns.cov() 
fun = 0.5*np.dot(np.dot(W, cov_matrix), W)    # variance of the portfolio
fun
输出为0.00015337622774133828,这是一个标量。 我不知道怎么了。感谢您的帮助

代码: 一些数据
这段代码乱七八糟,虽然我可以向您展示一些运行的东西,但这并不意味着什么

您将看到收敛到您的起点,无论这在您的任务中意味着什么!这是一个强有力的指标,表明某些事情仍然非常错误(可能是潜在的理论)

一些补充意见:

  • scipy的优化器是为使用numpy阵列而构建的,而不是熊猫数据帧或系列对象!
    • 原始问题中唯一暗示pandas用法的是一个var名称
      df
      returns.cov()
      ,它不适用于numpy数组
  • 射频从未在任何地方使用过
  • 在optimize的参数中有很多东西没有使用
  • 感觉使用scipy的优化器并不是一个问题!(但这是可能的;例如,我们正在为数字微分支付费用)
    • 如果正确解释问题(分析不多),可能是更好的方法(更干净、更快、更准确)
    • 但同样的规则也适用:需要一些python知识
代码:

输出:

A         B         C
A  0.813375 -0.001370  0.173901
B -0.001370  1.482756  0.380514
C  0.173901  0.380514  1.285936
fun: 0.2604530793556774
jac: array([ 0.32863522,  0.62063321,  0.61345008])
message: 'Optimization terminated successfully.'
nfev: 35
nit: 7
njev: 3
status: 0
success: True
x: array([ 0.33333333,  0.33333333,  0.33333333])

这段代码乱七八糟,虽然我可以向您展示一些运行的东西,但这并不意味着什么

您将看到收敛到您的起点,无论这在您的任务中意味着什么!这是一个强有力的指标,表明某些事情仍然非常错误(可能是潜在的理论)

一些补充意见:

  • scipy的优化器是为使用numpy阵列而构建的,而不是熊猫数据帧或系列对象!
    • 原始问题中唯一暗示pandas用法的是一个var名称
      df
      returns.cov()
      ,它不适用于numpy数组
  • 射频从未在任何地方使用过
  • 在optimize的参数中有很多东西没有使用
  • 感觉使用scipy的优化器并不是一个问题!(但这是可能的;例如,我们正在为数字微分支付费用)
    • 如果正确解释问题(分析不多),可能是更好的方法(更干净、更快、更准确)
    • 但同样的规则也适用:需要一些python知识
代码:

输出:

A         B         C
A  0.813375 -0.001370  0.173901
B -0.001370  1.482756  0.380514
C  0.173901  0.380514  1.285936
fun: 0.2604530793556774
jac: array([ 0.32863522,  0.62063321,  0.61345008])
message: 'Optimization terminated successfully.'
nfev: 35
nit: 7
njev: 3
status: 0
success: True
x: array([ 0.33333333,  0.33333333,  0.33333333])

fun
似乎不是一个函数。它应该是权重W和协方差矩阵cov_矩阵的函数。你确定你没有返回一个带有形状(1)的
np.array
float
的数组吗?@MatteoRagni如果我改为fun=float(0.5*np.dot(np.dot(W,cov_-matrix),W)),我得到了同样的错误。嗯,ma
fun
不是一个可调用的对象!可能这就是问题所在。…
fun
似乎不是一个函数。它应该是权重W和协方差矩阵cov_矩阵的函数。你确定你没有返回一个带有形状(1)的
np.array
float
?@MatteoRagni如果我改为fun=float(0.5*np.dot(np.dot(W,cov_矩阵),W)),我得到了同样的错误。嗯,ma
fun
不是一个可调用的对象!也许这就是问题所在……@MatteoRagni这是一个很难解决的问题。尤其是在人们意识到
np_array.cov()
不存在之前。进一步查看结果,我意识到尽管输出了一个结果,但代码并没有优化任何东西。无论我选择输入什么作为初始权重,都将是权重的最终结果,“乐趣”正是输入这些值时的目标函数。这是我首先告诉你的。我回答的第二句话很重要,没有一个明确的问题陈述(问题的理论),没有什么帮助。@MatteoRagni这是一个很难解决的问题。尤其是在人们意识到
np_array.cov()
不存在之前。进一步查看结果,我意识到尽管输出了一个结果,但代码并没有优化任何东西。无论我选择输入什么作为初始权重,都将是权重的最终结果,“乐趣”正是输入这些值时的目标函数。这是我首先告诉你的。我回答的第二句话很重要,如果没有明确的问题陈述(问题的理论),就没有什么帮助。
from scipy.optimize import minimize
import numpy as np
import pandas as pd

rf = 0.05
r_bar = 0.05
returns = pd.DataFrame(np.random.randn(30, 3), columns=list('ABC'))  # PANDAS DF
cov_matrix = returns.cov().as_matrix()                               # use PANDAS one last time
                                                                     # but result = np.array!
returns = returns.as_matrix()                                        # From now on: np-only!

def fun(x, returns, cov_matrix, rf):
    return 0.5*np.dot(np.dot(x, cov_matrix), x)

def efficient_frontier(rf, r_bar, returns):
    n = len(returns.transpose())
    W = np.ones([n])/n     # start optimization with equal weights
    exp_ret = returns.mean()

    cons = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1. },         # let's use numpy here
         {'type': 'ineq', 'fun': lambda x: np.dot(exp_ret, x) - r_bar })

    bnds = [(0.,1.) for i in range(n)]    # weights between 0..1.

    res = minimize(fun, W, (returns, cov_matrix, rf),
                method='SLSQP', bounds = bnds, constraints = cons)
    return res

x= efficient_frontier(rf,r_bar,returns)
print(x)
A         B         C
A  0.813375 -0.001370  0.173901
B -0.001370  1.482756  0.380514
C  0.173901  0.380514  1.285936
fun: 0.2604530793556774
jac: array([ 0.32863522,  0.62063321,  0.61345008])
message: 'Optimization terminated successfully.'
nfev: 35
nit: 7
njev: 3
status: 0
success: True
x: array([ 0.33333333,  0.33333333,  0.33333333])