生成 t 分布的随机数:接近零的较小数字。

机器算法验证 Python t分布
2022-03-27 12:54:25

根据Wikipedia 上给出的处方,我尝试生成具有三个自由度的学生 t 分布随机数。我还使用 numpy 的内置随机数生成器生成了这些数字,用于 t 分布。但是,我觉得我使用 Wikipedia 处方生成的数字与分布的分析形式不太吻合。下图显示了每种情况的五个示例直方图:手动(维基百科)生成(上排)和 python 的内置生成(下排)。我觉得在附近,存在一些问题。我的观察正确吗?如果是的话,我这样做的方式有什么问题?我的python代码也在下面给出..x=0

每个直方图包含个数字,绿色曲线代表解析分布10000

在此处输入图像描述

import numpy as np
import matplotlib.pyplot as plt
plt.style.use("seaborn")
import seaborn as sns
from scipy.stats import t

"""Generate t distributed values"""
def f(x, mu):
    n = len(x)
    return np.sqrt(n) * (x.mean()-mu)/ x.std()

mu = 0
df = 3


for i in range(5):
    plt.subplot(2,5,i+1)
    t_vals = [f(np.random.normal(loc = mu, size = df + 1), mu) for i in range(10000)]
    sns.distplot(t_vals, kde = False, norm_hist = True)
    x = np.linspace(-5, 5, 100)
    plt.plot(x, t.pdf(x, df))
    plt.xlim([-5, 5])
    plt.xlabel(r"$x$")
    if i == 0:
        plt.ylabel(r"$p(x)$")
    if i == 2:
        plt.title("Manually generated")

for i in range(5):
    plt.subplot(2,5,i+6)
    t_vals = np.random.standard_t(df, size = 10000)
    sns.distplot(t_vals, kde = False, norm_hist = True)
    x = np.linspace(-5, 5, 100)
    plt.plot(x, t.pdf(x, df))
    plt.xlim([-5, 5])
    plt.xlabel(r"$x$")
    if i == 0:
        plt.ylabel(r"$p(x)$")
    if i == 2:
        plt.title("Generated using python")

plt.tight_layout()
plt.savefig("t_dists.pdf", bboxinches = "tight")
1个回答

简短版本:问题在于 NumPy x.std(),它没有除以正确的自由度。

在 R 中重复实验显示没有差异:通过将直方图与具有三个自由度t

在此处输入图像描述

或三自由度 cdf对样本变换的均匀性t

在此处输入图像描述

或相应的QQ图:

在此处输入图像描述

大小为 10 5 的样本在 R 中按如下方式生成:

X=matrix(rnorm(4*1e5),ncol=4)
Z=sqrt(4)*apply(X,1,mean)/apply(X,1,sd)

Kolmogorov-Smirnov 检验也产生对 null 的接受:

> ks.test(Z,"pt",df=3)

    One-sample Kolmogorov-Smirnov test

data:  Z
D = 0.0039382, p-value = 0.08992
alternative hypothesis: two-sided

对于一个样品和

>  ks.test(Z,"pt",df=3)

    One-sample Kolmogorov-Smirnov test

data:  Z
 D = 0.0019529, p-value = 0.8402
 alternative hypothesis: two-sided

为下一个。

然而......,原因更普通:碰巧NumPy 没有以标准(Gosset 的)方式定义标准方差!实际上,它使用 的根 ,这导致了膨胀,因此观察到的差异:

1ni=1n(xix¯)2
t
nn1

> ks.test(sqrt(4/3)*Z,"pt",df=3)

        One-sample Kolmogorov-Smirnov test

data:  Z
D = 0.030732, p-value < 2.2e-16
alternative hypothesis: two-sided

在此处输入图像描述

虽然我个人不反对使用n代替n1在分母中,该定义与 Gosset 的定义相冲突,因此与 Student 的定义相冲突t分配。