如何为时间-强度数据集拟合最优高斯曲线?
问题描述
我有一组特定频率下的时间-强度数据集,x轴为numpy数组格式的时间数据,y轴为强度数组,具体数据如下:
time = [ 0.3 1.3 2.3 3.3 4.3 5.3 6.3 7.3 8.3 9.3 10.3 11.3 12.3 13.3 14.3 15.3 16.3 17.3 18.3 19.3 20.3 21.3 22.3 23.3 24.3 25.3 26.3 27.3 28.3 29.3 30.3 31.3 32.3 33.3 34.3 35.3 36.3 37.3 38.3 39.3 40.3 41.3 42.3 43.3 44.3 45.3 46.3 47.3 48.3 49.3 50.3 51.3 52.3 53.3 54.3 55.3 56.3 57.3 58.3 59.3] intensity = [1.03587, 1.03187, 1.03561, 1.02893, 1.04659, 1.03633, 1.0481 , 1.04156, 1.02164, 1.02741, 1.02675, 1.03651, 1.03713, 1.0252 , 1.02853, 1.0378 , 1.04374, 1.01427, 1.0387 , 1.03389, 1.03148, 1.04334, 1.042 , 1.04154, 1.0161 , 1.0469 , 1.03152, 1.22406, 5.4362 , 7.92132, 6.50259, 4.7227 , 3.32571, 2.46484, 1.74615, 1.51446, 1.2711 , 1.15098, 1.09623, 1.0697 , 1.06085, 1.05837, 1.04151, 1.0358 , 1.03574, 1.05095, 1.03382, 1.04629, 1.03636, 1.03219, 1.03555, 1.02886, 1.04652, 1.02617, 1.04363, 1.03591, 1.04199, 1.03726, 1.03246, 1.0408 ]
我用matplotlib绘制该数据集的图像,代码如下:
plt.figure(figsize=(15,6)) plt.title('Single frequency graph at 636 kHz', fontsize=18) plt.plot(time,intensity) plt.xticks(time[::3], fontsize=12) plt.yticks(fontsize=12) plt.xlabel('Elapsed time (minutes:seconds)', fontsize=18) plt.ylabel('Intensity at 1020 kHz', fontsize=18) plt.savefig('WIND_Single_frequency_graph_1020_kHz') plt.show()
图像显示数据呈现高斯分布特征,但我用以下代码拟合高斯曲线时效果很差:
def Gauss(x, A, B): y = A*np.exp(-1*B*x**2) return y parameters, covariance = curve_fit(Gauss, time, intensity_636) fit_A = parameters[0] fit_B = parameters[1] fit_y = Gauss(time, fit_A, fit_B) plt.figure(figsize=(15,6)) plt.plot(time, intensity, 'o', label = 'data') plt.plot(time, fit_y, '-', label ='fit') plt.legend()
请问我哪里出错了?如何让拟合曲线更好地匹配数据?
问题分析与解决方法
1. 高斯函数模型不匹配
你使用的高斯函数 A*np.exp(-1*B*x**2) 是以x=0为中心的对称分布,但你的数据峰值明显出现在x≈29.3的位置,模型中心位置完全错误。标准的高斯函数需要包含中心位置、宽度参数,正确形式如下:
def Gauss(x, A, mu, sigma): return A * np.exp(-(x - mu)**2 / (2 * sigma**2))
参数说明:
A:峰值高度mu:峰值对应的x坐标(曲线中心位置)sigma:标准差,控制曲线的宽窄程度
2. 变量名错误
拟合代码中使用了 intensity_636,但你的数据集变量名是 intensity,这会导致拟合时传入错误数据,直接影响结果准确性。
3. 未提供初始参数猜测
curve_fit 默认用全1的初始参数猜测,但对于非中心在0的高斯分布,不合适的初始值会导致拟合失败或偏差。你需要根据数据给出合理的初始猜测:
- 峰值高度
A:参考数据最大值≈7.92 - 中心位置
mu:峰值对应的x≈29.3 - 标准差
sigma:观察峰值左右下降到一半的宽度,大概为10左右
修正后的完整代码
import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt # 转换为numpy数组 time = np.array([0.3, 1.3, 2.3, 3.3, 4.3, 5.3, 6.3, 7.3, 8.3, 9.3, 10.3, 11.3, 12.3, 13.3, 14.3, 15.3, 16.3, 17.3, 18.3, 19.3, 20.3, 21.3, 22.3, 23.3, 24.3, 25.3, 26.3, 27.3, 28.3, 29.3, 30.3, 31.3, 32.3, 33.3, 34.3, 35.3, 36.3, 37.3, 38.3, 39.3, 40.3, 41.3, 42.3, 43.3, 44.3, 45.3, 46.3, 47.3, 48.3, 49.3, 50.3, 51.3, 52.3, 53.3, 54.3, 55.3, 56.3, 57.3, 58.3, 59.3]) intensity = np.array([1.03587, 1.03187, 1.03561, 1.02893, 1.04659, 1.03633, 1.0481, 1.04156, 1.02164, 1.02741, 1.02675, 1.03651, 1.03713, 1.0252, 1.02853, 1.0378, 1.04374, 1.01427, 1.0387, 1.03389, 1.03148, 1.04334, 1.042, 1.04154, 1.0161, 1.0469, 1.03152, 1.22406, 5.4362, 7.92132, 6.50259, 4.7227, 3.32571, 2.46484, 1.74615, 1.51446, 1.2711, 1.15098, 1.09623, 1.0697, 1.06085, 1.05837, 1.04151, 1.0358, 1.03574, 1.05095, 1.03382, 1.04629, 1.03636, 1.03219, 1.03555, 1.02886, 1.04652, 1.02617, 1.04363, 1.03591, 1.04199, 1.03726, 1.03246, 1.0408]) # 修正后的高斯函数 def Gauss(x, A, mu, sigma): return A * np.exp(-(x - mu)**2 / (2 * sigma**2)) # 提供初始参数猜测 initial_guess = [8, 29, 10] # A:峰值高度, mu:中心位置, sigma:宽度 parameters, covariance = curve_fit(Gauss, time, intensity, p0=initial_guess) fit_A, fit_mu, fit_sigma = parameters fit_y = Gauss(time, fit_A, fit_mu, fit_sigma) # 绘图对比 plt.figure(figsize=(15,6)) plt.plot(time, intensity, 'o', label='原始数据') plt.plot(time, fit_y, '-', label=f'拟合曲线 (A={fit_A:.2f}, μ={fit_mu:.2f}, σ={fit_sigma:.2f})') plt.title('636 kHz 单频数据与高斯拟合', fontsize=18) plt.xlabel('流逝时间 (分:秒)', fontsize=18) plt.ylabel('1020 kHz 强度', fontsize=18) plt.legend(fontsize=12) plt.show()
额外优化:加入基线参数
如果拟合后基线部分仍有偏差,可在高斯函数中加入基线参数 C(你的数据基线在1左右),模型变为:
def Gauss(x, A, mu, sigma, C): return A * np.exp(-(x - mu)**2 / (2 * sigma**2)) + C
此时初始猜测需补充基线值:initial_guess = [7, 29, 10, 1],拟合结果会更贴合基线区域的数据。
内容的提问来源于stack exchange,提问作者new-to-coding
相关产品推荐
相关产品推荐

