【问题标题】:Matching moments of fitted parametric distribution in Python is inaccuratePython中拟合参数分布的匹配矩不准确
【发布时间】:2021-03-18 21:46:57
【问题描述】:

在下面的代码中,我生成了一个随机变量x,我知道它是正态分布的,所以我对其进行了参数正态分布(通过参数的最大似然估计)来模拟一个名为@的合成变量987654322@ 应该匹配原始数据的属性。 xy 的统计矩(均值、标准差)也应该匹配。

那么为什么y 的分布时刻不匹配x 的分布呢?在下面的代码的一次运行中,y (0.052) 的平均值可能是 x (0.01) 的 5 倍,有时甚至是负数,而应该是正数

import numpy as np
from scipy.stats import norm

n = 2000
x = norm.rvs(size=n)
y = norm(*norm.fit(x)).rvs(size=n)

for i in [x,y]:
    print("mu={:.4f}, sd={:.4f}".format(np.mean(i), np.std(i)))

【问题讨论】:

    标签: python statistics distribution normal-distribution data-fitting


    【解决方案1】:

    那么为什么 y 的分布矩不匹配 x 的矩 分布?

    他们确实 - 或者至少他们在预期的错误范围内这样做 (1)

    快速观察是它们都接近标准正态分布;它们的第一个时刻都接近 0,第二个时刻都接近 1。但是,请注意 x 是从 N(0,1) 采样的,y 是从 N(mean(x), std(x)) 采样的。

    大样本量n

    如果您希望它们的值更接近而不是简单地增加样本大小n。我们将修复random_state 以实现重现性2

    import numpy as np
    from scipy.stats import norm
    
    n = 200000
    
    for i in range(5):
        x = norm.rvs(size=n, random_state=i)
        y = norm(*norm.fit(x)).rvs(size=n, random_state=i)
    
        print("Trial {}".format(i))
        for i in [x, y]:
            print("mu={:.4f}, sd={:.4f}".format(np.mean(i), np.std(i)))
    

    这会产生:

    Trial 0
    mu=0.0033, sd=0.9980
    mu=0.0067, sd=0.9960
    Trial 1
    mu=0.0045, sd=0.9977
    mu=0.0089, sd=0.9953
    Trial 2
    mu=-0.0004, sd=0.9981
    mu=-0.0008, sd=0.9963
    Trial 3
    mu=-0.0019, sd=0.9965
    mu=-0.0037, sd=0.9930
    Trial 4
    mu=-0.0052, sd=0.9992
    mu=-0.0104, sd=0.9984
    

    小样本量 n

    对于小样本n,我们自然会预计xy 之间存在一些差异,因为我们实际上是从y 中抽取另一个样本。但是,我们可以观察到拟合参数的表现如何,如下所示:

    n = 200
    for i in range(5):
        x = norm.rvs(size=n, random_state=i)    
        print("Trial {}".format(i))
        print(np.mean(x), np.std(x), norm(*norm.fit(x)).args)
    

    这会产生

    Trial 0
    0.07091049314116117 1.0214227686959954 (0.07091049314116117, 1.0214227686959954)
    Trial 1
    0.1066888148479486 0.9100459829739235 (0.1066888148479486, 0.9100459829739235)
    Trial 2
    0.012250008696874187 1.0800421002497833 (0.012250008696874187, 1.0800421002497833)
    Trial 3
    -0.07079063505988327 0.9767123391405987 (-0.07079063505988327, 0.9767123391405987)
    Trial 4
    0.028540839305884236 0.9537561748836348 (0.028540839305884236, 0.9537561748836348)
    

    (1) 没有实际计算标准误差,如果我错了,请纠正我。在Cross Validated 上快速搜索可以很好地解释Standard Error 的一般情况。

    (2) 修复随机状态xnorm(*norm.fit(x)) 并不意味着来自后者的随机样本应该产生N(mean(x), std(x))。话又说回来,参考上面的(1) 为什么要呢?

    【讨论】:

    • 如何在我的原始代码中制定修复random_state 的第二种方法?它是否比您的答案中描述的增加样本量的第一种方法更准确?在我的应用程序中,n=50 的小样本量是常态
    • 是的,我刚刚意识到我关于随机状态的说法是错误的!
    • 是吗?你要撤回random_state 方法吗?
    • 在尝试将矩与参数分布匹配时有关小样本设置的任何 cmet
    • 当然,更新了脚注中的第一项。请注意,我的答案的后半部分显示拟合参数正好是 mean(x)std(x)。所以这实际上是一个问题:“给定N(a, b),N 应该有多大才能使样本均值和标准充分接近ab”。我将删除我对 random state 的评论,因为它现在已经在问题中得到解决 - 并且还因为它措辞不当并且可能具有误导性。
    猜你喜欢
    • 2020-05-20
    • 1970-01-01
    • 2018-04-27
    • 2012-08-02
    • 2014-06-13
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多