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

如何在Python中编写用于scipy.optimize.least_squares的误差函数

非线性拟合优化指南(针对你的代码场景)

看来你在非线性拟合调优上遇到了瓶颈,我结合你给出的代码片段和实际拟合中常见的问题,给你梳理几个能快速提升拟合效果的方向:

先把你的代码补全示意(方便后续操作)

你的温度数据有截断,我先补全常见的后续值,同时补上目标数据的占位,你替换成自己的实际数据即可:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import least_squares
from scipy.optimize import curve_fit

# 补全后的温度数据(根据截断部分推测)
temperature = [38., 40., 42., 44., 46., 48., 50., 52., 54., 56., 58., 60., 62., 64., 66., 68., 70., 71.9, 73.81, 75.69, 77.6, 79.5, 81.4]
# 替换成你的实际目标测量数据
y_data = []  

一、先确保模型函数匹配数据的内在规律

非线性拟合的核心从来不是调参数,而是选对模型!如果你的模型和数据趋势完全不搭,再怎么调都没用:

  • 第一步先画原始数据的散点图,看清趋势:
    plt.scatter(temperature, y_data, color='darkorange', label='Raw Data')
    plt.xlabel('Temperature (°C)')
    plt.ylabel('Measured Value')
    plt.legend()
    plt.grid(alpha=0.3)
    plt.show()
    
  • 根据散点趋势选对应的模型:
    • 如果是指数上升/下降:用Arrhenius类模型 def model(x, a, b): return a * np.exp(b * x)
    • 如果是饱和增长/下降:用Logistic模型 def model(x, a, b, c): return a / (1 + np.exp(-b*(x - c)))
    • 如果是有拐点的曲线:用二次/三次多项式 def model(x, a, b, c): return a*np.power(x,2) + b*x + c

二、给拟合参数一个靠谱的初始猜测

curve_fit和least_squares对初始参数非常敏感,瞎猜初始值很容易陷入局部最优:

  • 手动根据数据估算初始值:比如饱和模型里,a大概是数据的渐近最大值/最小值,c大概是拐点对应的温度,b是斜率的大致范围
  • 示例(以饱和模型为例):
    # 手动估算初始参数p0
    p0 = [max(y_data), 0.1, np.median(temperature)]  # 渐近值、斜率、拐点温度
    # 执行拟合
    popt, pcov = curve_fit(model, temperature, y_data, p0=p0)
    

三、用least_squares实现更灵活的拟合(可选)

如果你需要给参数加约束(比如参数必须为正),least_squares比curve_fit更实用:

# 自定义残差函数
def residuals(params, x, y):
    a, b, c = params
    return y - model(x, a, b, c)

# 初始参数
x0 = [max(y_data), 0.1, np.median(temperature)]
# 设置参数边界:比如a必须大于0,b必须大于0,c在温度范围内
bounds = ([0, 0, min(temperature)], [np.inf, np.inf, max(temperature)])
# 执行带约束的拟合
result = least_squares(residuals, x0, args=(temperature, y_data), bounds=bounds)
popt = result.x  # 拟合得到的最优参数

四、用量化指标评估拟合效果

别只靠眼睛看,用指标说话:

  • 均方误差(MSE):值越小越好
    mse = np.mean((model(temperature, *popt) - y_data)**2)
    
  • 决定系数R²:越接近1,拟合效果越好
    ss_res = np.sum((y_data - model(temperature, *popt))**2)
    ss_tot = np.sum((y_data - np.mean(y_data))**2)
    r2 = 1 - (ss_res / ss_tot)
    

五、常见坑点排查

如果拟合结果还是很差,先检查这几点:

  • 数据里有没有异常值?用3σ原则剔除掉偏离过大的点
  • 模型是不是完全不符合数据趋势?比如数据是饱和的,但你用了线性模型
  • 参数约束是不是太严?如果拟合后的参数卡在边界上,说明约束可能不合理或者初始值选得太差

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:21:56