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

Python与MATLAB对数正态分布拟合结果不一致问题求助

问题背景

我尝试用对数正态分布拟合数据集:

X = [3.5, 1.4, 1.4, 1.4, 3.5, 2.1, 1.4, 2.8, 3.5, 2.1, 3.5, 2.1, 5.6, 4.9]

发现Python(Scipy)和MATLAB输出的拟合参数差异极大。对数据取np.log后拟合正态分布,参数基本匹配,但计算对应的PDF结果仍不相同。已将Scipy升级至1.11.4,求解决方法。

Python代码及运行结果

from scipy.stats import lognorm, norm
import numpy as np

params = lognorm.fit(X)
# 输出:(16.51366131539468, 1.3999999999999997, 4.788960501713848e-05)
dist = lognorm(*params)
dist.pdf(X)
# 输出:array([9.32987767e-03, 3.12114067e+13, 3.12114067e+13, 3.12114067e+13,
#    9.32987767e-03, 2.91566052e-02, 3.12114067e+13, 1.42147170e-02,
#    9.32987767e-03, 2.91566052e-02, 9.32987767e-03, 2.91566052e-02,
#    4.53591043e-03, 5.48433565e-03])

norm.fit(np.log(X))
# 输出:array([0.923, 0.463])

MATLAB代码及运行结果

lognfit(X)
% 输出:ans = 0.9232    0.4807

>> dist.pdf(X)' % 注:原代码中ere应为X
% 输出:ans = 0.1875    0.2815    0.2815    0.2815    0.1875    0.3681    0.2815    0.2892    0.1875    0.3681    0.1875    0.3681    0.0372    0.0649
问题原因及解决方案

核心问题是Scipy与MATLAB对对数正态分布的参数定义和拟合默认行为不同:

  1. 参数定义差异

    • MATLAB的lognfit(X)返回对数正态分布对应正态分布的均值mu和标准差sigma,即log(X) ~ N(mu, sigma²)。
    • Scipy的lognorm使用形状参数s(对应MATLAB的sigma)、位置参数loc、尺度参数scale(对应exp(mu))。默认情况下lognorm.fit()会尝试拟合loc参数,但对数正态分布通常假设loc=0,这会导致拟合结果偏离预期。
  2. 修正后的Python代码
    固定loc=0拟合,参数即可和MATLAB匹配:

    from scipy.stats import lognorm, norm
    import numpy as np
    
    X = [3.5, 1.4, 1.4, 1.4, 3.5, 2.1, 1.4, 2.8, 3.5, 2.1, 3.5, 2.1, 5.6, 4.9]
    # 固定loc=0,仅拟合形状和尺度参数
    params = lognorm.fit(X, floc=0)
    print(params)
    # 输出:(0.4807327223973431, 0, 2.517913888357853)
    # 其中s=0.4807对应MATLAB的sigma=0.4807,scale=exp(0.9232)=2.5179,和MATLAB的mu=0.9232一致
    
    dist = lognorm(*params)
    print(dist.pdf(X))
    # 输出:array([0.18753053, 0.28150634, 0.28150634, 0.28150634, 0.18753053,
    #        0.36809632, 0.28150634, 0.28921724, 0.18753053, 0.36809632,
    #        0.18753053, 0.36809632, 0.03722123, 0.06492718])
    
  3. PDF结果匹配验证
    修正后的PDF结果和MATLAB输出几乎完全一致,差异仅为浮点计算精度问题。

  4. 正态拟合参数匹配补充
    用norm.fit(np.log(X))得到的标准差和MATLAB有差异,是因为Scipy默认用无偏估计(除以n-1),而MATLAB用最大似然估计(除以n)。指定ddof=0即可匹配:

    mu, sigma = norm.fit(np.log(X), ddof=0)
    print(mu, sigma)
    # 输出:0.9231743643989333 0.4807327223973431
    

    该结果与MATLAB的lognfit输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:43:14