学习总结
- 如为了判断两个城市的企业发展状况存不存在显著差异,需要将这些指标作为一个整体去研究,才能解决上述问题。而在多元数值向量的假设检验中,最常用的假设检验便是均值向量的假设检验。
- 多元部分就没有解决非正态性问题的非参数检验了。在多元领域,有一个检验和t检验非常类似——Hotelling T2检验,该检验在变量个数等于1时就退化成了t检验。本次学习的多元数值向量检验,均值向量检验中反复使用Hotelling T2检验。
- 多元均值向量检验中,成对检验的原理与一元均值检验的成对检验原理是相似的,本质上做两个均值向量之差与零向量的之间的单样本均值向量检验。
文章目录
零、背景介绍
思考问题:单变量问题和多变量问题的区别是什么——主要在于微观与宏观的区别。
单变量问题研究的是具体某一个指标的性质,而多变量问题则是将多个指标作为一个整体,用它们去描述一个对象的性质。
如果我们想要了解两个城市在某个指标上的差异,如企业的资产负债率,那么我们肯定使用的是单变量均值检验;如果问题变成了了解两个城市的企业发展状况的差异,我们还能使用单变量均值检验吗?肯定是不行的,因为企业发展状况需要用多个指标去共同描述。
问题:那我能不能分别对这些指标做单变量检验呢?
答:且不说如果指标有很多个,依次做单变量检验的工作量会很大;
最主要的问题是,难以通过这些分散的单变量检验回答诸如“两个城市的企业发展状况是否存在显著差异”的问题,假设在十个指标中,有三个指标有显著差异,七个指标没有显著差异,我们不可以认为两个城市的企业发展状况不存在显著差异。因此,需要将这些指标作为一个整体去研究,才能解决上述问题。而在多元数值向量的假设检验中,最常用的假设检验便是均值向量的假设检验。
一、均值向量的检验
多元数值数据中的组间均值向量假设检验的内容,我们主要学习如何通过样本数据对其所在多元总体的均值向量的性质进行检验,并展示如何在python中实现每个检验。均值向量检验的内容架构与均值检验的架构是一样的,主要内容有:
- 比较一组数据的总体均值向量与一个固定向量是否相等的检验
- 比较两组数据的总体均值向量之间是否相等的检验
- 比较两组以上的多组数据的总体均值向量之间是否相等的检验
多元部分就没有解决非正态性问题的非参数检验了。在多元领域,有一个检验和t检验非常类似——Hotelling T2检验,该检验在变量个数等于1时就退化成了t检验。在下面的均值向量检验中会反复使用Hotelling T2检验。
1.1 单组样本均值向量假定的检验
单组样本均值向量检验与单组样本的均值检验类似,只不过假定的对象从一个数值变成了一个向量。对于这个问题,我们可以使用单样本hotelling T2检验。
设 x 1 , ⋯ , x n \boldsymbol{x}_1,\cdots ,\boldsymbol{x}_n\, x1,⋯,xn来一个 p p p元正态分布的一个样本。对于单样本hotelling T2检验,我们做如下两个假设:
H 0 : μ = μ 0 ↔ H 1 : μ ≠ μ 0 H_0:\boldsymbol{\mu }=\boldsymbol{\mu }_0\leftrightarrow H_1:\boldsymbol{\mu }\ne \boldsymbol{\mu }_0\, H0:μ=μ0↔H1:μ=μ0
注意,这里的 μ \boldsymbol{\mu } μ是加粗的,代表向量的意思。
检验统计量为:
T e s t s t a t i s t i c s = n − p p ( n − 1 ) T 2 , T 2 = n ( x ˉ − μ 0 ) ′ S − 1 ( x ˉ − μ 0 ) Test\,\,statistics=\frac{n-p}{p\left( n-1 \right)}T^2\,\,, T^2=n\left( \boldsymbol{\bar{x}}-\boldsymbol{\mu }_0 \right) '\boldsymbol{S}^{-1}\left( \boldsymbol{\bar{x}}-\boldsymbol{\mu }_0 \right) Teststatistics=p(n−1)n−pT2,T2=n(xˉ−μ0)′S−1(xˉ−μ0)
其中, S \boldsymbol{S} S样本的无偏协方差矩阵
检验统计量服从分布
T e s t s t a t i s t i c s ∼ F ( p , n − p ) Test\,\,statistics\sim F\left( p,n-p \right) Teststatistics∼F(p,n−p)
p值计算公式为
p v a l u e = P ( F > T e s t s t a t i s t i c s ) pvalue=P\left( F>Test\,\,statistics \right) pvalue=P(F>Teststatistics)
注意,尽管备择假设的符号是 ≠ \ne =,但这里p值并不是双边p值,多元检验中p值形式的判断并不能沿用一元均值检验的判断方法。
Example.5 我们想研究某地区农村2岁男婴的发育状况是否达到国家参考标准,于是抽取了6名男婴并测量了他们的身高 x 1 x_1 x1、胸围 x 2 x_2 x2、上半臀围 x 3 x_3 x3。已知这三个指标的国家参考标准均值为 μ 0 = ( 90 , 58 , 16 ) ′ \boldsymbol{\mu }_0=\left( 90,58,16 \right) ' μ0=(90,58,16)′,6名男婴的数据如下所示,问能否认为该地区农村男婴的发育状况达到国家标准?
由于scipy
包中并没有Hotelling T2的api,因此我们需要使用上述的检验统计量及其分布自己编写假设检验。
# 构造一个函数,帮助我们进行单样本Hotelling T2检验
def multi_checkmean(data:pd.DataFrame,mean:np.ndarray,confidence=0.05):
'''
data:待比较的矩阵,格式最好为pd.DataFrame(),以列为变量,以行为样本。
mean:假定的均值向量,格式为numpy.ndarray。
'''
from scipy.stats import f
# 计算检验统计量
S=np.cov(data.T)
S_inv=np.linalg.inv(S)
x_bar=np.mean(data).values.T
T2=len(data)*np.dot((x_bar-mean).T,np.dot(S_inv,x_bar-mean))
Test_statistics=T2*(len(data)-len(mean))/(len(mean)*(len(data)-1))
# 计算p值
pvalue=f.sf(Test_statistics,len(mean),len(data)-len(mean))
# 输出样本的均值向量
print('样本均值向量为:{}'.format(x_bar))
print('目标均值向量为:{}'.format(mean))
# 比较p值与显著性水平
if pvalue<confidence:
print('在显著性水平{0:}下,样本均值向量不等于假定的均值向量。(p={1:.4f})'.format(confidence,pvalue))
else:
print('在显著性水平{0:}下,样本均值向量等于假定的均值向量。(p={1:.4f})'.format(confidence,pvalue))
return pvalue
# 目标均值向量
mean=np.array([90,58,16]).T #均值向量
multi_checkmean(data,mean)
"""
样本均值向量为:[82. 60.2 14.5]
目标均值向量为:[90 58 16]
在显著性水平0.05下,样本均值向量不等于假定的均值向量。(p=0.0022)
0.0021552720459323657
"""
结论:该地区农村男婴的发育状况与国家标准存在显著差异,且通过观察两个均值向量可以发现,农村男婴的发育状况低于国家标准。
1.2 两组样本之间的均值向量相等性检验
与单变量的双样本均值检验一样,双样本均值向量的检验同样分为组别间独立与组别成对两种情况,且判别两者的方法也是相同的。
(1)组别间独立
Example.6 想知道3周岁的男女婴儿的身体指标是否存在显著差异,于是各抽取了男女各15名婴儿,并测量了他们的身高 X 1 X_1 X1与体重 X 2 X_2 X2,问:在显著性水平0.05下能否认为两者存在显著差异?
由于两个样本性别不同,因此我们可以认为两个样本相互独立。
设两个样本 x 1 , ⋯ , x n 1 \boldsymbol{x}_1,\cdots ,\boldsymbol{x}_{n1}\, x1,⋯,xn1和 y 1 , ⋯ , y n 2 \boldsymbol{y}_1,\cdots ,\boldsymbol{y}_{n2}\, y1,⋯,yn2分别来自两个 p p p元正态分布,我们做如下两个假设:
H 0 : μ 1 = μ 2 ↔ H 1 : μ 1 ≠ μ 2 H_0:\boldsymbol{\mu_1 }=\boldsymbol{\mu }_2\leftrightarrow H_1:\boldsymbol{\mu_1 }\ne \boldsymbol{\mu }_2\, H0:μ1=μ2↔H1:μ1=μ2
检验统计量为:
T e s t s t a t i s t i c s = n 1 + n 2 − p − 1 p ( n 1 + n 2 − 2 ) T 2 , T 2 = n 1 n 2 n 1 + n 2 ( x ‾ − y ‾ ) ′ S p − 1 ( x ‾ − y ‾ ) , S p = ( n 1 − 1 ) S 1 + ( n 2 − 1 ) S 2 n 1 + n 2 − 2 Test\,\,statistics=\frac{n_1+n_2-p-1}{p\left( n_1+n_2-2 \right)}T^2\,\,, T^2=\frac{n_1n_2}{n_1+n_2}(\overline{\boldsymbol{x}}-\overline{\boldsymbol{y}})^{'}\boldsymbol{S}_{p}^{-1}(\overline{\boldsymbol{x}}-\overline{\boldsymbol{y}}) , \boldsymbol{S}_p=\frac{\left( n_1-1 \right) \boldsymbol{S}_1+\left( n_2-1 \right) \boldsymbol{S}_2}{n_1+n_2-2} Teststatistics=p(n1+n2−2)n1+n2−p−1T2,T2=n1+n2n1n2(x−y)′Sp−1(x−y),Sp=n1+n2−2(n1−1)S1+(n2−1)S2
检验统计量服从分布:
T e s t s t a t i s t i c s ∼ F ( p , n 1 + n 2 − p − 1 ) Test\,\,statistics\sim F\left( p,n_1+n_2-p-1 \right) Teststatistics∼F(p,n1+n2−p−1)
p值形式为:
p v a l u e = P ( F > T e s t s t a t i s t i c s ) pvalue=P\left( F>Test\,\,statistics \right) pvalue=P(F>Teststatistics)
data=pd.read_excel('./data/ex6.xlsx')
# 将两个独立样本分开成两组
group_boy=data[data['gender']=='b'].drop('gender',axis=1) # 去除性别标签列,只保留数值列
group_girl=data[data['gender']=='g'].drop('gender',axis=1)
def multi_unparied_data(group1:pd.DataFrame,group2:pd.DataFrame,confidence=0.05):
# 计算检验统计量
n1=len(group1)
n2=len(group2)
p=np.shape(group1)[1] # 变量维度
mean1=np.mean(group1).values.T
mean2=np.mean(group2).values.T
S1=np.cov(group1.T)
S2=np.cov(group2.T)
Sp=((n1-1)*S1+(n2-1)*S2)/(n1+n2-2)
T2=n1*n2*(mean1-mean2).T@np.linalg.inv(Sp)@(mean1-mean2)/(n1+n2)
Test_statistics=(n1+n2-p-1)*T2/(p*(n1+n2-2))
# 计算p值
from scipy.stats import f
pvalue=f.sf(Test_statistics,p,n1+n2-p-1)
# 比较p值与显著性水平
if pvalue<confidence:
print('在显著性水平{0:}下,两组样本所在总体的均值向量不相等。(p={1:.4f})'.format(confidence,pvalue))
else:
print('在显著性水平{0:}下,两组样本所在总体的均值向量相等。(p={1:.4f})'.format(confidence,pvalue))
return pvalue
multi_unparied_data(group_boy,group_girl)
"""
在显著性水平0.05下,两组样本所在总体的均值向量相等。(p=0.9396)
0.9396308874768952
"""
(2)成对组别
多元均值向量检验中,成对检验的原理与一元均值检验的成对检验原理是相似的,本质上做两个均值向量之差与零向量的之间的单样本均值向量检验。
设 ( x i , y i ) , i = 1 , ⋯ , n \left( \boldsymbol{x}_i,\boldsymbol{y}_i \right) \,\,, i=1,\cdots ,n (xi,yi),i=1,⋯,n为服从 p p p元正态分布的成对数据,令他们相减得:
d i = x i − y i \boldsymbol{d}_i=\boldsymbol{x}_i-\boldsymbol{y}_i di=xi−yi
检验统计量为:
T e s t s t a t i s t i c s = n − p p ( n − 1 ) T 2 , T 2 = n d ˉ ′ S d − 1 d ˉ Test\,\,statistics=\frac{n-p}{p\left( n-1 \right)}T^2\,\,, T^2=n\boldsymbol{\bar{d}}'\boldsymbol{S}_{\boldsymbol{d}}^{-1}\boldsymbol{\bar{d}} Teststatistics=p(n−1)n−pT2,T2=ndˉ′Sd−1dˉ
检验统计量服从分布:
T e s t s t a t i s t i c s ∼ F ( p , n − p ) Test\,\,statistics\sim F\left( p,n-p \right) Teststatistics∼F(p,n−p)
p值计算公式为
p v a l u e = P ( F > T e s t s t a t i s t i c s ) pvalue=P\left( F>Test\,\,statistics \right) pvalue=P(F>Teststatistics)
def multi_paried_data(group1:pd.DataFrame,group2:pd.DataFrame,confidence=0.05):
# 计算检验统计量值
n=len(group1)
p=np.shape(group1)[1]
mean1=np.mean(group1).values.T
mean2=np.mean(group2).values.T
d=group1-group2
d_mean=mean1-mean2
Sd=np.cov(d.T)
Sd_inv=np.linalg.inv(Sd)
T2=n*d_mean.T@Sd_inv@d_mean
Test_statistics=(n-p)*T2/(p*(n-1))
# 计算p值
from scipy.stats import f
pvalue=f.sf(Test_statistics,p,n-p)
# 比较p值与显著性水平
if pvalue<confidence:
print('在显著性水平{0:}下,两组样本所在总体的均值向量不相等。(p={1:.4f})'.format(confidence,pvalue))
else:
print('在显著性水平{0:}下,两组样本所在总体的均值向量相等。(p={1:.4f})'.format(confidence,pvalue))
return pvalue
1.3 多元方差分析-多组样本间的均值向量相等性比较
多元方差分析与一元方差分析研究的内容是相似的,只是前者研究的是多个总体均值向量的相等性,而后者是均值的相等性。多元方差分析的检验统计量被称为威尔克斯(Wilks) Λ \varLambda Λ统计量,该统计量服从的分布为 Λ \varLambda Λ分布。
- 这个分布的分位点值可通过查F分布表得到,两者的转换非常复杂。
- 但是
statsmodels.multivariate.manova
模块有多元方差分析(MANOVA)的api。
Example.8 某医生测量了16个正常人的早晨中3个小时各小时的低频心电频值谱(LF)与高频心电频值谱(HF),数据在下面给出,问:这16个人的两个指标表现在3次测量中有无显著的差别?
分析:由于问题考察的变量有两个:LF与HF,因此这是一个多元问题;又由于样本有三个:早晨的3次测量,因此这是一个多组均值比较问题。结合以上分析,该问题是一个(单因素)多元方差分析问题。
data=pd.read_excel('./data/ex8.xlsx')
group_1=data[data['Time']==1].drop('Time',axis=1).reset_index(drop=True)
group_2=data[data['Time']==2].drop('Time',axis=1).reset_index(drop=True)
group_3=data[data['Time']==3].drop('Time',axis=1).reset_index(drop=True)
from statsmodels.multivariate.manova import MANOVA
model=MANOVA.from_formula('LF + HF ~ Time', data=data).mv_test()
# 在''中填入公式,其中~左侧填入自变量名称,~右侧填入因素名称
print(model.results['Time']['stat'])
"""
Value Num DF Den DF F Value Pr > F
Wilks' lambda 0.99114 2 45.0 0.201139 0.81853
Pillai's trace 0.00886 2.0 45.0 0.201139 0.81853
Hotelling-Lawley trace 0.008939 2 45.0 0.201139 0.81853
Roy's greatest root 0.008939 2 45 0.201139 0.81853
"""
注:只需要看Wilks’ lambda的p值即可。此处p值为0.81853,显然我们不能拒绝原假设,3次测量没有显著区别。
二、从多元到一元——寻找显著的变量
多元均值向量的检验可以告诉我们不同分析对象的某个宏观性质(如城市企业的发展状况)是否存在显著区别,如果我们拒绝了原假设,便可以说明它们确实存在显著区别。但是在实际分析中,仅仅得出“它们存在显著区别”的结论是远远不够的,我们会想知道,究竟是什么变量导致了这种显著区别呢?这个时候,我们就要是用一元的均值向量检验来回答这一问题。在实际分析当中,往往都是始于“多元”,终于“一元”。
Example.9 为了研究3种销售方式对商品销售额的影响,我们选择了4种商品按照这3种销售方式进行销售。这四种商品的销售额分别为x1,x2,x3,x4。数据如下所示,请用多元/一元假设检验方法对该问题进行研究分析。
简单分析:该例中有三个样本,因此我们会使用方差分析进行研究;销售额方面,本例用了四个商品的销售额去衡量,也就是说变量有4个,因此在分析的第一步我们可以使用多元方差分析,分析三种销售方式在“宏观”上是否会给商品销售额带来影响。
# 先做多元方差分析
model=MANOVA.from_formula('x1 + x2 + x3 + x4 ~ sale', data=data).mv_test()
print(model.results['sale']['stat'])
"""
Value Num DF Den DF F Value Pr > F
Wilks' lambda 0.749149 4 55.0 4.604152 0.002807
Pillai's trace 0.250851 4.0 55.0 4.604152 0.002807
Hotelling-Lawley trace 0.334847 4 55.0 4.604152 0.002807
Roy's greatest root 0.334847 4 55 4.604152 0.002807
"""
p值为0.002807,显然三种销售方式的均值向量不全部相等。这三种销售方式的显著差异究竟是由哪些商品引起的呢?这个问题可以转化成——这三种销售方式会对哪种商品的销售产生显著的差异,为了研究这个问题,我们可以分别对变量x1,x2,x3,x4做一元方差分析。
# 分别检验
## 先分组
group_1=data[data['sale']==1].drop('sale',axis=1).reset_index(drop=True)
group_2=data[data['sale']==2].drop('sale',axis=1).reset_index(drop=True)
group_3=data[data['sale']==3].drop('sale',axis=1).reset_index(drop=True)
## 分别做单变量方差检验
print(stats.f_oneway(group_1.x1.values,group_2.x1.values,group_3.x1.values))
print(stats.f_oneway(group_1.x2.values,group_2.x2.values,group_3.x2.values))
print(stats.f_oneway(group_1.x3.values,group_2.x3.values,group_3.x3.values))
print(stats.f_oneway(group_1.x4.values,group_2.x4.values,group_3.x4.values))
"""
F_onewayResult(statistic=3.3766410140335, pvalue=0.04112546209315577)
F_onewayResult(statistic=1.6154481009614068, pvalue=0.2077698930751813)
F_onewayResult(statistic=0.16557150166792145, pvalue=0.8478153535976287)
F_onewayResult(statistic=8.008491041468082, pvalue=0.0008607020541776114)
"""
x2-x3的p值很大,因此我们可以认为这三种销售方式对于商品2/3而言不会产生显著的影响;x1、x4的p值小于0.05,且x4的p值尤其小,我们猜测,可能是商品4销售额均值的差异引起了均值向量的差异。对于该问题,我们可以剔除x4,对x1~x3再做一次多元方差分析:
# 去掉变量x4,再做一次多元方差分析
model=MANOVA.from_formula('x1 + x2 + x3 ~ sale', data=data).mv_test()
print(model.results['sale']['stat'])
"""
Value Num DF Den DF F Value Pr > F
Wilks' lambda 0.976477 3 56.0 0.449666 0.718524
Pillai's trace 0.023523 3.0 56.0 0.449666 0.718524
Hotelling-Lawley trace 0.024089 3 56.0 0.449666 0.718524
Roy's greatest root 0.024089 3 56 0.449666 0.718524
"""
去除了x4后,多元方差分析检验不显著,因此说明对于商品1/2/3而言,三种销售方式的总体均值向量之间没有显著差异;此外,尽管对x1单独进行方差分析是显著的,可是x1~x3一起做多元方差分析时却不显著,这说明商品1对三种销售方式的差异无明显影响,即“你的差异影响不了大伙”。
三、小练习
为研究东、中、西部各省市规模以上的企业发展状况,我们收集了各城市企业的主要经济指标,包括:总资产贡献率、资产负债率、流动资产周转次数、工业成本费用利润率、产品销售率。我们用变量“类别”定义了各类城市,其中1为东部城市;2为中部城市;3为西部城市。数据文件为homework2.xlsx
。假设显著性水平为 α \alpha α。
先加载需要的包和看对应数据:
加载必要的包
import numpy as np
import pandas as pd
from scipy import stats
import matplotlib.pyplot as plt
from IPython.display import display
加载数据
data = pd.read_excel('./data/homework2.xlsx')
group1 = data[data['类别']==1].drop(['类别','地区'],axis=1).reset_index(drop=True)
group2 = data[data['类别']==2].drop(['类别','地区'],axis=1).reset_index(drop=True)
group3 = data[data['类别']==3].drop(['类别','地区'],axis=1).reset_index(drop=True)
data
(1)对三个类别的城市进行均值向量间的两两比较,查看结果
def multi_unparied_data(group1:pd.DataFrame,group2:pd.DataFrame,confidence=0.05):
# 计算检验统计量
n1=len(group1)
n2=len(group2)
p=np.shape(group1)[1] # 变量维度
mean1=np.mean(group1).values.T
mean2=np.mean(group2).values.T
S1=np.cov(group1.T)
S2=np.cov(group2.T)
Sp=((n1-1)*S1+(n2-1)*S2)/(n1+n2-2)
T2=n1*n2*(mean1-mean2).T@np.linalg.inv(Sp)@(mean1-mean2)/(n1+n2)
Test_statistics=(n1+n2-p-1)*T2/(p*(n1+n2-2))
# 计算p值
from scipy.stats import f
pvalue=f.sf(Test_statistics,p,n1+n2-p-1)
# 比较p值与显著性水平
if pvalue<confidence:
print('在显著性水平{0:}下,两组样本所在总体的均值向量不相等。(p={1:.4f})'.format(confidence,pvalue))
else:
print('在显著性水平{0:}下,两组样本所在总体的均值向量相等。(p={1:.4f})'.format(confidence,pvalue))
return pvalue
# 东部城市和中部城市两组样本之间的均值向量相等性检验结果
multi_unparied_data(group1,group2)
# 中部地区与西部地区
multi_unparied_data(group2,group3)
# 东部地区与西部地区
multi_unparied_data(group1,group3)
"""
在显著性水平0.01下,两组样本所在总体的均值向量相等。(p=0.2793) 企业发展相似。
在显著性水平0.01下,两组样本所在总体的均值向量相等。(p=0.0470) 企业发展相似。
在显著性水平0.01下,两组样本所在总体的均值向量不相等。(p=0.0097) 企业发展不相似。
"""
(2)对三个类别的城市同时进行均值向量间的比较,查看结果
多元方差分析。
from statsmodels.multivariate.manova import MANOVA
model=MANOVA.from_formula('总资产贡献率 + 资产负债率 + 流动资产周转次数 + 工业成本费用利润率 + 产品销售率 ~ 类别', data=data).mv_test()
# 在''中填入公式,其中~左侧填入自变量名称,~右侧填入因素名称
print(model.results['类别']['stat'])
"""
Value Num DF Den DF F Value Pr > F
Wilks' lambda 0.535029 5 25.0 4.345284 0.005542
Pillai's trace 0.464971 5.0 25.0 4.345284 0.005542
Hotelling-Lawley trace 0.869057 5 25.0 4.345284 0.005542
Roy's greatest root 0.869057 5 25 4.345284 0.005542
"""
只需看Wilks’ lambda的p值即可,mzheli 。此处p值为0.005542。
(3)承接问题2,你认为哪些变量导致了三个类别城市均值向量的差异?说出你的理由。
附:时间安排
Task | 内容 | 时间 |
---|---|---|
Task01 | 假设检验1:方法论与一元数值检验 | 8-13 —— 8-18周四 |
Task02 | 假设检验2:多元数值向量检验 | 8-19 —— 8-20周六 |
Task03 | 假设检验3:分类数据检验 | 8-21 —— 8-22周一 |
Task04 | 应用随机过程与仿真系统 | 8-23 —— 8-25周四 |
Task05 | 金融量化分析与随机模拟 | 8-26 —— 9-28周日 |
Reference
[1] https://github.com/Git-Model/Modeling-Universe/tree/main/Data-Story