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

Python中带响应变量Y范围约束的最小二乘拟合问题

带预测值区间约束的二维多项式最小二乘拟合实现

问题分析

你的问题属于带线性不等式约束的最小二乘问题:目标是最小化残差的2-范数,同时要求预测值Xb落在正区间(c1, c2)内。无约束的scipy.linalg.lstsq无法处理这类约束,需要使用支持约束优化的工具。

可行实现方案

主流Python生态中,scipy.optimize模块提供了两种直接可行的方法:

方法1:使用scipy.optimize.lsq_linear(推荐)

lsq_linear是专门为线性最小二乘问题设计的约束优化函数,支持线性等式/不等式约束,效率远高于通用优化器。

适配你的代码的修改示例:

首先导入模块:

from scipy.optimize import lsq_linear

替换原代码中lstsq的部分:

# --- 原无约束拟合代码替换为以下内容 ---
n_variables = A.shape[1]
# 区分原样本数据和正则化拼接部分(如果启用了正则化)
n_samples_original = len(z) - n_variables if self.lambd != 0 else len(z)
X_original = A[:n_samples_original]  # 对应原设计矩阵X

# 构造约束:每个样本的预测值Xb需满足 c1 < Xb < c2
# 注:lsq_linear处理闭区间,若需要严格开区间,可给c1加微小增量、c2减微小增量(如±1e-8)
lb = c1 * np.ones(n_samples_original)
ub = c2 * np.ones(n_samples_original)

# 定义约束:X_original @ b >= lb 且 X_original @ b <= ub
constraints = {
    'type': 'ineq',
    'A': X_original,
    'lb': lb,
    'ub': ub
}

# 执行约束最小二乘拟合
result = lsq_linear(
    A, z,
    bounds=(None, None),  # 参数b无额外约束(若需要可自行添加)
    constraints=constraints,
    lsq_solver='lsmr',  # 适合大规模问题的求解器
    verbose=0  # 可设置为1查看迭代过程
)

# 获取结果
C = result.x
residuals = result.cost * 2  # cost是残差平方和的一半,乘以2得到完整平方和
# --- 替换结束 ---

方法2:使用scipy.optimize.minimize(通用方案)

如果需要更灵活的约束定义(比如后续扩展非线性约束),可以用通用优化器minimize配合SLSQP方法(支持线性/非线性约束)。

适配代码示例:

导入模块:

from scipy.optimize import minimize

替换原lstsq部分:

# --- 原无约束拟合代码替换为以下内容 ---
n_variables = A.shape[1]
n_samples_original = len(z) - n_variables if self.lambd != 0 else len(z)
X_original = A[:n_samples_original]

# 定义目标函数:残差平方和
def objective(b):
    return np.sum((A @ b - z) ** 2)

# 定义约束:Xb > c1 和 Xb < c2(转为不等式约束形式,加微小偏移避免严格等于)
constraints = [
    {'type': 'ineq', 'fun': lambda b: X_original @ b - (c1 + 1e-8)},
    {'type': 'ineq', 'fun': lambda b: (c2 - 1e-8) - X_original @ b}
]

# 用无约束解作为初始猜测,加速收敛
initial_guess = lstsq(A, z)[0]

# 执行优化
result = minimize(
    objective,
    initial_guess,
    method='SLSQP',
    constraints=constraints,
    options={'maxiter': 1000, 'disp': False}
)

# 获取结果
C = result.x
residuals = result.fun
# --- 替换结束 ---

关键注意事项

  • 正则化兼容:两种方法都能直接适配你原代码中的Tikhonov正则化(拼接sqrt(lambda)*I和零向量的操作),无需额外修改。
  • 数值稳定性:保留原代码中的坐标缩放逻辑(scale参数),避免高次多项式导致的数值溢出问题。
  • 严格区间处理:由于优化器通常处理闭区间约束,若需要严格开区间c1 < Xb < c2,可以给c1加微小增量、c2减微小增量(如±1e-8)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 14:55:59