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

自定义函数拟合直方图时曲线平坦不匹配问题咨询

对数分箱直方图高斯拟合平坦问题修复

核心错误点

  • 初始参数设置错误:初始参数x0全部设为0,优化器从a=0的初始点迭代,会直接收敛到y=0的局部最优解,输出平坦直线
  • 测试数据不符合对数坐标要求:你生成的正态分布均值为1e-10、标准差为1e-7,近50%的样本为负值,对数坐标无法展示负数,这些样本会被错误归到边缘bin,完全破坏分布形态
  • 分箱中心计算错误:对数分箱的中心不能用算术平均计算,需要用几何平均,否则x坐标位置偏移会直接导致拟合错误
  • 拟合曲线采样逻辑错误:用np.linspace在对数区间采样时,绝大多数点集中在大数值端,低数值区间采样严重不足,和对数分箱的密度不匹配
  • 重复拟合无意义:第一次拟合用错误初始值得到错误结果,再把这个结果作为初始值做第二次拟合,根本无法跳出错误收敛域
  • 冗余导入:代码中重复导入优化模块、导入未使用的pandas库,虽然不影响拟合结果,但属于无效代码

修正后代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# 修正测试数据:保证所有样本为正,落在对数区间内
x = np.random.normal(5e-8, 2e-8, size=10000)
x = x[x>0] # 过滤极小概率出现的负值

def func(x, a, b, c):
    return a * (np.exp(-b*(x-c)**2))

bins=25
logbins = np.logspace(np.log10(1.0E-10),np.log10(1E-07),bins)

bin_heights, bin_borders, _ = plt.hist(x, bins=logbins, edgecolor='black', color='b')
# 修正:对数分箱中心用几何平均计算
bin_centers = np.sqrt(bin_borders[:-1] * bin_borders[1:])

# 修正:传入合理初始参数,a为峰值高度、c为分布中心位置、b为宽度相关系数
x0 = np.array([bin_heights.max(), 1/(2*(2e-8)**2), 5e-8])
popt, pcov = curve_fit(func, bin_centers, bin_heights, p0=x0)

# 修正:用logspace生成拟合区间点,匹配对数坐标密度
x_interval_for_fit = np.logspace(np.log10(bin_borders[0]), np.log10(bin_borders[-1]), 1000)

plt.plot(x_interval_for_fit, func(x_interval_for_fit, *popt), label='Fit',color='r', linewidth=2)
plt.xscale('log')
plt.legend()
plt.show()

补充说明

修正后拟合曲线会和对数分箱下的直方图形态完全匹配,不会再出现平坦直线的问题。如果你要拟合的原始数据确实存在负值,就不能直接用对数x轴做拟合,需要先做坐标转换或者选择适配负值的分布函数。

运行结果截图:拟合曲线为平坦状态,但直方图呈上升分布形态

内容的提问来源于stack exchange,提问作者ABDUL

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:06:23