描述数据、查看数据分布、数据的假设检验——python实现

前言

 我们拿到数据的初步工作往往是对数据进行描述(描述统计量,图表),查看数据的分布,比较数据之间的关系,进而对数据进行假设检验或建模等。

 接下来我们看如何用python实现上述工作(持续更新)。

1. Measures of Location
1.1 均值
1.2 中位数
1.3 最大值和最小值
1.4 分位数

2. Measures of Dispersion
2.1 方差和标准差
2.2 极差
2.3 变异系数
2.4 偏度(Skewness)
2.5 峰度(Kurtosis)

3. Measures of Distribution
3.1 Shapiro-Wilk Test
3.2 Kolmogorov-Smirnov Test

4. Hypotheses Testing
4.1 t检验
  4.1.1 单样本t-检验
  4.1.2 双样本t-检验
  4.1.3 配对样本t-检验
  4.1.4 单边t-检验

1. Measures of Location

1.1 均值

语法:np.mean(a, axis=None)

说明:当数据a为高维数据时,可指定axis进行以行求平均或以列求平均,axis=0为按列求平均,axis=1为按行求平均

import numpy as np
data = np.arange(20) #[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
data_mean = np.mean(data)
print(data_mean)

输出: 9.5 9.5 9.5

1.2 中位数

语法:np.median(a)

data_median = np.median(data)
print(data_median)

输出: 9.5 9.5 9.5

1.3 最大值和最小值

语法:np.max()和np.min()

data_max = np.max(data)
data_min = np.min(data)
print(data_max)
print(data_min)

结果:19,0

1.4 分位数

语法:np.quantile(a, q)

说明:q为要计算的分位数或分位数序列,必须在0到1之间(含0和1)。 常用的为0.250.45,即下四分位数上四分位数

#将q设置为0.25,求下四分位数
data_q1 = np.quantile(data, q=0.25)
#将q设置为0.75,求上四分位数
data_q2 = np.quantile(data, q=0.75)
print(data_q1)
print(data_q2)

输出:4.75,14.25

2. Measures of Dispersion

2.1 方差和标准差

语法:方差为np.var(),标准差为np.std()

说明:这里计算方差的公式为: S 2 = 1 n ∑ i = 1 n ( x i − x ˉ ) 2 S^2=\frac{1}{n}\sum_{i=1}^n{(x_i-\bar{x})^2} S2=n1i=1n(xixˉ)2,这里是 n n n,而在很多情形下,要求的是 n − 1 n-1 n1,而只需先乘以 n n n再除以 n − 1 n-1 n1即可。

data_v = np.var(data)
data_s = np.std(data)
print(data_v)
print(data_s)

输出:33.25,5.766281297335398

2.2 极差

语法:np.ptp()或np.max() - np.min()

data_r = np.ptp(data)
print(data_r)

输出:19

2.3 变异系数

 变异系数是原始数据标准差与原始数据平均数的比,反映数据离散程度的绝对值,当两组数据量纲不同或测量尺度相差太大时,可以进行客观比较。

语法:这个python并没有专门的函数,不过我们根据 c v = s t d x ˉ cv=\frac{std}{\bar{x}} cv=xˉstd,可以自行编写:np.std() / np.mean()

data_cv = np.std(data) / np.mean(data)
print(data_cv)

输出:0.606976978666884

2.4 偏度(Skewness)

 公式: S k e w n e s s ( X ) = E [ ( X − μ σ ) 3 ] Skewness(X)=E[(\frac{X-\mu}{\sigma})^3] Skewness(X)=E[(σXμ)3]

 偏度是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征, 直观看来就是密度函数曲线尾部的相对长度。

 正态分布的偏度为 0 0 0,两侧尾部长度对称;偏度小于 0 0 0时,左偏,此时数据位于均值左边的比位于右边的少,直观表现为左边的尾部相对于与右边的尾部要长;偏度大于 0 0 0时,右偏,此时数据位于均值右边的比位于左边的少,直观表现为右边的尾部相对于与左边的尾部要长。

语法:scipy.stats.skew(a)或pandas.Series().skew()或pandas.DataFrame().skew()

说明:pandas.Series().skew()或pandas.DataFrame().skew()是说对series对象或dataframe对象直接调用skew()

from scipy import stats

#以scipy.stats.kurtosis(a)为例
data_skew = stats.skew(data)
print(data_skew)

