利用q-q plot检验样本数据分布

什么是q-q plot

在统计学中,q-q plot(又叫quantile-quantile plot)是一条曲线,利用这条曲线我们可以判断一个样本数据是否是从某个理论分布抽样而得。比如,我们想对某一个样本数据进行统计分析,并且假设这个样本数据来自一个正态分布(normal/Gaussian distribution),那么我们就可以用q-q plot来直观得检测这个假设,参考 [1]。

值得注意的是,q-q plot只为我们提供了一个目测样本数据是否来自某个理论分布的工具,并没有为我们提供一个严格意义上的证明。

具体来说,q-q plot是一个散点图。图的横坐标是一组数据的升序分位数(quantile),图的纵坐标是另一组数据的升序分位数。如果这两组数据都是从同一个理论分布中抽样所得,那么这个散点图就会近似于一条直线。如果散点图偏离直线较多,那么我们就可以认为这两组数据不是从同一个理论分布中抽样所得。如果我们只有一组数据并且想检测这组数据是否服从某个理论分布,那么我们的横坐标就选作这个理论分布的分位数的值。当然,我们横坐标的个数应该与纵坐标的个数相同。比如如果我们的样本数据有 n n n个,我们想检测这 n n n个数据是否是抽样自正态分布,那么我们的横坐标就选取标准正态分布的 n n n个分位点。

举例

检测正态分布(Normal distribution)

我们先生成一组服从正态分布的随机数,然后用q-q plot来检测这组数据是否服从正态分布。我们希望得到的q-q plot近似于一条直线。
Python代码如下:

import numpy as np
from scipy.stats import norm
from scipy.stats import uniform
import matplotlib.pyplot as plt

mu = 1 # expectation of the normal distribution
sigma = 1 # standard deviation of the normal distribution
N = 100 # number of data points
sample01 = np.random.normal(mu, sigma, N) # generate random numbers from N(0, 1)
sample01.sort() # sort sample01

x = np.linspace(0.01, 0.99, N)
normal_quantile = [norm.ppf(c) for c in x] # generatating the N(0, 1) distribution quantile values

# make the q-q plot
plt.figure(figsize=(8, 6), dpi=100)
plt.scatter(normal_quantile, sample01)
plt.xlabel("quantile values for standard normal distribution", fontsize=20)
plt.ylabel("sorted sample values", fontsize=20)
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)

q-q plot normal quantile我们看到得到的q-q plot近似为一条直线。在上面代码中norm.ppf(q, loc=0, scale=1)是percent point function,用来求正态分布的分位数。默认的参数loc=0loc为正态分布的期望(平均值),scale=1scale为正态分布的标准差。如果我们求标准正态分布的分位数,我们可以省略locscale,直接用norm.ppf(q)即可。

值得指出的是,如果我们知道 X ∼ N ( μ ,   σ 2 ) X \sim N(\mu, \, \sigma^2) XN(μ,σ2), 那么我们有 X − μ σ ∼ N ( 0 ,   1 ) \displaystyle \frac{X - \mu}{\sigma} \sim N(0, \, 1) σXμN(0,1). 于是,如果我们已知标准正态分布的分位数 Z α Z_{\alpha} Zα,即 P ( Z ≤ Z α ) = α ,   0 < = 1 < = α ,   Z ∼ N ( 0 ,   1 ) \displaystyle P(Z \leq Z_{\alpha}) = \alpha, \, 0 <= 1 <= \alpha, \, Z \sim N(0, \, 1) P(ZZα)=α,0<=1<=α,ZN(0,1)。如果我们须要求 X X X 的分位数,即 P ( X ≤ X α ) = α \displaystyle P(X \leq X_{\alpha}) = \alpha P(XXα)=α。 利用 X − μ σ ∼ N ( 0 ,   1 ) \displaystyle \frac{X - \mu}{\sigma} \sim N(0, \, 1) σXμN(0,1), 我们有 P ( X ≤ X α ) = P ( X − μ σ ≤ X α − μ σ ) = α \displaystyle P(X \leq X_{\alpha}) = P \left( \frac{X - \mu}{\sigma} \leq \frac{X_{\alpha} - \mu}{\sigma} \right) = \alpha P(XXα)=P(σXμσXαμ)=α,于是我们知道 X α − μ σ = Z α \displaystyle \frac{X_{\alpha} - \mu}{\sigma} = Z_{\alpha} σXαμ=Zα。所以,一般正态分布 X X X的分位数 X α \displaystyle X_{\alpha} Xα 与标准正态分布的分位数 Z α \displaystyle Z_{\alpha} Zα同样存在一个简单的线性关系。这也就是为什么我们可以用标准正态分布的分位数来当作x-axis的数据,来对标我们须要验证的样本数据(y-axis)。

检测均匀分布(uniform distribution)

对于同样的数据sample01,如果我们想检测数据是否是从均匀分布 U ( 0 , 1 ) U(0, 1) U(0,1)中抽样所得,那么我们的q-q plot中的横坐标取值应该为 U ( 0 , 1 ) U(0, 1) U(0,1)的分位数。这时候的q-q plot就如下图所示。

uniform_quantile = [uniform.ppf(c) for c in x] # generatating the N(0, 1) distribution quantile values

# make the q-q plot
plt.figure(figsize=(8, 6), dpi=100)
plt.scatter(uniform_quantile, sample01)
plt.xlabel("quantile values for uniform distribution", fontsize=20)
plt.ylabel("sorted sample values", fontsize=20)
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)

q-q plot uniform quantile
我们可以看到,这时的q-q plot偏离直线较多。因为我们的样本取自正态分布,而不是均匀分布。

如果我们从 U n i f o r m ( 0 , 1 ) \mathrm{Uniform}(0, 1) Uniform(0,1)分布中抽取样本,然后对这个样本做 U ( 0 , 1 ) U(0, 1) U(0,1) 分位数的q-q plot,则q-q plot如下图所示。

# Generate the random sample from a uniform distribution. 
sample02 = np.random.uniform(0, 1, N) # generate random numbers from Uniform(0, 1)
sample02.sort() # sort sample01

# make the q-q plot
plt.figure(figsize=(8, 6), dpi=100)
plt.scatter(uniform_quantile, sample02)
plt.xlabel("quantile values for uniform distribution", fontsize=20)
plt.ylabel("sorted sample values", fontsize=20)
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)

q-q plot
我们发现这时的q-q plot又接近于一条直线。

参考文献

[1] http://data.library.virginia.edu/understanding-q-q-plots

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值