PP图,QQ 图,及 python 画图

统计学中有时会用到 PP 图 或 QQ 图,用来看样本数据是否服从某一特定分布,或用来看两个样本数据是否服从同一分布。

若 PP 或 QQ 图中的点基本落在一条 45度 的线上,则说明服从特定分布。

一般的步骤为:

  1. 将样本数据从小到大排序,假设排序后的样本数据为
    x1x_1

    x1?,

    x2x_2

    x2?,

    \dots

    …,

    xnx_n

    xn?。

  2. 对于
    nn

    n 个样本数据,对应

    nn

    n 个分位数。分位数的取值规则不一样,一个比较简答的规则是:第

    kk

    k 个分位数的取值为

    Qk=(k?0.5)/nQ_k=(k-0.5)/n

    Qk?=(k?0.5)/n

  3. 横坐标为:
    x1x_1

    x1?,

    x2x_2

    x2?,

    \dots

    …,

    xnx_n

    xn?,纵坐标为:所判断分布的累计分布函数在分位数的逆函数值

    F?(Qk)F^-(Q_k)

    F?(Qk?),则为 QQ 图;若横坐标为:

    F(x1)F(x_1)

    F(x1?),

    F(x2)F(x_2)

    F(x2?),

    \dots

    …,

    F(xn)F(x_n)

    F(xn?),纵坐标为:

    QkQ_k

    Qk?,则为 PP 图。

PP 图与 QQ 图的功能基本一样,我见用 QQ 图的比较多。因为分位数的取值规则不一样,因此 QQ 图可能画的不太一样。

下面以正态分布的随机样本为例,用 python 画一下图形,专门的 QQ 图也可以调用 scipy 中的 probplot 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import scipy.stats as st
import matplotlib.pyplot as plt
import numpy as np


n = 100
samples = st.norm.rvs(loc = 5, scale = 2, size = n)

samples_sort = sorted(samples)


x_labels_p = np.zeros(n)
x_labels_p[0] = 1 - 0.5 ** (1/n)
x_labels_p[n - 1] = 0.5 ** (1/n)
for i in range(1, n - 1):
    x_labels_p[i] = (i + 1 - 0.3175)/(n + 0.365)
y_labels_p = st.norm.cdf(samples_sort, loc = 5, scale = 2)

plt.scatter(x_labels_p, y_labels_p)
plt.title('PP plot for normal distribution samle')
plt.show()


x_labels_q = samples_sort
y_labels_q = st.norm.ppf(x_labels_p, loc = 5, scale = 2)

plt.scatter(x_labels_q, y_labels_q)
plt.title('QQ plot for normal distribution samle')
plt.show()

res = st.probplot(samples, sparams=(5, 2), plot = plt) # 若没有 sparams,默认会标准化样本数据
plt.title('QQ plot by probplot for normal distribution')
plt.show()

显示图形:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

由于 probplot 的分位数取值规则不同,从图形上看,probplot 的 QQ 图与自己画的 QQ 图略微不一样。