如何获取双峰正态分布的最优拟合参数?
解决双峰正态分布拟合的参数优化问题
你手动调整参数很难找到全局最优解,建议用数值优化工具自动拟合参数。下面是改进后的代码,使用scipy.optimize.curve_fit来自动寻找最优参数,同时优化了函数定义让拟合更高效:
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit # 数据准备 hours = np.array([i/2 for i in range(49)]) frequency = np.array([79, 77, 68, 72, 72, 73, 97, 126, 179, 278, 436, 529, 684, 641, 532, 460, 275, 206, 136, 120, 108, 104, 88, 114, 129, 122, 142, 143, 142, 139, 145, 149, 162, 270, 371, 418, 495, 421, 334, 274, 144, 126, 97, 99, 90, 78, 77, 94, 79]) # 重新定义双峰正态分布函数,参数更直观 def bimodal(x, phi, mu1, mu2, sigma): # phi: 第一个峰的权重(0<phi<1) # mu1, mu2: 两个峰的均值 # sigma: 两个峰的共同标准差 norm1 = phi * np.exp(-(x - mu1)**2 / (2 * sigma**2)) / (sigma * np.sqrt(2 * np.pi)) norm2 = (1 - phi) * np.exp(-(x - mu2)**2 / (2 * sigma**2)) / (sigma * np.sqrt(2 * np.pi)) return norm1 + norm2 # 计算密度值:频率/(总样本数*组距),组距是0.5(因为hours间隔0.5) total_samples = frequency.sum() bin_width = 0.5 density = frequency / (total_samples * bin_width) # 初始参数猜测:从直方图看,两个峰大概在6和18,权重接近0.5,标准差约3 p0 = [0.5, 6, 18, 3] # 拟合参数,设置参数边界避免不合理值(phi在0-1,sigma>0) bounds = ([0, -np.inf, -np.inf, 1e-3], [1, np.inf, np.inf, np.inf]) params, covariance = curve_fit(bimodal, hours, density, p0=p0, bounds=bounds) # 提取最优参数 phi_opt, mu1_opt, mu2_opt, sigma_opt = params print(f"最优参数:phi={phi_opt:.4f}, mu1={mu1_opt:.4f}, mu2={mu2_opt:.4f}, sigma={sigma_opt:.4f}") # 生成拟合曲线 x_fit = np.linspace(min(hours), max(hours), 400) y_fit = bimodal(x_fit, phi_opt, mu1_opt, mu2_opt, sigma_opt) # 绘图对比 plt.figure(figsize=(10, 6)) plt.bar(hours, density, width=bin_width, alpha=0.7, label="密度直方图数据", align='center') plt.plot(x_fit, y_fit, 'r-', label="双峰拟合曲线", linewidth=2) plt.xlabel('小时') plt.ylabel('密度') plt.title('供应时间密度直方图与双峰正态分布拟合') plt.legend() plt.grid(True, which='both', linestyle='--', linewidth=0.5) plt.tight_layout() plt.show()
关键改进点:
- 参数定义优化:直接使用权重
phi、两个峰的均值mu1/mu2和共同标准差sigma,物理意义更明确,减少参数转换带来的拟合难度。 - 自动拟合工具:用
curve_fit进行非线性最小二乘拟合,自动寻找最优参数,避免手动调参的主观性。 - 参数边界约束:通过
bounds限制参数范围(比如phi必须在0-1之间,sigma必须为正),确保拟合结果合理。 - 数据预处理:正确计算密度值,让拟合目标与直方图的密度轴对齐,提升拟合精度。
运行这段代码后,会输出最优参数,并且拟合曲线会更贴合你的数据分布。
内容的提问来源于stack exchange,提问作者Dondu
相关产品推荐
相关产品推荐