输出:0,因为我们的数据是[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19],是对称的。

2.5 峰度(Kurtosis)

 公式: K u r t o s i s ( X ) = E [ ( X − μ σ ) 4 ] Kurtosis(X)=E[(\frac{X-\mu}{\sigma})^4] Kurtosis(X)=E[(σXμ)4]

 峰度表征概率密度分布曲线在平均值处峰值高低的特征数。直观看来,峰度反映了峰部的尖度.

 正态分布的峰度为3。以一般而言,正态分布为参照,因此计算时会减去3(python包里也是这样)。峰度可以描述分布形态的陡缓程度,若峰度小于0,则称分布具有不足的峰度,直观上就是峰的形状比较尖,比正态分布峰要陡峭;若峰度大于0,则称分布具有过度的峰度,直观上就是峰的形状比较钝,没有正态分布峰陡峭;

语法:scipy.stats.kurtosis(a)或pandas.Series().kurtosis()或pandas.DataFrame().kurtosis()

说明:这几个包里的函数都是减去3了的,因此正态分布的峰度为0。可自行检验(先生成服从正态分布的随机数,指定分布随机数生成方法,再把数据代入)

#以scipy.stats.kurtosis(a)为例
data_kurt= stats.kurtosis(data)
print(data_kurt)

输出:-1.206015037593985

3 Measures of Distribution

3.1 Shapiro-Wilk Test

 Shapiro-Wilk Test(夏皮罗-威尔克检验)是一种在频率上检验小样本数据(样本量小于等于50)正态性的方法,它的零假设是总体呈正态分布。

import numpy as np
from scipy import stats

#先产生50个服从标准正态分布的样本
np.random.seed(2020)
data_ran = np.random.normal(0, 1, 50)

#用scipy.stats.shapiro()进行Shapiro-Wilk Test检验其是否服从正态分布
result = stats.shapiro(data_ran)
print(result)
#输出的第一个值为检验统计量,越大说明和正态分布拟合的越好,
#输出的第二个值为p值,如果小于给定的α值,那么拒绝原假设,即说明样本数据不服从正态分布

输出:ShapiroResult(statistic=0.9700697660446167, pvalue=0.23296509683132172)

3.2 Kolmogorov-Smirnov Test(K-S检验)

 Kolmogorov-Smirnov Test分为单样本和双样本。
 对于单样本,K-S检验基于累计分布函数,可以检验样本数据的经验分布与另一个理论分布是否不同,原假设是数据符合理论分布,备择假设可以是双边假设或者单边假设;
 对于双样本,K-S检验基于累计分布函数,可以检验两个样本数据的经验分布是否不同,原假设是数据符合理论分布两个数据分布一致。

语法
 单样本——scipy.stats.kstest(rvs, cdf, args=(), alternative=‘two-sided’)
 双样本——scipy.stats.ks_2samp(data1, data2, alternative=‘two-sided’)

说明
单样本
rvs是数据,可以是数组型,不过必须是一维的;也可以是callable(可调用的对象),不过此时必须是生成随机变量的函数。
cdf是待比较的理论分布,可以是字符串,不过必须是’scipy.stats’里面的,比如正态分布是’norm’,t分布是’t’。
args=()是cdf的参数,为元组类型,比如cdf=‘norm’时,默认的是均值为0,标准差为1,可以通过args=(1, 2),将理论分布的均值为1,标准差为2;如果cdf=‘t’,t分布只有一个自由度的参数,此时可以设args=(1, )。注意:t分布必须设置此参数,正态分布不用,默认为(0, 1)。
alternative是设置备择假设,默认为双边假设,可选择{‘two-sided’, ‘less’, ‘greater’}

双样本——data1, data2为两个样本的数据,维度不一定要相同;alternative同上。

import numpy as np
from scipy import stats

#先产生10000个服从标准正态分布的样本
np.random.seed(2020)
data_ran = np.random.normal(0, 1, 10000)
#用scipy.stats.kstest()进行我们生成的单样本是否服从正态分布
results = stats.kstest(data_ran, 'norm')
print(results)
#生成的第一个值为统计量,越小,说明样本数据的经验分布和理论分布越相似
#生成的第一个值为p值,当小于给定的α时,拒绝备择假设,即样本数据的经验分布和理论分布不相同

输出:KstestResult(statistic=0.008834024961597298, pvalue=0.4136790491750736)

4. Hypotheses Testing

