SciPy 1.12 中文文档(六十一)
scipy.stats.percentileofscore
scipy.stats.percentileofscore(a, score, kind='rank', nan_policy='propagate')
计算相对于一组分数的分数的百分位数。
例如,percentileofscore的 80%表示a中 80%的分数低于给定的分数。在存在间隙或并列值的情况下,确切的定义取决于可选关键字kind。
参数:
aarray_like
与* score *进行比较的数组。
scorearray_like
用于计算百分位数的分数。
kind{‘rank’, ‘weak’, ‘strict’, ‘mean’}, optional
指定结果分数的解释。可用以下选项(默认为‘rank’):
- ‘rank’:分数的平均百分位排名。在存在多个匹配项的情况下,平均所有匹配分数的百分位排名。
- ‘weak’:这种类型对应于累积分布函数的定义。百分位数为 80%表示 80%的值小于或等于提供的分数。
- ‘strict’:类似于“weak”,但仅计数严格小于给定分数的值。
- ‘mean’:弱和严格分数的平均值,通常用于测试。参见
en.wikipedia.org/wiki/Percentile_rank
nan_policy{‘propagate’, ‘raise’, ‘omit’}, optional
指定如何处理a中的* nan *值。可用以下选项(默认为‘propagate’):
- ‘propagate’:对于* score *中的每个值都返回 nan。
- ‘raise’:抛出错误
- ‘omit’:执行计算时忽略 nan 值
返回:
pcosfloat
分数在* a *中的百分位数(0-100)
另请参阅
scipy.stats.scoreatpercentile, scipy.stats.rankdata
示例
给定分数以下的给定值四分之三:
>>> import numpy as np
>>> from scipy import stats
>>> stats.percentileofscore([1, 2, 3, 4], 3)
75.0
对于多个匹配项,请注意两个匹配项的分数分别为 0.6 和 0.8:
>>> stats.percentileofscore([1, 2, 3, 3, 4], 3)
70.0
仅有 2/5 的值严格小于 3:
>>> stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='strict')
40.0
但是 4/5 的值小于或等于 3:
>>> stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='weak')
80.0
严格和弱得分之间的平均值是:
>>> stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='mean')
60.0
支持任意维度的分数数组:
>>> stats.percentileofscore([1, 2, 3, 3, 4], [2, 3])
array([40., 70.])
输入可以是无限的:
>>> stats.percentileofscore([-np.inf, 0, 1, np.inf], [1, 2, np.inf])
array([75., 75., 100.])
如果* a 为空,则生成的百分位数均为 nan *:
>>> stats.percentileofscore([], [1, 2])
array([nan, nan])
scipy.stats.scoreatpercentile
scipy.stats.scoreatpercentile(a, per, limit=(), interpolation_method='fraction', axis=None)
计算输入序列给定百分位数处的分数。
例如,per=50 处的分数是中位数。如果所需分位数位于两个数据点之间,我们根据 interpolation 的值进行插值。如果提供了 limit 参数,则应为两个值(下限,上限)的元组。
参数:
a类似数组
要提取分数的一维值数组。
per类似数组
要提取分数的百分位数。值应该在区间 [0,100] 内。
limit元组,可选
两个标量的元组,用于计算百分位数的下限和上限。a 的值如果在此(闭合)区间之外将被忽略。
interpolation_method{‘fraction’, ‘lower’, ‘higher’},可选
指定在所需分位数位于两个数据点 i 和 j 之间时要使用的插值方法。以下选项可用(默认为 ‘fraction’):
fraction:i + (j - i) * fraction,其中fraction是被i和j包围的索引的分数部分- ‘lower’:
i- ‘higher’:
j
axis整数,可选
计算百分位数的轴。默认为 None。如果为 None,则在整个数组 a 上计算。
返回:
score浮点数或者 ndarray
百分位数处的分数。
另请参见
percentileofscore,numpy.percentile
注意
这个函数将来将会过时。对于 NumPy 1.9 及更高版本,建议使用 numpy.percentile,它提供了与 scoreatpercentile 相同的功能,并且速度显著更快。
示例
>>> import numpy as np
>>> from scipy import stats
>>> a = np.arange(100)
>>> stats.scoreatpercentile(a, 50)
49.5
scipy.stats.relfreq
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.stats.relfreq.html#scipy.stats.relfreq
scipy.stats.relfreq(a, numbins=10, defaultreallimits=None, weights=None)
返回一个相对频率直方图,使用直方图函数。
相对频率直方图是每个区间内观察值数量相对于总观察值的映射。
参数:
a数组型
输入数组。
numbins整数,可选
直方图使用的箱子数量。默认为 10。
defaultreallimits元组(下限,上限),可选
直方图的范围的下限和上限值。如果未给定值,则使用稍大于 a 值范围的范围。具体来说是 (a.min() - s, a.max() + s),其中 s = (1/2)(a.max() - a.min()) / (numbins - 1)。
weights数组型,可选
a中每个值的权重。默认为 None,每个值的权重为 1.0。
返回:
frequencyn 维数组
相对频率的分箱值。
lowerlimit浮点数
较低的实际限制。
binsize浮点数
每个箱子的宽度。
extrapoints整数
额外的点。
示例
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy import stats
>>> rng = np.random.default_rng()
>>> a = np.array([2, 4, 1, 2, 3, 2])
>>> res = stats.relfreq(a, numbins=4)
>>> res.frequency
array([ 0.16666667, 0.5 , 0.16666667, 0.16666667])
>>> np.sum(res.frequency) # relative frequencies should add up to 1
1.0
创建具有 1000 个随机值的正态分布
>>> samples = stats.norm.rvs(size=1000, random_state=rng)
计算相对频率
>>> res = stats.relfreq(samples, numbins=25)
计算 x 的值空间
>>> x = res.lowerlimit + np.linspace(0, res.binsize*res.frequency.size,
... res.frequency.size)
绘制相对频率直方图
>>> fig = plt.figure(figsize=(5, 4))
>>> ax = fig.add_subplot(1, 1, 1)
>>> ax.bar(x, res.frequency, width=res.binsize)
>>> ax.set_title('Relative frequency histogram')
>>> ax.set_xlim([x.min(), x.max()])
>>> plt.show()
scipy.stats.binned_statistic
scipy.stats.binned_statistic(x, values, statistic='mean', bins=10, range=None)
计算一个或多个数据集的分 bin 统计量。
这是直方图函数的一般化。直方图将空间划分为 bins,并返回每个 bin 中点的数量。此函数允许计算每个 bin 中的值(或值集合)的和、均值、中位数或其他统计量。
参数:
x(N,) 类似数组
要分 bin 的一系列值。
values(N,) 类似数组或者(N,) 类似数组的列表
统计量将被计算的数据。这必须与x具有相同的形状,或者是一组序列 - 每个序列与x具有相同的形状。如果values是一组序列,则将独立地计算每个统计量。
statistic字符串或可调用对象,可选
要计算的统计量(默认为‘mean’)。以下统计量可用:
- ‘mean’:计算每个 bin 内点的平均值。空的 bins 将用 NaN 表示。
- ‘std’:计算每个 bin 内的标准差。这是使用 ddof=0 隐式计算的。
- ‘median’:计算每个 bin 内点的值的中位数。空的 bins 将用 NaN 表示。
- ‘count’:计算每个 bin 内点的数量。这等同于一个非加权直方图。values数组不被引用。
- ‘sum’:计算每个 bin 内点的值的总和。这等同于一个加权直方图。
- ‘min’:计算每个 bin 内点的最小值。空的 bins 将用 NaN 表示。
- ‘max’:计算每个 bin 内点的值的最大值。空的 bins 将用 NaN 表示。
- function:一个用户定义的函数,接受一个值的 1D 数组,并输出一个单一的数值统计量。此函数将在每个 bin 中的值上调用。空的 bins 将由 function([])表示,如果这导致错误,则返回 NaN。
bins整数或标量序列,可选
如果bins是整数,则定义给定范围内的等宽 bin 数(默认为 10)。如果bins是序列,则定义 bin 边缘,包括右边的边缘,允许非均匀的 bin 宽度。小于最低 bin 边缘的x值被分配给 bin 号 0,超出最高 bin 的值被分配给bins[-1]。如果指定了 bin 边缘,则 bins 的数量将为(nx = len(bins)-1)。
range (float, float) 或 [(float, float)],可选
bins 的下限和上限。如果未提供,则范围为(x.min(), x.max())。超出范围的值将被忽略。
返回值:
statistic数组
每个 bin 中所选统计量的值。
bin_edges浮点数 dtype 的数组
返回 bin 边界 (length(statistic)+1)。
binnumber:整数型的 1-D ndarray
每个值 x 属于的箱子(对应于 bin_edges)的索引。与 values 长度相同。箱号为 i 表示对应的值位于 (bin_edges[i-1], bin_edges[i]) 之间。
另请参阅
numpy.digitize, numpy.histogram, binned_statistic_2d, binned_statistic_dd
注意:
除了最后一个(最右边的)箱子是半开放的。换句话说,如果 bins 是 [1, 2, 3, 4],那么第一个箱子是 [1, 2)(包括 1,但不包括 2),第二个是 [2, 3)。然而,最后一个箱子是 [3, 4],其中包括 4。
版本 0.11.0 中的新特性。
示例:
>>> import numpy as np
>>> from scipy import stats
>>> import matplotlib.pyplot as plt
首先是一些基本示例:
在给定样本范围内创建两个均匀间隔的箱子,并计算每个箱子中对应的值的总和:
>>> values = [1.0, 1.0, 2.0, 1.5, 3.0]
>>> stats.binned_statistic([1, 1, 2, 5, 7], values, 'sum', bins=2)
BinnedStatisticResult(statistic=array([4\. , 4.5]),
bin_edges=array([1., 4., 7.]), binnumber=array([1, 1, 1, 2, 2]))
也可以传递多个值数组。统计量是在每个集合上独立计算的:
>>> values = [[1.0, 1.0, 2.0, 1.5, 3.0], [2.0, 2.0, 4.0, 3.0, 6.0]]
>>> stats.binned_statistic([1, 1, 2, 5, 7], values, 'sum', bins=2)
BinnedStatisticResult(statistic=array([[4\. , 4.5],
[8\. , 9\. ]]), bin_edges=array([1., 4., 7.]),
binnumber=array([1, 1, 1, 2, 2]))
>>> stats.binned_statistic([1, 2, 1, 2, 4], np.arange(5), statistic='mean',
... bins=3)
BinnedStatisticResult(statistic=array([1., 2., 4.]),
bin_edges=array([1., 2., 3., 4.]),
binnumber=array([1, 2, 1, 2, 3]))
作为第二个例子,我们现在生成一些作为风速函数的帆船速度的随机数据,然后确定我们的船在特定风速下的速度有多快:
>>> rng = np.random.default_rng()
>>> windspeed = 8 * rng.random(500)
>>> boatspeed = .3 * windspeed**.5 + .2 * rng.random(500)
>>> bin_means, bin_edges, binnumber = stats.binned_statistic(windspeed,
... boatspeed, statistic='median', bins=[1,2,3,4,5,6,7])
>>> plt.figure()
>>> plt.plot(windspeed, boatspeed, 'b.', label='raw data')
>>> plt.hlines(bin_means, bin_edges[:-1], bin_edges[1:], colors='g', lw=5,
... label='binned statistic of data')
>>> plt.legend()
现在我们可以使用 binnumber 来选择所有风速低于 1 的数据点:
>>> low_boatspeed = boatspeed[binnumber == 0]
最后一个例子中,我们将使用 bin_edges 和 binnumber 来绘制一个分布的图,该图显示每个 bin 中的平均值及其周围的分布,叠加在常规直方图和概率分布函数之上:
>>> x = np.linspace(0, 5, num=500)
>>> x_pdf = stats.maxwell.pdf(x)
>>> samples = stats.maxwell.rvs(size=10000)
>>> bin_means, bin_edges, binnumber = stats.binned_statistic(x, x_pdf,
... statistic='mean', bins=25)
>>> bin_width = (bin_edges[1] - bin_edges[0])
>>> bin_centers = bin_edges[1:] - bin_width/2
>>> plt.figure()
>>> plt.hist(samples, bins=50, density=True, histtype='stepfilled',
... alpha=0.2, label='histogram of data')
>>> plt.plot(x, x_pdf, 'r-', label='analytical pdf')
>>> plt.hlines(bin_means, bin_edges[:-1], bin_edges[1:], colors='g', lw=2,
... label='binned statistic of data')
>>> plt.plot((binnumber - 0.5) * bin_width, x_pdf, 'g.', alpha=0.5)
>>> plt.legend(fontsize=10)
>>> plt.show()
scipy.stats.binned_statistic_2d
scipy.stats.binned_statistic_2d(x, y, values, statistic='mean', bins=10, range=None, expand_binnumbers=False)
计算一个或多个数据集的二维分箱统计量。
这是直方图 2d 函数的泛化。直方图将空间划分为箱子,并返回每个箱子中点的数量。此函数允许计算每个箱内值(或值集)的总和、均值、中位数或其他统计量。
参数:
x(N,) 数组样式
要沿第一维度分箱的一系列值。
y(N,) 数组样式
要沿第二维度分箱的一系列值。
values(N,) 数组样式或(N,)数组样式的列表
将计算统计量的数据。它必须与x的形状相同,或者是一个序列列表 - 每个序列具有与x相同的形状。如果values是这样的列表,则将分别在每个列表上计算统计量。
statistic字符串或可调用对象,可选
要计算的统计量(默认为‘mean’)。可用以下统计量:
- ‘mean’:计算每个箱内点的平均值。空箱将用 NaN 表示。
- ‘std’:计算每个箱内的标准偏差。这隐式地以 ddof=0 计算。
- ‘median’:计算每个箱内点的中位数。空箱将用 NaN 表示。
- ‘count’:计算每个箱内的点数。这与未加权的直方图相同。values数组未被引用。
- ‘sum’:计算每个箱内点的总和。这与加权直方图相同。
- ‘min’:计算每个箱内点的最小值。空箱将用 NaN 表示。
- ‘max’:计算每个箱内点的最大值。空箱将用 NaN 表示。
- 函数:一个用户定义的函数,接受值的 1D 数组,并输出单个数值统计量。该函数将在每个箱子的值上调用。空箱将由 function([])表示,或者如果返回错误,则为 NaN。
bins整数或[int, int]或类数组或[array, array],可选
箱子的规范:
- 两个维度的箱子数量(nx = ny = bins),
- 每个维度中的箱子数量(nx, ny = bins),
- 两个维度的箱子边缘(x_edge = y_edge = bins),
- 每个维度中的箱子边缘(x_edge, y_edge = bins)。
如果指定了箱子边缘,则箱子数量将为(nx = len(x_edge)-1, ny = len(y_edge)-1)。
range(2,2) 数组样式,可选
每个维度的最左边和最右边的箱子边缘(如果在bins参数中未显式指定):[[xmin, xmax], [ymin, ymax]]。该范围外的所有值将被视为异常值,并不计入直方图。
expand_binnumbers布尔值,可选
'False'(默认值):返回的 binnumber 是形状为 (N,) 的线性化 bin 索引数组。'True':返回的 binnumber '展开' 成形状为 (2,N) 的 ndarray,其中每行给出相应维度中的 bin 数。参见 binnumber 返回值和 Examples 部分。
新版本 0.17.0 中新增。
返回:
statistic(nx, ny) ndarray
每个二维 bin 中所选统计量的值。
x_edge(nx + 1) ndarray
第一维度上的 bin 边缘。
y_edge(ny + 1) ndarray
第二维度上的 bin 边缘。
binnumber(N,) 整数数组或 (2,N) 整数 ndarray
此参数为每个 sample 元素分配一个整数,表示此观察值所在的 bin。表示依赖于 expand_binnumbers 参数。详细信息请参见 Notes。
另请参阅
numpy.digitize,numpy.histogram2d,binned_statistic,binned_statistic_dd
Notes
Binedges:除了最后一个(最右侧)bin 是半开放的。换句话说,如果 bins 是 [1, 2, 3, 4],则第一个 bin 是 [1, 2)(包括 1,但不包括 2),第二个是 [2, 3)。然而,最后一个 bin 是 [3, 4],包含 4。
binnumber:此返回参数为每个 sample 元素分配一个整数,表示其所属的 bin。表示依赖于 expand_binnumbers 参数。如果为 'False'(默认值):返回的 binnumber 是一个形状为 (N,) 的数组,其中包含将每个 sample 元素映射到其对应 bin 的线性化索引(使用行优先顺序)。请注意,返回的线性化 bin 索引用于具有外部 bin 边界上额外 bin 的数组,以捕获定义的 bin 边界之外的值。如果为 'True':返回的 binnumber 是一个形状为 (2,N) 的 ndarray,其中每行分别指示每个维度的 bin 放置。在每个维度中,binnumber 为 i 表示相应的值位于(D_edge[i-1],D_edge[i])之间,其中 'D' 可以是 'x' 或 'y'。
新版本 0.11.0 中新增。
示例
>>> from scipy import stats
使用显式 bin 边缘计算计数:
>>> x = [0.1, 0.1, 0.1, 0.6]
>>> y = [2.1, 2.6, 2.1, 2.1]
>>> binx = [0.0, 0.5, 1.0]
>>> biny = [2.0, 2.5, 3.0]
>>> ret = stats.binned_statistic_2d(x, y, None, 'count', bins=[binx, biny])
>>> ret.statistic
array([[2., 1.],
[1., 0.]])
每个样本所在的 bin 由返回的 binnumber 参数给出。默认情况下,这些是线性化的 bin 索引:
>>> ret.binnumber
array([5, 6, 5, 9])
也可以使用 expand_binnumbers 参数将 bin 索引扩展为每个维度的单独条目:
>>> ret = stats.binned_statistic_2d(x, y, None, 'count', bins=[binx, biny],
... expand_binnumbers=True)
>>> ret.binnumber
array([[1, 1, 1, 2],
[1, 2, 1, 1]])
表明前三个元素属于 xbin 1,第四个元素属于 xbin 2;y 以此类推。
scipy.stats.binned_statistic_dd
scipy.stats.binned_statistic_dd(sample, values, statistic='mean', bins=10, range=None, expand_binnumbers=False, binned_statistic_result=None)
计算一组数据的多维度分箱统计量。
这是 histogramdd 函数的泛化。直方图将空间划分为箱,并返回每个箱内点的计数。此函数允许计算每个箱内值的总和、平均值、中位数或其他统计量。
参数:
sample 数组样本
将作为 N 个长度为 D 的数组序列或者是(N,D)数组传递的数据直方图。
values (N,) 数组样本或 (N,) 数组样本列表
将计算统计量的数据。它必须与sample具有相同的形状,或者是一个序列的列表 - 每个序列都具有与sample相同的形状。如果values是这样的列表,则将独立地对每个计算统计量。
statistic 字符串或可调用对象,可选
要计算的统计量(默认为'mean')。提供以下统计量选项:
- ‘mean’:计算每个箱内点的值的平均值。空箱将由 NaN 表示。
- ‘median’:计算每个箱内点的值的中位数。空箱将由 NaN 表示。
- ‘count’:计算每个箱内点的计数。这等同于一个非加权直方图。values 数组不被引用。
- ‘sum’:计算每个箱内点的值的总和。这等同于加权直方图。
- ‘std’:计算每个箱内的标准差。这是以 ddof=0 隐式计算的。如果给定箱内值的数量为 0 或 1,则计算的标准差值将为该箱的 0。
- ‘min’:计算每个箱内点的值的最小值。空箱将由 NaN 表示。
- ‘max’:计算每个箱内点的值的最大值。空箱将由 NaN 表示。
- function:一个用户定义的函数,接受一个 1D 值数组,并输出单个数值统计量。将对每个箱中的值调用此函数。空箱将由 function([]) 表示,如果这导致错误,则为 NaN。
bins 序列或正整数,可选
箱规范必须是以下形式之一:
- 一系列描述沿每个维度的箱边界的数组。
- 每个维度的箱数(nx、ny,... = bins)。
- 所有维度的箱数(nx = ny = ... = bins)。
range 序列,可选
一系列下限和上限箱边界,如果在bins中未显式给出边界,则默认为每个维度的最小值和最大值。
expand_binnumbers 布尔值,可选
‘False’(默认值):返回的 binnumber 是一个形状为 (N,) 的数组,其中包含线性化的箱索引。‘True’:返回的 binnumber 被‘展开’为一个形状为 (D,N) 的 ndarray,其中每行给出相应维度的箱编号。请参见 binned_statistic_2d 中的 binnumber 返回值和 Examples 部分。
binned_statistic_result:binnedStatisticddResult
前一次调用函数的结果,以便在新值和/或不同统计信息上重用箱边界和箱号。若要重用箱号,expand_binnumbers 必须设置为 False(默认值)。
从版本 0.17.0 开始新增。
返回:
statistic:ndarray,形状为 (nx1, nx2, nx3,…)
每个二维箱中所选统计量的值。
bin_edges 的列表,其中包含 ndarray
描述每个维度的 (nxi + 1) 箱边缘的 D 个数组的列表。
binnumber(N,) 整数数组或 (D,N) 整数数组
此分配给 sample 中每个元素一个整数,表示此观测值所在的箱。表示依赖于 expand_binnumbers 参数。有关详细信息,请参见 Notes。
另请参阅
numpy.digitize, numpy.histogramdd, binned_statistic, binned_statistic_2d
注释
Binedges:除最后一个(最右边的)箱子外,在每个维度中都是半开放的。换句话说,如果 bins 是 [1, 2, 3, 4],那么第一个箱是 [1, 2)(包括 1,但不包括 2),第二个箱是 [2, 3)。然而,最后一个箱是 [3, 4],其中包含 4。
binnumber:此返回的参数将为 sample 中的每个元素分配一个整数,表示其所属的箱。表示依赖于 expand_binnumbers 参数。若‘False’(默认值):返回的 binnumber 是一个形状为 (N,) 的数组,其中每个元素的索引映射到其相应的箱(使用行优先顺序)。若‘True’:返回的 binnumber 是一个形状为 (D,N) 的 ndarray,其中每行分别指示每个维度的箱位置。在每个维度中,一个 binnumber 为 i 意味着对应的值在(bin_edges[D][i-1], bin_edges[D][i])之间。
从版本 0.11.0 开始新增。
示例
>>> import numpy as np
>>> from scipy import stats
>>> import matplotlib.pyplot as plt
>>> from mpl_toolkits.mplot3d import Axes3D
以一个包含 600 个 (x, y) 坐标的数组为例。binned_statistic_dd 可以处理更高维度 D 的数组。但需要维度 D+1 的绘图。
>>> mu = np.array([0., 1.])
>>> sigma = np.array([[1., -0.5],[-0.5, 1.5]])
>>> multinormal = stats.multivariate_normal(mu, sigma)
>>> data = multinormal.rvs(size=600, random_state=235412)
>>> data.shape
(600, 2)
创建箱子并计算每个箱子中有多少数组:
>>> N = 60
>>> x = np.linspace(-3, 3, N)
>>> y = np.linspace(-3, 4, N)
>>> ret = stats.binned_statistic_dd(data, np.arange(600), bins=[x, y],
... statistic='count')
>>> bincounts = ret.statistic
设置柱的体积和位置:
>>> dx = x[1] - x[0]
>>> dy = y[1] - y[0]
>>> x, y = np.meshgrid(x[:-1]+dx/2, y[:-1]+dy/2)
>>> z = 0
>>> bincounts = bincounts.ravel()
>>> x = x.ravel()
>>> y = y.ravel()
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111, projection='3d')
>>> with np.errstate(divide='ignore'): # silence random axes3d warning
... ax.bar3d(x, y, z, dx, dy, bincounts)
重复使用具有新值的箱编号和箱边缘:
>>> ret2 = stats.binned_statistic_dd(data, -np.arange(600),
... binned_statistic_result=ret,
... statistic='mean')
scipy.stats.ttest_1samp
scipy.stats.ttest_1samp(a, popmean, axis=0, nan_policy='propagate', alternative='two-sided', *, keepdims=False)
计算一个组分数的均值的 T 检验。
这是一个关于期望值(样本的平均值)的空假设的检验,即样本 a 的期望值等于给定的总体均值 popmean。
参数:
a类似数组
样本观察值。
popmeanfloat 或 类似数组
空假设中的期望值。如果是类似数组,则其沿 axis 的长度必须等于 1,否则必须可以广播至 a。
axis整数或 None,默认为:0
如果是整数,则输入的轴沿着计算统计量的轴(例如行)的统计量将出现在输出的相应元素中。如果为 None,则在计算统计量之前会展平输入。
nan_policy{'propagate', 'omit', 'raise'}
定义如何处理输入的 NaN 值。
-
propagate: 如果轴切片(例如行)中的 NaN 存在,则计算统计量时相应的输出条目将为 NaN。 -
omit: 在执行计算时将省略 NaN。如果在计算统计量的轴切片中剩余的数据不足,则相应的输出条目将为 NaN。 -
raise: 如果存在 NaN,则会引发ValueError。
alternative{'two-sided', 'less', 'greater'},可选
定义备择假设。以下选项可用(默认为 'two-sided'):
-
‘two-sided’: 样本的基础分布的均值与给定的总体均值不同(popmean)
-
‘less’: 样本的基础分布的均值小于给定的总体均值(popmean)
-
‘greater’: 样本的基础分布的均值大于给定的总体均值(popmean)
keepdims布尔值,默认为:False
如果设置为 True,则会保留被减少的轴作为大小为一的维度结果。使用此选项,结果将正确广播至输入数组。
返回:
resultTtestResult
一个带有以下属性的对象:
statisticfloat 或 数组
t 统计量。
pvaluefloat 或 数组
与给定备择假设相关联的 p 值。
dffloat 或 数组
在计算 t 统计量时使用的自由度数量;这比样本的大小少一个 (a.shape[axis]).
在版本 1.10.0 中新增。
对象还具有以下方法:
confidence_interval(confidence_level=0.95)
计算给定置信水平下围绕总体均值的置信区间。置信区间以具有 low 和 high 字段的 namedtuple 返回。
在版本 1.10.0 中新增。
注意事项
统计量计算公式为(np.mean(a) - popmean)/se,其中se表示标准误差。因此,当样本均值大于总体均值时,统计量为正;当样本均值小于总体均值时,统计量为负。
从 SciPy 1.9 开始,np.matrix输入(不建议新代码使用)在执行计算之前会转换为np.ndarray。在这种情况下,输出将是一个标量或适当形状的np.ndarray,而不是 2D 的np.matrix。同样,虽然被屏蔽的数组的屏蔽元素会被忽略,但输出将是一个标量或np.ndarray,而不是带有mask=False的屏蔽数组。
例子
假设我们希望测试总体均值等于 0.5 的空假设。我们选择 99%的置信水平;也就是说,如果 p 值小于 0.01,我们将拒绝空假设,支持备选假设。
在进行来自标准均匀分布的随机变量测试时,该分布均值为 0.5,我们预期数据大多数时间与空假设一致。
>>> import numpy as np
>>> from scipy import stats
>>> rng = np.random.default_rng()
>>> rvs = stats.uniform.rvs(size=50, random_state=rng)
>>> stats.ttest_1samp(rvs, popmean=0.5)
TtestResult(statistic=2.456308468440, pvalue=0.017628209047638, df=49)
如预期的那样,0.017 的 p 值不低于我们的 0.01 阈值,因此我们不能拒绝空假设。
在测试来自标准正态分布的数据时,其均值为 0,我们预期将拒绝空假设。
>>> rvs = stats.norm.rvs(size=50, random_state=rng)
>>> stats.ttest_1samp(rvs, popmean=0.5)
TtestResult(statistic=-7.433605518875, pvalue=1.416760157221e-09, df=49)
确实,p 值低于我们的 0.01 阈值,因此我们拒绝空假设,支持默认的“双侧”替代假设:总体均值不等于0.5。
然而,假设我们针对单侧替代检验空假设,即总体均值大于0.5。由于标准正态分布的均值小于 0.5,我们不会期望拒绝空假设。
>>> stats.ttest_1samp(rvs, popmean=0.5, alternative='greater')
TtestResult(statistic=-7.433605518875, pvalue=0.99999999929, df=49)
毫不奇怪,由于 p 值大于我们的阈值,我们不会拒绝空假设。
注意,在使用 99%置信水平时,真空假设将被拒绝约 1%的时间。
>>> rvs = stats.uniform.rvs(size=(100, 50), random_state=rng)
>>> res = stats.ttest_1samp(rvs, popmean=0.5, axis=1)
>>> np.sum(res.pvalue < 0.01)
1
实际上,即使以上所有 100 个样本均来自标准均匀分布,其总体均值确实为 0.5,我们也会错误地拒绝一个样本的空假设。
ttest_1samp还可以计算围绕总体均值的置信区间。
>>> rvs = stats.norm.rvs(size=50, random_state=rng)
>>> res = stats.ttest_1samp(rvs, popmean=0)
>>> ci = res.confidence_interval(confidence_level=0.95)
>>> ci
ConfidenceInterval(low=-0.3193887540880017, high=0.2898583388980972)
95%置信区间的边界是参数popmean的最小和最大值,使得测试的 p 值为 0.05。
>>> res = stats.ttest_1samp(rvs, popmean=ci.low)
>>> np.testing.assert_allclose(res.pvalue, 0.05)
>>> res = stats.ttest_1samp(rvs, popmean=ci.high)
>>> np.testing.assert_allclose(res.pvalue, 0.05)
在关于从样本抽取的总体的某些假设下,95%置信水平的置信区间预计在 95%的样本复制中包含真实总体均值。
>>> rvs = stats.norm.rvs(size=(50, 1000), loc=1, random_state=rng)
>>> res = stats.ttest_1samp(rvs, popmean=0)
>>> ci = res.confidence_interval()
>>> contains_pop_mean = (ci.low < 1) & (ci.high > 1)
>>> contains_pop_mean.sum()
953
scipy.stats.binomtest
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.stats.binomtest.html#scipy.stats.binomtest
scipy.stats.binomtest(k, n, p=0.5, alternative='two-sided')
执行成功概率为 p 的检验。
二项式检验[1]是对伯努利实验中成功概率为p的原假设的检验。
可在许多统计学文本中找到检验的详细信息,例如[2]的 24.5 节。
参数:
k整数
成功次数。
n整数
试验次数。
p浮点数,可选
成功的假设概率,即预期的成功比例。该值必须在区间0 <= p <= 1内。默认值为p = 0.5。
alternative{‘two-sided’, ‘greater’, ‘less’},可选
指示备择假设。默认值为'两侧'。
返回:
resultBinomTestResult 实例
返回值是一个带有以下属性的对象:
k 整数
成功次数(从binomtest中复制)
n 整数
试验次数(从binomtest中复制)
alternativestr
指示输入到binomtest中的备择假设。它将是'two-sided'、'greater'或'less'中的一个。
统计浮点数
成功比例的估计。
p 值浮点数
假设检验的 p 值。
该对象具有以下方法:
proportion_ci(confidence_level=0.95, method=’exact’):
计算statistic的置信区间。
注意事项
新功能版本 1.7.0。
参考文献
[1]
二项式检验,en.wikipedia.org/wiki/Binomial_test
[2]
Jerrold H. Zar,《生物统计分析》(第五版),Prentice Hall,Upper Saddle River,New Jersey USA(2010)
示例
>>> from scipy.stats import binomtest
汽车制造商声称他们的汽车不安全的比例不超过 10%。检查了 15 辆汽车的安全性,发现 3 辆不安全。检验制造商的声明:
>>> result = binomtest(3, n=15, p=0.1, alternative='greater')
>>> result.pvalue
0.18406106910639114
在 5%显著水平下,无法拒绝原假设,因为返回的 p 值大于 5%的临界值。
检验统计量等于估计比例,即简单地3/15:
>>> result.statistic
0.2
我们可以使用结果的*proportion_ci()*方法计算估计的置信区间:
>>> result.proportion_ci(confidence_level=0.95)
ConfidenceInterval(low=0.05684686759024681, high=1.0)
scipy.stats.quantile_test
scipy.stats.quantile_test(x, *, q=0, p=0.5, alternative='two-sided')
执行分位数测试并计算分位数的置信区间。
此函数测试零假设,即 q 是样本 x 底层人口分布的分位数值。例如,默认参数下,它测试 x 底层分布的中位数是否为零。函数返回一个对象,包括测试统计量、p 值以及计算分位数置信区间的方法。
参数:
xarray_like
一维样本。
qfloat,默认值:0
假设的分位数值。
pfloat,默认值:0.5
与分位数相关联的概率;即人口比例小于 q 是 p。必须严格在 0 和 1 之间。
alternative{‘two-sided’, ‘less’, ‘greater’},可选
定义备择假设。可用以下选项(默认为‘two-sided’):
-
‘two-sided’: 与概率 p 相关的分位数不是 q。
-
‘less’: 与概率 p 相关的分位数小于 q。
-
‘greater’: 与概率 p 相关的分位数大于 q。
返回值:
resultQuantileTestResult
具有以下属性的对象:
statisticfloat
两种可能用于分位数测试的检验统计量之一。第一个检验统计量 T1 是 x 中小于或等于假设分位数 q 的样本比例。第二个检验统计量 T2 是 x 中严格小于假设分位数 q 的样本比例。
当 alternative = 'greater' 时,使用 T1 计算 p 值,statistic 设置为 T1。
当 alternative = 'less' 时,使用 T2 计算 p 值,statistic 设置为 T2。
当 alternative = 'two-sided' 时,考虑 T1 和 T2,并使用导致最小 p 值的那个。
statistic_typeint
根据使用 T1 或 T2 计算 p 值而定,为 1 或 2。
pvaluefloat
与给定备择假设相关联的 p 值。
该对象还具有以下方法:
confidence_interval(confidence_level=0.95)
计算与人口分位数相关联的概率 p 的置信区间。置信区间在 namedtuple 中返回,字段为 low 和 high。当观测数不足以计算所需置信度的置信区间时,值为 nan。
注:
此测试及其计算置信区间的方法是非参数的。仅当观测值独立同分布时才有效。
测试遵循 Conover [1]。考虑了两个检验统计量。
T1:小于或等于 q 的观测值数量。
T1 = (x <= q).sum()
T2:严格小于 q 的观测值数量。
T2 = (x < q).sum()
使用两个检验统计量是必要的,以处理 x 是从离散或混合分布生成的可能性。
检验的零假设是:
H0:第 (p^{\mathrm{th}}) 个总体分位数是 q。
并且每个检验统计量的零分布是 (\mathrm{binom}\left(n, p\right))。当 alternative='less' 时,备择假设是:
H1:第 (p^{\mathrm{th}}) 个总体分位数小于 q。
而 p 值是二项随机变量小于或等于观测值 T1 的概率。
[Y \sim \mathrm{binom}\left(n, p\right)]
大于或等于观测值 T2。
当 alternative='greater' 时,备择假设是:
H1:第 (p^{\mathrm{th}}) 个总体分位数大于 q。
而 p 值是二项随机变量 Y 小于或等于观测值 T1 的概率。
当 alternative='two-sided' 时,备择假设是:
H1:q 不是第 (p^{\mathrm{th}}) 个总体分位数。
而 p 值是 'less' 和 'greater' 情况下 p 值的较小者的两倍。对于同一数据,这两个 p 值都可能超过 0.5,因此该值被限制在区间 ([0, 1])。
置信区间的方法归因于 Thompson [2],并且后来被证明适用于任何一组独立同分布样本 [3]。计算基于这样的观察:分位数 (q) 大于任何观测值 (x_m (1\leq m \leq N)) 的概率可以计算为
[\mathbb{P}(x_m \leq q) = 1 - \sum_{k=0}^{m-1} \binom{N}{k} q^k(1-q)^{N-k}]
默认情况下,置信区间是针对 95% 的置信水平计算的。对于 95% 置信区间的常见解释是,如果从同一总体中重复抽取独立同分布样本并形成置信区间,这些置信区间将在大约 95% 的试验中包含指定分位数的真实值。
QuantileNPCI R 包中有类似的功能 [4]。其基础相同,但通过在样本值之间进行插值来计算置信区间边界,而本函数仅使用样本值作为边界。因此,quantile_test.confidence_interval 返回更保守的区间(即更大)。
计算分位数置信区间的相同方法包含在 confintr 包中[5]。
双侧置信区间不能保证是最优的;即可能存在一个更紧的区间,其概率大于置信水平包含感兴趣的分位数。在没有关于样本的进一步假设(例如,底层分布的性质)的情况下,单侧区间是最优紧的。
参考文献
[1]
-
- Conover,《实用非参数统计学》,第 3 版,1999 年。
[2]
W. R. Thompson,《关于中位数和其他期望分布的置信区间》,《数理统计学年刊》,卷 7,第 3 期,pp. 122-128,1936 年,访问日期:2019 年 9 月 18 日。[在线]. 可用:www.jstor.org/stable/2957563.
[3]
H. A. David 和 H. N. Nagaraja,《非参数推断中的序统计量》,《序统计量》,John Wiley & Sons, Ltd,2005 年,pp. 159-170. 可用:onlinelibrary.wiley.com/doi/10.1002/0471722162.ch7.
[4]
N. Hutson, A. Hutson, L. Yan,《QuantileNPCI: 非参数置信区间的分位数》,R 包,cran.r-project.org/package=QuantileNPCI
[5]
M. Mayer,《confintr: 置信区间》,R 包,cran.r-project.org/package=confintr
例子
假设我们希望测试一个总体中位数等于 0.5 的零假设。我们选择 99%的置信水平;也就是说,如果 p 值小于 0.01,我们将拒绝零假设,接受备择假设。
当测试来自标准均匀分布的随机变量时,其中位数为 0.5,我们预期数据大部分时间与零假设一致。
>>> import numpy as np
>>> from scipy import stats
>>> rng = np.random.default_rng()
>>> rvs = stats.uniform.rvs(size=100, random_state=rng)
>>> stats.quantile_test(rvs, q=0.5, p=0.5)
QuantileTestResult(statistic=45, statistic_type=1, pvalue=0.36820161732669576)
顾名思义,p 值未低于我们的 0.01 阈值,因此我们无法拒绝零假设。
当测试来自标准正态分布的数据时,其中位数为 0,我们预期会拒绝零假设。
>>> rvs = stats.norm.rvs(size=100, random_state=rng)
>>> stats.quantile_test(rvs, q=0.5, p=0.5)
QuantileTestResult(statistic=67, statistic_type=2, pvalue=0.0008737198369123724)
实际上,p 值低于我们的 0.01 阈值,因此我们拒绝零假设,接受默认的“双边”备择假设:总体中位数不等于 0.5。
然而,假设我们要测试一个单侧备择假设,即总体中位数大于0.5。由于标准正态分布的中位数小于 0.5,我们不希望拒绝零假设。
>>> stats.quantile_test(rvs, q=0.5, p=0.5, alternative='greater')
QuantileTestResult(statistic=67, statistic_type=1, pvalue=0.9997956114162866)
不出所料,由于 p 值高于我们的阈值,我们不会拒绝零假设,而是接受所选择的备择假设。
分位数测试不仅可以用于中位数,还可以用于任何分位数。例如,我们可以测试样本基础分布的第三四分位数是否大于 0.6。
>>> rvs = stats.uniform.rvs(size=100, random_state=rng)
>>> stats.quantile_test(rvs, q=0.6, p=0.75, alternative='greater')
QuantileTestResult(statistic=64, statistic_type=1, pvalue=0.00940696592998271)
p 值低于阈值。我们拒绝零假设,接受备择假设:样本基础分布的第三四分位数大于 0.6。
quantile_test 还可以计算任何分位数的置信区间。
>>> rvs = stats.norm.rvs(size=100, random_state=rng)
>>> res = stats.quantile_test(rvs, q=0.6, p=0.75)
>>> ci = res.confidence_interval(confidence_level=0.95)
>>> ci
ConfidenceInterval(low=0.284491604437432, high=0.8912531024914844)
在测试单侧备择假设时,置信区间包含所有观察结果,使得如果作为q,则测试的 p 值大于 0.05,因此不会拒绝原假设。例如:
>>> rvs.sort()
>>> q, p, alpha = 0.6, 0.75, 0.95
>>> res = stats.quantile_test(rvs, q=q, p=p, alternative='less')
>>> ci = res.confidence_interval(confidence_level=alpha)
>>> for x in rvs[rvs <= ci.high]:
... res = stats.quantile_test(rvs, q=x, p=p, alternative='less')
... assert res.pvalue > 1-alpha
>>> for x in rvs[rvs > ci.high]:
... res = stats.quantile_test(rvs, q=x, p=p, alternative='less')
... assert res.pvalue < 1-alpha
此外,如果针对随机样本重复生成 95%置信区间,则在大约 95%的复制中,置信区间将包含真实的分位值。
>>> dist = stats.rayleigh() # our "unknown" distribution
>>> p = 0.2
>>> true_stat = dist.ppf(p) # the true value of the statistic
>>> n_trials = 1000
>>> quantile_ci_contains_true_stat = 0
>>> for i in range(n_trials):
... data = dist.rvs(size=100, random_state=rng)
... res = stats.quantile_test(data, p=p)
... ci = res.confidence_interval(0.95)
... if ci[0] < true_stat < ci[1]:
... quantile_ci_contains_true_stat += 1
>>> quantile_ci_contains_true_stat >= 950
True
只要样本是独立同分布的,这对任何分布和任何分位数都适用。
scipy.stats.skewtest
原文:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.stats.skewtest.html#scipy.stats.skewtest
scipy.stats.skewtest(a, axis=0, nan_policy='propagate', alternative='two-sided')
检验偏度是否与正态分布不同。
此函数测试空假设,即样本抽取的总体偏度与对应的正态分布的偏度相同。
参数:
aarray
待测试的数据。
axisint 或 None,可选
计算统计量的轴线。默认为 0。如果为 None,则在整个数组 a 上计算。
nan_policy{‘propagate’, ‘raise’, ‘omit’},可选
定义当输入包含 NaN 时如何处理。有以下选项可用(默认为 'propagate'):
-
‘propagate’:返回 NaN
-
‘raise’:抛出错误
-
‘omit’:在执行计算时忽略 NaN 值
alternative{‘two-sided’,‘less’,‘greater’},可选
定义备择假设。默认为 'two-sided'。有以下选项可用:
-
‘two-sided’:样本背后的分布的偏度与正态分布(即 0)不同
-
‘less’:样本背后的分布的偏度小于正态分布的偏度
-
‘greater’:样本背后的分布的偏度大于正态分布的偏度
1.7.0 版中的新功能。
返回:
statisticfloat
此测试的计算 z 分数。
pvaluefloat
假设检验的 p 值。
注意
样本大小必须至少为 8。
参考文献
[1]
R. B. D’Agostino, A. J. Belanger 和 R. B. D’Agostino Jr.,“使用强大和信息丰富的正态性检验的建议”,《美国统计学家》44,第 316-321 页,1990 年。
[2]
Shapiro,S. S.,& Wilk,M. B.(1965)。正态性的方差分析检验(完整样本)。《生物统计学》,52(3/4),591-611。
[3]
B. Phipson 和 G. K. Smyth。“当排列随机抽取时,排列 p 值永远不应为零:计算精确 p 值。”《遗传学和分子生物学中的统计应用》9.1(2010)。
示例
假设我们希望从测量中推断出,医学研究中成年男性的体重是否不符合正态分布 [2]。以下是记录在数组 x 中的体重(磅)。
>>> import numpy as np
>>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])
来自[1]的偏度检验从计算基于样本偏度的统计量开始。
>>> from scipy import stats
>>> res = stats.skewtest(x)
>>> res.statistic
2.7788579769903414
因为正态分布的偏度为零,所以此统计量的大小 tend 对于从正态分布中抽取的样本而言通常较低。
通过比较观察到的统计量的值与空假设的空分布来执行测试:统计量值的分布是在空假设下得出的,即权重是从正态分布中抽取的分布。
对于此测试,非常大样本的统计量的空分布是标准正态分布。
>>> import matplotlib.pyplot as plt
>>> dist = stats.norm()
>>> st_val = np.linspace(-5, 5, 100)
>>> pdf = dist.pdf(st_val)
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> def st_plot(ax): # we'll reuse this
... ax.plot(st_val, pdf)
... ax.set_title("Skew Test Null Distribution")
... ax.set_xlabel("statistic")
... ax.set_ylabel("probability density")
>>> st_plot(ax)
>>> plt.show()
比较由 p 值量化:在零分布中比观察到的统计值更极端或更极端的值的比例。在双侧检验中,零分布中大于观察统计量的元素和小于观察统计量的负值都被认为是“更极端”的。
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> st_plot(ax)
>>> pvalue = dist.cdf(-res.statistic) + dist.sf(res.statistic)
>>> annotation = (f'p-value={pvalue:.3f}\n(shaded area)')
>>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
>>> _ = ax.annotate(annotation, (3, 0.005), (3.25, 0.02), arrowprops=props)
>>> i = st_val >= res.statistic
>>> ax.fill_between(st_val[i], y1=0, y2=pdf[i], color='C0')
>>> i = st_val <= -res.statistic
>>> ax.fill_between(st_val[i], y1=0, y2=pdf[i], color='C0')
>>> ax.set_xlim(-5, 5)
>>> ax.set_ylim(0, 0.1)
>>> plt.show()
>>> res.pvalue
0.005455036974740185
如果 p 值“小” - 即从一个正态分布的总体中抽取这样一个统计极值的概率很低 - 这可能被视为反对零假设的证据,赞成备择假设:这些权重不是从正态分布中抽取的。请注意:
-
反之不成立;也就是说,该检验不用于提供支持零假设的证据。
-
将被视为“小”的值的阈值是在数据分析之前应该考虑的选择,考虑到误报(错误地拒绝零假设)和漏报(未能拒绝错误的零假设)的风险 [3]。
注意标准正态分布提供了零分布的渐近逼近;对于有许多观测样本的情况,它只是准确的。对于像我们这样的小样本,scipy.stats.monte_carlo_test可能提供了一个更准确的,尽管是随机的,精确 p 值的近似。
>>> def statistic(x, axis):
... # get just the skewtest statistic; ignore the p-value
... return stats.skewtest(x, axis=axis).statistic
>>> res = stats.monte_carlo_test(x, stats.norm.rvs, statistic)
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> st_plot(ax)
>>> ax.hist(res.null_distribution, np.linspace(-5, 5, 50),
... density=True)
>>> ax.legend(['aymptotic approximation\n(many observations)',
... 'Monte Carlo approximation\n(11 observations)'])
>>> plt.show()
>>> res.pvalue
0.0062 # may vary
在这种情况下,渐近逼近和蒙特卡罗逼近非常接近,即使对于我们的小样本也是如此。
scipy.stats.kurtosistest
scipy.stats.kurtosistest(a, axis=0, nan_policy='propagate', alternative='two-sided')
测试数据集是否具有正态峰度。
此函数检验假设,样本抽取自的总体峰度是正态分布的峰度。
参数:
a数组
样本数据的数组。
axis整数或 None, 可选
计算检验的轴线。默认为 0。如果为 None,则计算整个数组 a。
nan_policy{‘propagate’, ‘raise’, ‘omit’}, 可选
定义如何处理输入包含 nan 的情况。以下选项可用(默认为 ‘propagate’):
-
‘propagate’:返回 nan
-
‘raise’:抛出错误
-
‘omit’:执行计算时忽略 nan 值
alternative{‘two-sided’, ‘less’, ‘greater’}, 可选
定义备择假设。以下选项可用(默认为 ‘two-sided’):
-
‘two-sided’: 样本所在分布的峰度与正态分布不同。
-
‘less’:样本所在分布的峰度小于正态分布的峰度
-
‘greater’:样本所在分布的峰度大于正态分布的峰度
从版本 1.7.0 开始。
返回:
statistic浮点数
此检验的计算 z 分数。
pvalue浮点数
假设检验的 p 值。
注释
仅对 n>20 有效。此函数使用 [1] 中描述的方法。
参考文献
[1] (1,2)
参见例如 F. J. Anscombe, W. J. Glynn,“正态样本 b2 峰度统计量的分布”, Biometrika, vol. 70, pp. 227-234, 1983。
[2]
Shapiro, S. S., & Wilk, M. B. (1965). 方差分析检验正态性(完整样本)。 Biometrika, 52(3/4), 591-611.
[3]
B. Phipson 和 G. K. Smyth. “置换 p 值不应为零:在随机抽取置换时计算精确 p 值。” 统计遗传学与分子生物学应用 9.1 (2010)。
[4]
Panagiotakos, D. B. (2008). 生物医学研究中 p 值的价值. The open cardiovascular medicine journal, 2, 97.
示例
假设我们希望从测量中推断,医学研究中成年男性的体重不服从正态分布[2]。以下是记录在数组 x 中的体重(磅)。
>>> import numpy as np
>>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])
[1,2] 中的峰度检验首先基于样本(过量/费舍尔)峰度计算统计量。
>>> from scipy import stats
>>> res = stats.kurtosistest(x)
>>> res.statistic
2.3048235214240873
(该检验警告我们的样本观察值太少,无法进行检验。我们将在示例结束时返回这一点。) 因为正态分布的过量峰度为零(定义如此),所以从正态分布中抽取的样本的此统计量的大小趋于较低。
测试是通过比较统计量的观察值与零分布进行的:在零假设下,权重是从正态分布中抽取的统计量值的分布。
对于这个测试,对于非常大的样本,统计量的零分布是标准正态分布。
>>> import matplotlib.pyplot as plt
>>> dist = stats.norm()
>>> kt_val = np.linspace(-5, 5, 100)
>>> pdf = dist.pdf(kt_val)
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> def kt_plot(ax): # we'll reuse this
... ax.plot(kt_val, pdf)
... ax.set_title("Kurtosis Test Null Distribution")
... ax.set_xlabel("statistic")
... ax.set_ylabel("probability density")
>>> kt_plot(ax)
>>> plt.show()
比较由 p 值量化:在双侧检验中,统计量为正时,零分布中大于观察统计量的元素和小于观察统计量的负值都被认为是“更极端”的值。
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> kt_plot(ax)
>>> pvalue = dist.cdf(-res.statistic) + dist.sf(res.statistic)
>>> annotation = (f'p-value={pvalue:.3f}\n(shaded area)')
>>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
>>> _ = ax.annotate(annotation, (3, 0.005), (3.25, 0.02), arrowprops=props)
>>> i = kt_val >= res.statistic
>>> ax.fill_between(kt_val[i], y1=0, y2=pdf[i], color='C0')
>>> i = kt_val <= -res.statistic
>>> ax.fill_between(kt_val[i], y1=0, y2=pdf[i], color='C0')
>>> ax.set_xlim(-5, 5)
>>> ax.set_ylim(0, 0.1)
>>> plt.show()
>>> res.pvalue
0.0211764592113868
如果 p 值“小” - 也就是说,从一个正态分布的人群中取样数据,产生如此极端的统计值的概率很低 - 这可能被视为反对零假设的证据,支持备择假设:权重并非来自正态分布。请注意:
-
反之则不成立;也就是说,该检验不能用来支持零假设。
-
被认为“小”的值的阈值是在分析数据之前应该做出的选择 [3],考虑到假阳性(错误地拒绝零假设)和假阴性(未能拒绝错误的零假设)的风险。
请注意,标准正态分布提供了零分布的渐近逼近;它仅适用于具有许多观察值的样本。这就是为什么我们在示例开始时收到了警告的原因;我们的样本非常小。在这种情况下,scipy.stats.monte_carlo_test可能提供更精确的,尽管是随机的精确 p 值的近似。
>>> def statistic(x, axis):
... # get just the skewtest statistic; ignore the p-value
... return stats.kurtosistest(x, axis=axis).statistic
>>> res = stats.monte_carlo_test(x, stats.norm.rvs, statistic)
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> kt_plot(ax)
>>> ax.hist(res.null_distribution, np.linspace(-5, 5, 50),
... density=True)
>>> ax.legend(['aymptotic approximation\n(many observations)',
... 'Monte Carlo approximation\n(11 observations)'])
>>> plt.show()
>>> res.pvalue
0.0272 # may vary
此外,尽管它们具有随机性质,以这种方式计算的 p 值可以用来精确控制零假设的错误拒绝率 [4]。
scipy.stats.normaltest
scipy.stats.normaltest(a, axis=0, nan_policy='propagate')
测试样本是否不同于正态分布。
此函数测试样本是否来自正态分布的零假设。基于 D’Agostino 和 Pearson 的[1], [2] 检验,结合偏度和峰度产生正态性的全能检验。
参数:
aarray_like
包含待测试样本的数组。
axisint 或 None,可选
计算测试的轴。默认为 0。如果为 None,则在整个数组 a 上计算。
nan_policy{‘propagate’, ‘raise’, ‘omit’},可选
定义输入包含 nan 时如何处理。可用以下选项(默认为 ‘propagate’):
- ‘propagate’: 返回 nan
- ‘raise’: 抛出错误
- ‘omit’: 在计算中忽略 nan 值
返回:
statisticfloat 或 数组
s² + k²,其中 s 是由 skewtest 返回的 z 分数,k 是由 kurtosistest 返回的 z 分数。
pvaluefloat 或 数组
双侧卡方检验的 p 值。
参考文献
[1] (1,2)
D’Agostino, R. B. (1971), “适用于中等和大样本量的正态性全能检验”, 生物统计学, 58, 341-348
[2] (1,2)
D’Agostino, R. 和 Pearson, E. S. (1973), “偏离正态性的检验”, 生物统计学, 60, 613-622
[3]
Shapiro, S. S., & Wilk, M. B. (1965). 完整样本的方差分析正态性检验。生物统计学, 52(3/4), 591-611.
[4]
B. Phipson 和 G. K. Smyth. “置换 p 值绝不能为零:当置换是随机抽取时计算精确 p 值。” 遗传与分子生物统计应用 9.1 (2010).
[5]
Panagiotakos, D. B. (2008). 生物医学研究中 p 值的价值。开放心血管医学期刊, 2, 97.
示例
假设我们希望根据测量推断成年人类男性体重在医学研究中是否不服从正态分布[3]。下面的数组 x 记录了体重(磅)。
>>> import numpy as np
>>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])
[1] 和 [2] 的正态性检验首先基于样本偏度和峰度计算统计量。
>>> from scipy import stats
>>> res = stats.normaltest(x)
>>> res.statistic
13.034263121192582
(测试警告我们的样本观测量太少,无法进行测试。我们将在示例结束时回到这个问题。) 因为正态分布具有零偏度和零(“过剩”或“费舍尔”)峰度,所以对于从正态分布中抽取的样本,该统计量的值趋向较低。
测试通过将统计量的观察值与空分布进行比较来执行:在空假设下,重量来自正态分布的统计值分布。对于这种正态性检验,对于非常大的样本,空分布是自由度为两的卡方分布。
>>> import matplotlib.pyplot as plt
>>> dist = stats.chi2(df=2)
>>> stat_vals = np.linspace(0, 16, 100)
>>> pdf = dist.pdf(stat_vals)
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> def plot(ax): # we'll reuse this
... ax.plot(stat_vals, pdf)
... ax.set_title("Normality Test Null Distribution")
... ax.set_xlabel("statistic")
... ax.set_ylabel("probability density")
>>> plot(ax)
>>> plt.show()
比较由 p 值量化:空分布中大于或等于观察到的统计量值的比例。
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> plot(ax)
>>> pvalue = dist.sf(res.statistic)
>>> annotation = (f'p-value={pvalue:.6f}\n(shaded area)')
>>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
>>> _ = ax.annotate(annotation, (13.5, 5e-4), (14, 5e-3), arrowprops=props)
>>> i = stat_vals >= res.statistic # index more extreme statistic values
>>> ax.fill_between(stat_vals[i], y1=0, y2=pdf[i])
>>> ax.set_xlim(8, 16)
>>> ax.set_ylim(0, 0.01)
>>> plt.show()
>>> res.pvalue
0.0014779023013100172
如果 p 值“较小” - 即从一个正态分布的总体中抽取数据得到该统计量的极端值的概率较低 - 这可能被视为支持备择假设而非原假设的证据:重量并非来自正态分布。注意:
-
反之不成立;即该检验不能用于提供支持空假设的证据。
-
将被视为“小”的值的阈值是在分析数据之前应该做出的选择 [4],考虑到误拒空假设(错误地拒绝空假设)和假阴性(未能拒绝错误的空假设)的风险。
请注意,卡方分布提供空分布的渐近近似;它仅对观测值较多的样本准确。这就是我们在示例开始时收到警告的原因;我们的样本相当小。在这种情况下,scipy.stats.monte_carlo_test 可能提供更准确的、虽然是随机的、对精确 p 值的近似。
>>> def statistic(x, axis):
... # Get only the `normaltest` statistic; ignore approximate p-value
... return stats.normaltest(x, axis=axis).statistic
>>> res = stats.monte_carlo_test(x, stats.norm.rvs, statistic,
... alternative='greater')
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> plot(ax)
>>> ax.hist(res.null_distribution, np.linspace(0, 25, 50),
... density=True)
>>> ax.legend(['aymptotic approximation (many observations)',
... 'Monte Carlo approximation (11 observations)'])
>>> ax.set_xlim(0, 14)
>>> plt.show()
>>> res.pvalue
0.0082 # may vary
此外,尽管其随机性,以这种方式计算的 p 值可以用来精确控制空假设的误拒率 [5]。
scipy.stats.jarque_bera
scipy.stats.jarque_bera(x, *, axis=None, nan_policy='propagate', keepdims=False)
在样本数据上执行 Jarque-Bera 拟合度检验。
Jarque-Bera 检验测试样本数据的偏度和峰度是否与正态分布匹配。
请注意,此测试仅适用于足够大量的数据样本(>2000),因为测试统计量在渐近上具有自由度为 2 的卡方分布。
参数:
x类似数组
随机变量的观察。
轴整数或无,默认:无
如果是 int,则是计算统计量的输入轴。输入的每个轴切片(例如行)的统计量将出现在输出的相应元素中。如果为None,则在计算统计量之前将拉直输入。
nan_policy{‘propagate’,‘omit’,‘raise’}
定义如何处理输入的 NaN。
-
propagate:如果沿着计算统计量的轴切片(例如行)存在 NaN,则输出的相应条目将是 NaN。 -
omit:执行计算时将省略 NaN。如果在计算统计量的轴切片中剩余的数据不足,则输出的相应条目将是 NaN。 -
raise:如果存在 NaN,则将引发ValueError。
keepdims布尔值,默认:False
如果设置为 True,则减少的轴将作为大小为一的维度保留在结果中。通过此选项,结果将正确地广播到输入数组。
返回:
结果显著性结果
具有以下属性的对象:
统计量浮点数
测试统计量。
p 值浮点数
假设检验的 p 值。
注解
自 SciPy 1.9 开始,np.matrix输入(不建议在新代码中使用)在执行计算之前将转换为np.ndarray。在这种情况下,输出将是一个标量或适当形状的np.ndarray,而不是 2D 的np.matrix。类似地,虽然忽略掩码数组的屏蔽元素,输出将是一个标量或np.ndarray,而不是具有mask=False的掩码数组。
参考文献
[1]
Jarque, C. 和 Bera, A. (1980) “回归残差的正态性、等方差性和序列独立性的有效检验”,6 Econometric Letters 255-259.
[2]
Shapiro, S. S., & Wilk, M. B. (1965). 正态性的方差分析检验(完整样本)。Biometrika,52(3/4),591-611。
[3]
B. Phipson 和 G. K. Smyth. “置换 p 值永远不应为零:在随机抽取置换时计算精确 p 值。” Statistical Applications in Genetics and Molecular Biology 9.1 (2010).
[4]
Panagiotakos, D. B. (2008). 生物医学研究中 p 值的价值。The open cardiovascular medicine journal, 2, 97.
示例
假设我们希望从测量中推断,医学研究中成年男性体重是否不服从正态分布[2]。下面数组x记录了体重(磅)。
>>> import numpy as np
>>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])
Jarque-Bera 测试首先计算基于样本偏度和峰度的统计量。
>>> from scipy import stats
>>> res = stats.jarque_bera(x)
>>> res.statistic
6.982848237344646
因为正态分布具有零偏度和零(“过量”或“Fisher”)峰度,这个统计量的值对于从正态分布中抽取的样本 tend to 较低。
测试通过比较统计量的观察值与零分布来执行:该统计值派生的零假设下的统计值分布,即权重来自正态分布。对于 Jarque-Bera 测试,非常大样本的零分布是具有两自由度的卡方分布。
>>> import matplotlib.pyplot as plt
>>> dist = stats.chi2(df=2)
>>> jb_val = np.linspace(0, 11, 100)
>>> pdf = dist.pdf(jb_val)
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> def jb_plot(ax): # we'll reuse this
... ax.plot(jb_val, pdf)
... ax.set_title("Jarque-Bera Null Distribution")
... ax.set_xlabel("statistic")
... ax.set_ylabel("probability density")
>>> jb_plot(ax)
>>> plt.show()
比较由 p 值量化:零分布中大于或等于统计量观察值的数值比例。
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> jb_plot(ax)
>>> pvalue = dist.sf(res.statistic)
>>> annotation = (f'p-value={pvalue:.6f}\n(shaded area)')
>>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
>>> _ = ax.annotate(annotation, (7.5, 0.01), (8, 0.05), arrowprops=props)
>>> i = jb_val >= res.statistic # indices of more extreme statistic values
>>> ax.fill_between(jb_val[i], y1=0, y2=pdf[i])
>>> ax.set_xlim(0, 11)
>>> ax.set_ylim(0, 0.3)
>>> plt.show()
>>> res.pvalue
0.03045746622458189
如果 p 值“小” - 也就是说,从正态分布人群中抽样产生统计量极端值的概率较低 - 这可能被视为反对零假设的证据,支持备选假设:体重未来自正态分布。请注意:
-
相反则不成立;即,该测试不用于提供支持零假设的证据。
-
将被认为是“小”的值的阈值是在分析数据之前应做出的选择[3],考虑到假阳性(错误地拒绝零假设)和假阴性(未能拒绝错误的零假设)的风险。
注意,卡方分布提供了零分布的渐近逼近;它仅对有大量观测样本的样本准确。对于像我们这样的小样本,scipy.stats.monte_carlo_test可能提供了一个更准确的,尽管是随机的,准确的 p 值近似。
>>> def statistic(x, axis):
... # underlying calculation of the Jarque Bera statistic
... s = stats.skew(x, axis=axis)
... k = stats.kurtosis(x, axis=axis)
... return x.shape[axis]/6 * (s**2 + k**2/4)
>>> res = stats.monte_carlo_test(x, stats.norm.rvs, statistic,
... alternative='greater')
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> jb_plot(ax)
>>> ax.hist(res.null_distribution, np.linspace(0, 10, 50),
... density=True)
>>> ax.legend(['aymptotic approximation (many observations)',
... 'Monte Carlo approximation (11 observations)'])
>>> plt.show()
>>> res.pvalue
0.0097 # may vary
此外,尽管它们具有随机性质,通过这种方式计算的 p 值可以用来精确控制零假设的虚假拒绝率[4]。
scipy.stats.shapiro
原文链接:
docs.scipy.org/doc/scipy-1.12.0/reference/generated/scipy.stats.shapiro.html#scipy.stats.shapiro
scipy.stats.shapiro(x)
执行 Shapiro-Wilk 正态性检验。
Shapiro-Wilk 测试检验的零假设是数据来自正态分布。
参数:
xarray_like
样本数据数组。
返回:
统计量float
检验统计量。
P 值float
假设检验的 P 值。
另请参见
anderson
Anderson-Darling 正态性检验
kstest
Kolmogorov-Smirnov 拟合优度检验。
注意事项
描述的算法见[4],但未实现所述的参数审查。对于 N > 5000,W 测试统计量是准确的,但 P 值可能不准确。
参考文献
[1]
www.itl.nist.gov/div898/handbook/prc/section2/prc213.htm DOI:10.18434/M32189
[2] (1,2)
Shapiro, S. S. & Wilk, M.B, “方差分析正态性检验(完全样本)”,1965 年,《生物统计学》,第 52 卷,第 591-611 页,DOI:10.2307/2333709
[3]
Razali, N. M. & Wah, Y. B., “Shapiro-Wilk、Kolmogorov-Smirnov、Lilliefors 和 Anderson-Darling 测试的功效比较”,2011 年,《统计建模与分析杂志》,第 2 卷,第 21-33 页。
[4]
Royston P., “备注 AS R94: 关于算法 AS 181 的备注:W-测试用于正态性”,1995 年,《应用统计学》,第 44 卷,DOI:10.2307/2986146
[5]
Phipson B., and Smyth, G. K., “当排列随机抽取时,置换 P 值不应为零:计算精确 P 值”,2010 年,《统计应用于遗传学和分子生物学》,第 9 卷,DOI:10.2202/1544-6115.1585
[6]
Panagiotakos, D. B., “在生物医学研究中 P 值的价值”,《开放心血管医学杂志》,2008 年,第 2 卷,第 97-99 页,DOI:10.2174/1874192400802010097
示例
假设我们希望根据测量数据推断医学研究中成年男性体重是否不服从正态分布[2]。以下是记录在数组x中的成年男性体重(磅)。
>>> import numpy as np
>>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])
[1]和[2]的正态性检验首先基于观测值与正态分布的预期顺序统计量之间的关系计算统计量。
>>> from scipy import stats
>>> res = stats.shapiro(x)
>>> res.statistic
0.7888147830963135
该统计量的值对于从正态分布中抽取的样本趋于高(接近 1)。
该检验通过比较统计量的观察值与零分布进行:统计值形成的分布在零假设下,即权重是从正态分布中抽取的。对于这个正态性检验,零分布不容易精确计算,因此通常通过蒙特卡罗方法来近似,即从一个与x相同大小的正态分布中抽取许多样本,并计算每个统计量的值。
>>> def statistic(x):
... # Get only the `shapiro` statistic; ignore its p-value
... return stats.shapiro(x).statistic
>>> ref = stats.monte_carlo_test(x, stats.norm.rvs, statistic,
... alternative='less')
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> bins = np.linspace(0.65, 1, 50)
>>> def plot(ax): # we'll reuse this
... ax.hist(ref.null_distribution, density=True, bins=bins)
... ax.set_title("Shapiro-Wilk Test Null Distribution \n"
... "(Monte Carlo Approximation, 11 Observations)")
... ax.set_xlabel("statistic")
... ax.set_ylabel("probability density")
>>> plot(ax)
>>> plt.show()
比较由 p 值量化:零分布中小于或等于统计量观察值的值的比例。
>>> fig, ax = plt.subplots(figsize=(8, 5))
>>> plot(ax)
>>> annotation = (f'p-value={res.pvalue:.6f}\n(highlighted area)')
>>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
>>> _ = ax.annotate(annotation, (0.75, 0.1), (0.68, 0.7), arrowprops=props)
>>> i_extreme = np.where(bins <= res.statistic)[0]
>>> for i in i_extreme:
... ax.patches[i].set_color('C1')
>>> plt.xlim(0.65, 0.9)
>>> plt.ylim(0, 4)
>>> plt.show
>>> res.pvalue
0.006703833118081093
如果 p 值“小” - 即从一个正态分布的总体中抽样数据,使得统计量的极端值的概率很低 - 这可能被视为反对零假设,支持备选假设:权重并非来自正态分布。注意:
-
逆反是不成立的;也就是说,该检验并不用于为零假设提供证据。
-
被视为“小”的值的阈值是在分析数据之前应作出的选择,考虑到假阳性(错误拒绝零假设)和假阴性(未能拒绝虚假的零假设)的风险 [5]。