You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python计算最小方差?Pyomo建模求解问题求助

问题分析与修复方案

核心问题

  1. 协方差矩阵索引不匹配
    你定义的资产名称是a1到a59,但协方差矩阵Cov的行/列索引是默认的0-58(因df为59列),直接用资产名称索引会触发KeyError。

  2. Param规则函数参数错误
    Pyomo的Param规则函数必须以model作为第一个参数,你的get_covariance参数顺序不符合要求,无法正确加载协方差值。

  3. 目标函数语法冗余
    双重嵌套生成器可以简化为单层循环,避免语法歧义。

  4. 未使用的二进制变量
    定义了model.v但未添加任何相关约束,属于冗余代码,要么删除要么补充约束(比如限制选中资产数量)。

修复后的代码

!pip install pyomo
!wget -N -q "https://ampl.com/dl/open/ipopt/ipopt-linux64.zip"
!unzip -o -q ipopt-linux64
!apt-get install -y -qq glpk-utils

import pandas as pd
import numpy as np
from pyomo.environ import *
from pyomo.opt import SolverFactory

# 生成与协方差矩阵索引匹配的资产名称
assets = [str(i) for i in range(59)]  # 对应df的0-58列索引
df = pd.DataFrame(np.random.randint(0,10,size=(36, 59)))
Cov = df.cov()

# 修正Param规则函数:第一个参数为model,后接索引i,j
def get_covariance(model, i, j):
    return Cov.loc[int(i), int(j)]  

model = ConcreteModel()
model.i = Set(initialize=assets)
model.w = Var(model.i, within=NonNegativeReals)  # 非负权重(无卖空)
model.cov = Param(model.i, model.i, rule=get_covariance, doc='covariance')

# 简化目标函数:最小化投资组合方差
model.objective = Objective(expr=sum(model.w[i] * model.w[j] * model.cov[i,j] 
                                     for i in model.i for j in model.i), 
                           sense=minimize)  

# 权重和为1的约束
model.Const1 = Constraint(expr=sum(model.w[i] for i in model.i) == 1)

# 调用IPOPT求解,打开tee=True查看求解过程
solver = SolverFactory('ipopt', executable='/content/ipopt')
results = solver.solve(model, tee=True)

# 输出求解结果
print("求解状态:", results.solver.status)
print("最优目标值(最小方差):", model.objective())
print("最优权重(忽略极小值):")
for i in model.i:
    if model.w[i].value > 1e-6:
        print(f"资产{i}: {model.w[i].value:.4f}")

额外说明

  • 如果需要构建稀疏投资组合(限制选中资产数量),可补充以下约束(示例为最多选10个资产):
    model.v = Var(model.i, domain=Binary)
    # 权重>0时必须选中对应资产
    def invest_rule(model, i):
        return model.w[i] <= model.v[i]
    model.invest_constr = Constraint(model.i, rule=invest_rule)
    # 限制选中资产总数
    model.asset_limit = Constraint(expr=sum(model.v[i] for i in model.i) <= 10)
    
  • 无卖空约束下的最小方差解,本质是将全部权重分配给单一方差最小的资产,求解器结果会与该解析解一致。

内容的提问来源于stack exchange,提问作者Reza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 08:38:49