4.1 t-检验

详见:t检验

 t检验的前提是要求样本服从正态分布或近似正态分布(情景2还需要满足方差齐性),不然可以利用一些变换(取对数、开根号、倒数等等)试图将其转化为服从正态分布是数据。不过当样本量大于30的时候,可以认为数据近似正态分布。

 t检验最常见的四个用途:
 1. 单样本均值检验:用于检验总体方差未知、正态数据或近似正态的单样本的均值是否与已知的总体均值相等;
 2. 两独立样本均值检验:用于检验两对独立的正态数据或近似正态的样本的均值是否相等,这里可根据总体方差是否相等分类讨论;
 3. 配对样本均值检验:用于检验一对配对样本的均值的差是否等于某一个值;
 4. 回归系数的显著性检验:用于检验 回归模型的解释变量对被解释变量是否有显著影响。

4.1.1 单样本t-检验

语法:scipy.stats.ttest_1samp(a)

#先产生50个服从标准正态分布的样本
np.random.seed(2020)
data_ran = np.random.normal(0, 1, 50)
#分别检验数据的均值是0还是1
r1 = stats.ttest_1samp(data_ran, 0)
r2 = stats.ttest_1samp(data_ran, 1)
print(r1)
print(r2)
#结果输出两个值,第一个值是统计量,第二个值是相应的p值,如果p值小于给定的α,就拒绝原假设,即数据的均值不是我们设置的数

输出
Ttest_1sampResult(statistic=-0.7624073055815211, pvalue=0.4494715663983747)
Ttest_1sampResult(statistic=-8.118276860613589, pvalue=1.2606057633242357e-10)

4.1.2 双样本t-检验

语法:scipy.stats.ttest_ind(a, b, equal_var=True)
说明:a, b为待比较的样本数据;当两组独立样本的方差(近似)相等时,可将equal_var设为True,否则将其设为False。如果两总体具有方差齐性,错将equal_var设为False,p值变大;两总体方差不等时,若没有将equal_var参数设定为False,则函数会默认equal_var为True,这样会低估p值。(如何检验两组数据的方差是否相等)

#先产生50个服从标准正态分布的样本和50个均值为0方差为4的数据
np.random.seed(2020)
data_ran = np.random.normal(0, 1, 50)
data_ran2 = np.random.normal(0, 2, 50)
#检验两组数据的均值是否相等,由于它们的方差不相等,因此将equal_var设为False
r1 = stats.ttest_ind(data_ran, data_ran2, equal_var=False)
print(r1)

输出:Ttest_indResult(statistic=-1.1267140774455147, pvalue=0.26355948862913453)

4.1.3 配对样本t-检验

语法:scipy.stats.ttest_rel(a, b)

#先产生50个服从标准正态分布的样本和50个均值为0方差为4的数据
np.random.seed(2020)
data_ran = np.random.normal(0, 1, 50)
data_ran2 = np.random.normal(0, 2, 50)
#检验两组数据的均值的差是否为0(试验结果应该为接收原假设)
r1 = stats.ttest_rel(data_ran, data_ran2)
print(r1)

输出:Ttest_relResult(statistic=-1.1314473367025755, pvalue=0.26337401761631224)

4.1.4 单边t-检验

 以上几种t检验都是双边t检验,即 H 0 : μ 1 = μ 2 − − − H 1 : μ 1 ≠ μ 2 H_0:\mu_1=\mu_{2}---H_1:\mu_1≠\mu2 H0:μ1=μ2H1:μ1=μ2。有时我们想进行单边t检验,即 H 0 : μ 1 ≤ μ 2 − − − H 1 : μ 1 > μ 2 H_0:\mu_1≤\mu_{2}---H_1:\mu_1>\mu_2 H0:μ1μ2H1:μ1μ2 H 0 : μ 1 ≥ μ 2 − − − H 1 : μ 1 < μ 2 H_0:\mu_1≥\mu_{2}---H_1:\mu_1<\mu_2 H0:μ1μ2H1:μ1μ2
 但以上结果仍可以用,只不过需要将最后得到的 p p p值除以 2 2 2作为单边的阈值。
 还有一点要注意的是,对于ttest_ind(a, b)和ttest_rel(a, b),是默认a.mean() − - b.mean(),因此,如果想得到正的结果,要将大的平均值放前面。

猜你喜欢

转载自blog.csdn.net/TSzero/article/details/111858334