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

Python非线性curve_fit拟合效果不佳,求参数优化及绘图建议

Python非线性curve_fit拟合优化建议

我来帮你排查这个拟合效果不佳的问题~从你的代码和数据来看,核心问题大概率是curve_fit默认的初始参数和无约束的参数范围导致拟合跑偏,结合你的数据趋势,给你几个具体的优化方案:

1. 给拟合算法设置合理的初始参数(p0)

curve_fit默认会用[1,1,1]作为参数初始值,但你的数据有明显的趋势:当baskets(x值)越大,scaling_factor(y值)越接近90-95的上限,而x很小时y趋近1.4。你的模型a - b*np.exp(c*x)要符合这个趋势的话:

  • a应该是y的渐近上限(约95左右)
  • b应该是a减去最小y值(大概95-1.4≈93)
  • c必须是负数(这样x增大时,exp(c*x)趋近0,y趋近a)

给算法一个接近真实解的起点,能大大提升拟合成功率。

2. 添加参数边界约束(bounds)

为了避免拟合出不符合逻辑的参数(比如c变成正数,导致y随x增大而下降,完全违背你的数据趋势),可以给每个参数设置合理的范围:

  • a:80-100(符合数据的上限区间)
  • b:正数(保证b*exp(c*x)是正数,y不会超过a)
  • c:负数(保证趋势是x增大y趋近a)

3. 优化后的完整代码

import matplotlib
matplotlib.use('Qt4Agg')
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

def func(x, a, b, c):
    return a - b * np.exp(c * x)

# 原始数据
baskets = np.array([475, 108, 2, 38, 320])
scaling_factor = np.array([95.5, 57.7, 1.4, 21.9, 88.8])

# 设置初始参数:贴合数据趋势的初始猜测
p0 = [95, 90, -0.01]
# 设置参数边界:限制参数在合理范围内
bounds = ([80, 1, -np.inf], [100, 100, -0.001])

# 带初始参数和边界的拟合
popt, pcov = curve_fit(func, baskets, scaling_factor, p0=p0, bounds=bounds)
print("优化后的参数:", popt)
print("协方差矩阵:\n", pcov)

# 生成拟合曲线数据(用vectorized调用代替列表推导,更高效)
basket_cont = np.linspace(min(baskets), max(baskets), 50)
fitted_data = func(basket_cont, *popt)

# 美化绘图,增加可读性
fig1 = plt.figure(1)
plt.scatter(baskets, scaling_factor, s=20, label='原始数据点')
plt.plot(basket_cont, fitted_data, 'r-', linewidth=2, label='拟合曲线')
plt.xlabel('Baskets')
plt.ylabel('Scaling Factor')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

额外建议:尝试更匹配的模型

如果调整参数后拟合效果还是不够理想,可以考虑更换模型。你的数据呈现饱和增长的趋势,逻辑斯蒂(Sigmoid)模型可能更贴合:

def sigmoid_func(x, a, b, c):
    # a是饱和上限,b是增长速率,c是中点x值
    return a / (1 + np.exp(-b*(x - c)))

同样给这个模型设置合理的p0和bounds,拟合效果可能会更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:17:25