Python中scipy curve_fit正弦曲线拟合不匹配问题求解
问题原因
拟合失败核心是两个问题:
- 模型和数据趋势完全不匹配:你用的
a * np.sin(b * x)是无偏移的正弦周期函数,输出值只会在[-a,a]之间来回振荡,但你的原始数据在x从0.3到2.88的区间里,y从20.93单调上涨到104.52,全程没有振荡特征,增长速度还越来越快,和正弦函数的形态完全对不上,硬套肯定拟合不准。 - 调用
curve_fit时没有传初始参数猜测值,非线性拟合默认从参数全1的位置开始迭代,很容易卡在局部最优解,进一步放大拟合偏差。
修复方案
- 先更换匹配数据趋势的模型:你的数据是单调递增、斜率逐渐变大的形态,优先选幂函数或者二次多项式做拟合,不要硬套正弦函数。
- 调用
curve_fit时传入合理的初始参数p0,降低落到局部最优的概率;如果要画平滑的拟合曲线,不要只用原始的离散x点计算拟合值,要在x的取值范围内生成密集的等距点再计算。
修改后的可运行参考代码:
import numpy as np from scipy.optimize import curve_fit from matplotlib import pyplot as plt # 原始数据 c = [0.3, 0.5, 1, 1.2, 2.1, 2.5 ,2.88 ] d = [20.93, 25.03, 35.75, 40.37, 66.32, 81.41, 104.52 ] x = np.array(c) y = np.array(d) # 更换为幂函数模型,匹配单调上升、增速变快的趋势 def test(x, a, b, c): return a * np.power(x, b) + c # 传入合理初始参数做拟合 param, param_cov = curve_fit(test, x, y, p0=[10, 1.5, 10]) print("拟合函数系数:") print(param) print("系数协方差:") print(param_cov) # 生成密集x点绘制平滑拟合曲线 x_fit = np.linspace(x.min(), x.max(), 100) y_fit = test(x_fit, *param) plt.plot(x, y, 'o', color ='red', label ="原始数据") plt.plot(x_fit, y_fit, '--', color ='blue', label ="拟合曲线") plt.legend() plt.show()
补充说明:如果你是基于特定业务/理论要求必须用正弦函数拟合,那你现在用的双参数无偏移正弦模型是错的——你采集的数据只覆盖了正弦曲线上升沿的一小段,必须给正弦模型加偏移量和相位参数,即模型改为
a * np.sin(b * x + c) + d,同时给参数设置符合物理意义的取值边界bounds,避免拟合出无意义的参数结果。
内容的提问来源于stack exchange,提问作者altan665
相关产品推荐
相关产品推荐

