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

如何为时间-强度数据集拟合最优高斯曲线?

问题描述

我有一组特定频率下的时间-强度数据集,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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:02:12