Python Scipy非中心卡方随机变量

Python Scipy非中心卡方随机变量,python,numpy,scipy,Python,Numpy,Scipy,考虑n平方iid正态随机变量的和S=sum(Z^2(mu,sig^2))。根据S/sig^2具有自由度=n和非中心性参数=n*mu^2 但是,比较通过平方正态和直接使用scipy.ncx2生成N非中心卡方随机变量来生成这些变量的S: import numpy as np from scipy.stats import ncx2, chi2 import matplotlib.pyplot as plt n = 1000 # number of normals in sum N_MC = 10

考虑
n
平方iid正态随机变量的和
S=sum(Z^2(mu,sig^2))
。根据S/sig^2具有自由度=
n
和非中心性参数=
n*mu^2

但是,比较通过平方正态和直接使用scipy.ncx2生成
N
非中心卡方随机变量来生成这些变量的
S

import numpy as np
from scipy.stats import ncx2, chi2
import matplotlib.pyplot as plt

n = 1000  # number of normals in sum
N_MC = 100000  # number of trials

mu = 0.05
sig = 0.3

### Generate sums of squared normals ###
Z = np.random.normal(loc=mu, scale=sig, size=(N_MC, n))
S = np.sum(Z**2, axis=1)

### Generate non-central chi2 RVs directly ###
dof = n
non_centrality = n*mu**2
NCX2 = sig**2 * ncx2.rvs(dof, non_centrality, size=N_MC)
# NCX2 = sig**2 * chi2.rvs(dof, size=N_MC)  # for mu = 0.0

### Plot histos ###
fig, ax = plt.subplots()
ax.hist(S, bins=50, label='S')
ax.hist(NCX2, bins=50, label='NCX2', alpha=0.7)
ax.legend()
plt.show()
这将产生直方图

我相信数学是正确的;这种差异可能是
ncx2
实现中的错误吗?设置
mu=0
并使用
scipy.chi2
看起来更好:
问题出现在问题的第二句:“
S/sig^2
具有非中心卡方分布,自由度=
n
,非中心性参数=
n*mu^2
”,非中心性参数不正确。它应该是
n*(mu/sig)^2

非中心卡方分布的标准定义是,它是具有平均μ和标准偏差1的正态变量的平方和。您正在使用标准偏差的正态变量计算
S
。让我们把这个分布写成
N(mu,sig**2)
。利用正态分布的位置-尺度特性,我们得到了

N(mu, sig**2) = mu + sig*N(0, 1) = sig*(mu/sig + N(0,1)) = sig*N(mu/sig, 1)
因此,将
N(mu,sig**2)
的变量平方相加等于将
sig*N(mu/sig,1)
的平方相加。这给出了
sig**2
乘以具有非中心性
mu/sig
的非中心卡方变量

如果将计算
非中心性的行更改为

non_centrality = n*(mu/sig)**2

柱状图如您所期望的那样排列。

这似乎有帮助。你介意详细说明一下吗?我加了一些详细说明。