使用scipy.optimize.curve_fit进行余弦曲线拟合效果差的原因咨询
余弦函数拟合效果异常问题解决
核心原因
scipy.optimize.curve_fit拟合失效的核心是未传入合理的初始参数:该函数默认所有参数初始值为1,而余弦函数具有周期性,优化过程极易陷入局部最优解,当默认初始值和实际数据的参数偏差过大时,就会出现拟合参数和预期偏差极大的问题。
代码中存在的两个问题
- 没有指定拟合初始参数
p0,完全依赖默认值导致优化偏离正常范围 - 绘制拟合曲线的x区间
np.linspace(-10,10,1000)和csv中x0的实际取值范围可能不匹配,会导致拟合曲线和原始数据错位,进一步放大拟合效果差的观感
修正方案
首先从原始数据估算初始参数,再传入curve_fit即可解决问题,修正后代码如下:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit # 读取数据并转为numpy数组,提高运算效率 df = pd.read_csv('C:/Users/SHYAMA/Downloads/data2.csv') f = np.array(df['x0']) s = np.array(df['x1']) # 手动估算初始参数,大幅提升拟合准确率 s_max, s_min = s.max(), s.min() p0 = [ (s_max - s_min)/2, # a:振幅初始值,取数据峰谷差的一半 2 * np.pi * 2/(f.max() - f.min()), # b:角频率初始值,这里的2可替换为你观测到的原始数据周期数 0, # c:相位初始值,可根据原始数据首个峰值位置微调 (s_max + s_min)/2 # d:竖直偏移量初始值,取数据峰谷的平均值 ] # 定义拟合函数 def func(x,a,b,c,d): return a*np.cos(b*x + c) + d # 拟合时传入初始参数p0 param, error = curve_fit(func, f, s, p0=p0) # 拟合曲线的x范围和原始数据对齐,避免错位 x = np.linspace(f.min(), f.max(), 1000) # 绘图 plt.figure(dpi=100) plt.plot(f, s, label='原始数据') plt.plot(x, func(x, *param), label='拟合曲线') plt.grid() plt.legend() plt.show() print("拟合参数:", param) print("协方差矩阵:", error)
可选优化
如果调整初始参数后仍有偏差,可以给curve_fit添加bounds参数限制各参数的取值范围,比如限制振幅必须为正、角频率在你预估的区间内,进一步避免陷入局部最优。
内容的提问来源于stack exchange,提问作者syamadas
相关产品推荐
相关产品推荐

