Python 使用scipy进行优化
我正试图建立一个有效的边界,就像马科维茨问题一样。 我已经写了下面的代码,但是我得到了错误“ValueError:Objective function必须返回标量”。我用一些值测试了“乐趣”,例如,我输入到控制台: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
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
,它不适用于numpy数组李>returns.cov()
- 原始问题中唯一暗示pandas用法的是一个var名称
- 射频从未在任何地方使用过李>
- 在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
,它不适用于numpy数组李>returns.cov()
- 原始问题中唯一暗示pandas用法的是一个var名称
- 射频从未在任何地方使用过李>
- 在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)),我得到了同样的错误。嗯,mafun
不是一个可调用的对象!可能这就是问题所在。…fun
似乎不是一个函数。它应该是权重W和协方差矩阵cov_矩阵的函数。你确定你没有返回一个带有形状(1)的np.array
,float
?@MatteoRagni如果我改为fun=float(0.5*np.dot(np.dot(W,cov_矩阵),W)),我得到了同样的错误。嗯,mafun
不是一个可调用的对象!也许这就是问题所在……@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])