
本文针对摆锤运动实验中因手抖导致的数据噪声大、拟合曲线严重偏离实测数据的问题,系统讲解如何通过引入直流偏移项、合理初始化参数、预处理数据及验证拟合质量来显著提升余弦函数拟合的准确性。
本文针对摆锤运动实验中因手抖导致的数据噪声大、拟合曲线严重偏离实测数据的问题,系统讲解如何通过引入直流偏移项、合理初始化参数、预处理数据及验证拟合质量来显著提升余弦函数拟合的准确性。
在分析摆锤视频追踪数据时,原始拟合(amplitude * cos(frequency * t))严重偏低,根本原因在于模型缺失关键物理自由度——垂直方向的系统性偏移(DC offset)。真实实验中,摄像头安装高度、坐标系原点设定或软件标定误差,常导致整个轨迹沿 y 轴整体上移或下移。若强行用无偏移的纯余弦函数拟合,优化器只能“妥协”于牺牲振幅和相位来最小化残差,最终造成拟合曲线整体塌陷(如您图中远低于数据的趋势)。
✅ 正确做法是采用带偏移的完整谐波模型:
def cos_func(times, amplitude, frequency, offset):
return amplitude * np.cos(frequency * times) + offset
该模型含 3 个物理可解释参数:振幅(A)、角频率(ω = 2πf)、以及最关键的零点偏移(offset)。它能独立调节拟合曲线的垂直位置,避免振幅被错误压缩。
? 关键改进步骤:
-
科学初始化参数(非猜测)
initial_amplitude = (np.max(x) - np.min(x)) / 2.0 # 峰峰值一半(鲁棒估计) initial_frequency = 2 * np.pi / np.mean(np.diff(t[x > np.median(x)])) # 粗略周期估算(推荐用FFT更准) initial_offset = np.mean(x) # 直接用数据均值作为offset初值(最合理!) p0 = (initial_amplitude, initial_frequency, initial_offset)
-
务必添加数据预处理(必须!)
手抖引入高频噪声会严重干扰 curve_fit。在拟合前进行轻量平滑:from scipy.signal import savgol_filter x_smooth = savgol_filter(x, window_length=51, polyorder=3) # 自适应窗口,抑制抖动不扭曲周期 popt, pcov = curve_fit(cos_func, t, x_smooth, p0=p0)
-
验证拟合合理性
拟合后检查协方差矩阵对角元(np.sqrt(np.diag(pcov)))是否远小于对应参数值(表明收敛可靠),并绘制残差图:residuals = x - cos_func(t, *popt) plt.figure(figsize=(10,4)) plt.subplot(1,2,1); plt.plot(t, x, 'o', ms=1, label='Data'); plt.plot(t, cos_func(t,*popt), '-', lw=2, label='Fit'); plt.legend() plt.subplot(1,2,2); plt.plot(t, residuals, '.'); plt.axhline(0, c='r', ls='--'); plt.title('Residuals')
⚠️ 注意:您代码中手动修改 popt[2] += shift * initial_frequency 是危险操作——curve_fit 已自动优化相位,人为干预会破坏最优解;且 shift 的物理意义不明,应删除。相位(phase)仅在需要显式建模初相角(如 cos(ωt + φ))时引入,而本例中 offset 已解决核心偏移问题,三参数模型更稳定、更易收敛。
总结:拟合失效往往源于模型欠定(missing term),而非算法问题。加入 + offset 是解决“拟合整体偏低”的黄金准则;辅以平滑预处理与物理驱动的初值,即可获得高精度、可解释的摆锤运动参数(如精确周期 T = 2π/ω)。










