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

Python for循环递归模型双参数优化:解决scipy.curve_fit拟合失效问题

原有拟合代码的错误点
  • 参数顺序错误:scipy.optimize.curve_fit的入参顺序为curve_fit(模型函数, 自变量, 观测因变量, 初始参数),原代码第一个参数传了模型输出X,完全不符合接口要求。
  • 模型函数逻辑错误:你在Y函数的第一行就写了return,后续循环计算逻辑完全不会执行;且函数内部没有初始化变量X,依赖全局变量会导致迭代优化时计算状态混乱;函数最终也没有返回和观测数据B维度一致的模型输出结果,无法计算拟合残差。
  • 多输出适配问题:curve_fit默认对单输出场景优化,你需要拟合180列的输出结果,强行适配需要做大量维度转换,成本很高。
  • 参数维度不匹配:你定义的a、b是每列对应一个参数值,原代码没有做参数的维度对齐,计算时会出现广播错误。
最优实现方案

这类带自定义递归逻辑、非负约束的参数拟合,优先使用scipy.optimize.least_squares接口,它不需要你适配curve_fit的输入规范,直接自定义残差计算逻辑即可,适配性更强。
完整实现代码示例:

import numpy as np
import pandas as pd
from scipy.optimize import least_squares

# 示例数据准备
A = pd.DataFrame({'col1': [1, 2, 3, 4], 'col2': [3, 4, 5, 6]})
B = pd.DataFrame({'col1': [0, 50, 156, 318], 'col2': [0, 182, 427, 735]})
n_cols = A.shape[1]
n_rows = A.shape[0]

# 定义残差计算函数:输入是扁平化的待优化参数,返回残差数组
def calc_residual(params):
    # 拆分参数:前n_cols个是每列的a,后n_cols个是每列的b
    a = params[:n_cols]
    b = params[n_cols:]
    # 初始化模型输出
    X = np.zeros((n_rows, n_cols))
    for idx in range(1, n_rows):
        delta = a - (b *7 * (1 - A.loc[idx]))
        X[idx] = np.maximum(X[idx-1] - delta, 0)
    # 计算残差:模型输出减观测值,扁平化返回
    return (X - B).values.flatten()

# 初始参数:按 [col1的a, col2的a, col1的b, col2的b] 顺序排列
p0 = [1, 3, 4, 5]
# 可选:给参数加非负约束,避免a、b出现负数
bounds = (0, np.inf)
# 执行优化
res = least_squares(calc_residual, p0, bounds=bounds)

# 提取优化后的参数
opt_params = res.x
opt_a = opt_params[:n_cols]
opt_b = opt_params[n_cols:]
print("优化后各列a值:", opt_a)
print("优化后各列b值:", opt_b)

额外优化建议

  • 若数据量较大,可以用numba给calc_residual函数加JIT编译,大幅提升递归计算速度
  • 如果拟合效果不好,可以调整初始参数p0,或者更换least_squares的优化方法(修改method参数)
  • 如果需要评估拟合效果,可以计算决定系数R²:1 - (残差平方和 / 观测值总平方和)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:24:04