如何获取两个重叠正态分布的均值与标准差?含小时维度循环数据的特殊情况处理
解决重叠分布的参数估计问题:从普通正态到循环小时数据
刚好处理过这类统计建模问题,分两种场景给你拆解:
一、非循环数据:重叠正态分布的均值与标准差估计
如果你的数据是线性的(比如身高、温度这类没有循环属性的数值),估计两个重叠正态分布的参数有几种靠谱的方法:
参数化拟合(最准确)
用有限混合正态模型,通过最大似然估计(MLE)来拆分两个成分。实操中可以用现成工具:- R语言:
mixtools包的normalmixEM()函数,输入数据并指定成分数k=2,拟合后会返回每个正态成分的均值mu、标准差sigma和权重lambda。 - Python:
sklearn.mixture.GaussianMixture,设置n_components=2,拟合后通过means_和covariances_(取平方根就是标准差)获取参数。
- R语言:
可视化快速估算
如果只有图表没有原始数据:- 先找两个峰值的位置,这就是两个分布的近似均值;
- 正态分布的拐点在均值±σ的位置,看曲线从峰值开始弯曲的点到均值的距离,就是近似标准差;
- 重叠部分较多时,可以先画整体的核密度曲线,再尝试手动拟合两个正态曲线调整参数,直到和原图匹配。
矩估计(近似方法)
如果知道两个分布的权重(比如通过先验信息),可以用总体矩来反推:
总体均值 = 权重1×均值1 + 权重2×均值2
总体方差 = 权重1×(方差1 + (均值1-总体均值)²) + 权重2×(方差2 + (均值2-总体均值)²)
不过这种方法需要已知权重,准确性不如MLE。
二、循环数据(小时数):特殊处理方案
小时数属于圆形数据(0点和24点重合,23点之后直接到0点),普通正态分布完全不适用——因为它的尾部是线性延伸的,会把跨0点的分布错误地当成“均值在中间”的宽分布。这里要换思路:
核心原则:用圆形分布替代正态分布
圆形数据里最接近正态分布的是von Mises分布,它专门用于建模圆周上的集中分布,参数包括:
- 方位角
μ:对应正态分布的均值,代表分布的中心位置(比如8点、20点); - 浓度参数
κ:对应正态分布标准差的倒数,κ越大,分布越集中。
参数估计方法
工具拟合
同样用混合模型思路,不过换成混合von Mises分布:- R语言:
mixtools包的vonmisesmixEM(),或者circular包提供的圆形统计工具; - Python:
circularstats库可以计算圆形均值、浓度参数,也可以用PyMC3做贝叶斯混合拟合。
- R语言:
从图表手动估算
- 找两个峰值对应的小时数,就是各自的方位角
μ; - 估算浓度
κ:当κ较大时,von Mises分布近似正态,此时可以用“从峰值到密度降为最大值1/e处的小时数差”来近似,换算成弧度后,σ≈1/√κ,反向推导κ; - 处理跨0点的情况:比如分布峰值在23点和1点,不要把数据当成线性的23和1,而是看成圆周上相邻的点,圆形均值会是0点(或24点),这才符合实际分布的中心。
- 找两个峰值对应的小时数,就是各自的方位角
避坑提醒
绝对不要强行把小时数当成线性数据拟合普通正态分布——比如把23点当成23,1点当成1,拟合出来的均值会是12点,完全不符合实际分布的集中趋势。如果实在要临时近似,只能在分布非常集中(比如峰值在8点,几乎没有跨0点的数据)时,把数据当成线性区间处理,否则必须用圆形统计方法。
内容的提问来源于stack exchange,提问作者Mark Solinski
相关产品推荐
相关产品推荐

