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

Scipy.optimize向量约束优化维度不匹配报错排查

问题根因

报错来自三处配置错误,直接触发维度不匹配和逻辑失效:

  • bounds参数长度必须和优化变量w的维度完全匹配:你的权重向量是10维(对应10个资产),但拼接后的bnds包含1个冗余b1、10个权重边界、1个波动率边界,总共12组边界,和变量维度不匹配,触发np.clip广播错误。
  • constraints参数要求传入字典组成的一维列表,你当前定义的cons嵌套了非负约束的子列表,结构不符合scipy接口规范。
  • 逻辑错误:bounds仅用于给单个优化变量设置上下限,你要限制的组合波动率是所有权重的聚合函数,不是独立优化变量,不能写在bounds里;且你原来的波动率约束仅要求方差大于0,未生效传入的波动率上下限参数。
修正要点
  1. 删掉冗余的b1、b3边界配置,仅给10个权重变量设置非负边界即可。
  2. 将cons展平为一维字典列表,补全波动率上下限约束:scipy的ineq类型约束要求函数返回值≥0,因此波动率下限对应w @ varcov @ w.T - lb_vol,上限对应ub_vol - w @ varcov @ w.T。
  3. 循环生成非负约束时显式捕获循环变量i,避免Python闭包特性导致所有约束仅作用于最后一个权重。
  4. 显式指定支持约束和边界的SLSQP求解器,避免scipy默认选用无约束求解器导致结果错误。
修正后可运行代码
import numpy as np
from scipy.optimize import minimize


def main():
    fake_x = np.random.random((60, 10))
    results = solution(fake_x, 0.05, 0.1)
    print(results)


def initial_weights(fund):
    index = np.asarray(fund)
    dim_index = index.shape[1]
    return np.array([1/dim_index]*dim_index)


def objective(w, fund):
    varcov = np.cov(fund, rowvar=False)
    obj_fun = 0.5 * np.log(w @ varcov @ w.T)
    return obj_fun


def solution(x, lb_vol, ub_vol):
    varcov = np.cov(x, rowvar=False)
    w0 = initial_weights(x)
    cons = [
        {"type": "eq", "fun": lambda w: 1 - np.sum(w)},
        *[{"type": "ineq", "fun": lambda w, i=i: w[i]} for i in range(x.shape[1])],
        {"type": "ineq", "fun": lambda w: w @ varcov @ w.T - lb_vol},
        {"type": "ineq", "fun": lambda w: ub_vol - w @ varcov @ w.T}
    ]
    bnds = [(0, None) for _ in range(x.shape[1])]
    res = minimize(objective, w0, bounds=bnds, args=(x,), constraints=cons, method='SLSQP')
    return res


if __name__ == "__main__":
    main()
补充优化

非负约束已经通过bnds实现,不需要重复写在constraints列表里,要简化代码可以直接删掉cons里的非负约束行,运行效果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:30:05