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

如何用scipy.optimize的LinearConstraint实现目标函数概率约束?

问题描述

现有一段实现Kelly-ECC方法的优化代码,希望添加一个约束:在概率分布p中至少(1-x)比例的场景下,对应场景的负对数收益项低于y,即约束形式为:

P[y ≥ -log(1 + r·f)] ≥ (1 - x)

原代码如下:

import random
import numpy as np
from scipy.optimize import minimize, LinearConstraint
random.seed(123)


# assumptions
d = np.array([1.3,  10])
p = np.array([random.randint(700, 950) / 1000 for _ in range(100)])


scenarios = np.array([[1],
                      [0]])
r = scenarios * d - 1           # returns per scenario


def obj(f):
    return -1 * np.sum(p * np.log(np.sum(1 + r * f, axis=1))[:, None])


f0 = [0, 0]
constr_1 = LinearConstraint(np.ones((1, 2)), lb=0, ub=1)
constr_2 = LinearConstraint(np.eye(2), lb=0, ub=1)
constraints = [constr_1, constr_2]
res = minimize(fun=obj, x0=f0, method='trust-constr', constraints=constraints)
print(res.x)

请问如何创建对应的约束?


解决方案

1. 约束转化为线性形式

你要求的约束可以转化为线性形式,从而用LinearConstraint实现:
原约束要求至少(1-x)概率的场景满足:
$$y \geq -\log(1 + r_i \cdot f)$$
对两边取指数并整理,得到等价的线性约束:
$$r_i \cdot f \geq e^{-y} - 1$$
其中$r_i \cdot f$是关于仓位$f$的线性表达式,完全符合LinearConstraint的要求。

2. 实现步骤

要保证满足约束的场景概率总和≥(1-x),我们可以筛选出概率最大的一批场景,强制它们满足上述线性约束:

  • 设定参数x和y(比如x=0.1表示至少90%概率的场景需满足条件)
  • 将场景按概率p从大到小排序,累加概率直到总和≥(1-x),筛选出这些高概率场景
  • 对每个筛选出的场景,添加对应的线性约束

3. 修改后的完整代码

import random
import numpy as np
from scipy.optimize import minimize, LinearConstraint
random.seed(123)

# assumptions
d = np.array([1.3, 10])
p = np.array([random.randint(700, 950) / 1000 for _ in range(100)])
scenarios = np.array([[1], [0]])
r = scenarios * d - 1  # returns per scenario

# 设定约束参数:x=0.1 表示至少90%概率的场景满足条件,y=0.5
x = 0.1
y = 0.5
target_prob = 1 - x
C = np.exp(-y) - 1  # 线性约束的下界

def obj(f):
    return -1 * np.sum(p * np.log(np.sum(1 + r * f, axis=1))[:, None])

f0 = [0, 0]
# 原有约束:仓位总和0-1,单个仓位0-1
constr_1 = LinearConstraint(np.ones((1, 2)), lb=0, ub=1)
constr_2 = LinearConstraint(np.eye(2), lb=0, ub=1)
constraints = [constr_1, constr_2]

# 添加新约束:筛选高概率场景并添加线性约束
# 按概率降序排序场景的索引
sorted_indices = np.argsort(p)[::-1]
cum_prob = 0.0
selected_indices = []
for idx in sorted_indices:
    cum_prob += p[idx]
    selected_indices.append(idx)
    if cum_prob >= target_prob:
        break

# 对每个选中的场景添加线性约束 r_i·f >= C
for idx in selected_indices:
    # 将场景收益向量转为(1,2)格式适配LinearConstraint
    constr = LinearConstraint(r[idx].reshape(1, -1), lb=C, ub=np.inf)
    constraints.append(constr)

# 执行优化
res = minimize(fun=obj, x0=f0, method='trust-constr', constraints=constraints)
print(res.x)

说明

  • 这种方法通过约束高概率场景满足条件,间接保证整体概率≥(1-x),是处理这类概率约束的常用近似手段
  • 如果需要更严格的概率约束,可改用NonlinearConstraint直接定义概率约束,但会增加优化的计算复杂度和难度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:20:19