单样本t检验
单样本 t 检验是对总体均值的假设检验。原假设为总体均值=μ0,备择假设为总体均值≠μ0,现计算出样本均值为x,样本标准差为S,检验的统计量服从t分布:t=(x-μ0)/S,若计算出的P值小于显著性水平则拒绝原假设,认为该样本不是出自均值为μ0的总体。
以房价增长率数据为例,原假设中总体均值为10%,样本住房增长率均值为11%,进行单样本t检验:
import pandas as pd
from scipy import stats
import statsmodels.api as sm
df=pd.read_csv('C:/Users/lenovo/Desktop/house_price_gr.csv',encoding='gbk')
df.rate.mean()
Out[1]: 0.11006099670192315
d1=sm.stats.DescrStatsW(df.rate)
#descriptive statistics and tests with weights for case weights
print('t统计量:%.4f,P值:%.4f,df=%s' %d1.ttest_mean(0.1))
t统计量:2.9812,P值:0.0034,df=149.0
可见P值远小于0.05,可以拒绝原假设,总体均值为10%的说法在95%的置信水平下不可信。
双样本t检验(连续变量与二分类变量)
单样本 t 检验是在比较假设的总体平均数与样本平均数的差异是否显著,双样本 t 检验在于检验两个样本均值的差异是否显著。在数据分析中,双样本t检验常用于检验某二分类变量区分下的某连续变量(通常是被解释变量)是否有显著差异,比如研究信用卡的消费额受性别的影响是否显著。
card=pd.read_csv('C:/Users/lenovo/Desktop/creditcard_exp.csv',skipinitialspace=True)#忽略分隔符后的空白
card=card.dropna(how='any')#删除表中含有任意个数NaN的行
card.head()
Out[3]:
id Acc avg_exp avg_exp_ln ... dist_avg_income age2 high_avg edu_class
0 19 1 1217.03 7.104169 ... 15.932789 1600 0.102361 3
1 5 1 1251.50 7.132098 ... 15.796316 1024 0.051184 2
3 86 1 856.57 6.752936 ... 11.275632 1681 0.197218 3
4 50 1 1321.83 7.186772 ... 13.346474 784 0.062676 2
5 67 1 816.03 6.704451 ... 10.332263 1681 -0.302113 3
其中变量avg_exp为信用卡消费额,gender为性别(0为男性,1为女性)。先对消费额按照性别分类汇总:
card['avg_exp'].groupby(card['gender']).describe()
Out[9]:
count mean std min 25% 50% 75% \
gender
0 50.0 925.7052 430.833365 163.18 593.3125 813.650 1204.7775
1 20.0 1128.5310 462.281389 648.15 829.8600 1020.005 1238.2025
max
gender
0 1992.39
1 2430.03
根据均值来看,平均消费额的差异还是比较明显的,女性的消费额要比男性多。接下来用双样本 t 检验看这种差异是否显著。双样本t检验流程如下:
- 获取两组样本数据(假设均服从正态分布)。
- 进行方差齐性检验,即F检验。
- 若方差齐,则进行方差齐的双样本t检验;若不齐,则进行方差不齐的双样本t检验。
方差齐性检验的假设和F统计量如图:
先进行方差齐性检验,即男性消费样本与女性消费样本的方差是否相同:
gender0 = card[card['gender']==0]['avg_exp']
gender1 = card[card['gender']==1]['avg_exp']
leveneTestRes = stats.levene(gender0,gender1)
#levene是方差齐性检验的包
print('statistic=%.4f, p-va1ue=%.4f' %leveneTestRes)
statistic=0.0683, p-va1ue=0.7946
P值接近0.8,不能拒绝原假设,认为两个样本方差齐性。因此可以进行方差齐性的双样本 t 检验(equal_var=True):
stats.stats.ttest_ind(gender0,gender1,equal_var=True)
Out[12]: Ttest_indResult(statistic=-1.742901386808629, pvalue=0.08587122878448449)
P值为0.08,若显著性水平为5%,说明不能拒绝原假设(无显著差异),男性和女性在信用卡消费上无显著差异。
注意这里双样本t检验研究的是一个连续变量和一个二元分类变量(性别)之间的关系,若分类变量为多元的,比如受教育程度(4个等级),则可以使用单因素方差分析法;如果研究一个连续变量受不止一个分类变量的影响,则可以使用多因素方差分析法,这两类方法在下一篇文章中介绍。
卡方检验(分类变量之间)
如何分析两个分类变量之间的相关关系呢?如果其中一个变量的分布随着另一个变量的变化而发生变化时,那么两个分类变量就有关系。在具体操作时,可以通过列联表分析与卡方检验得以实现。
列联表
列联表是一种常见的分类汇总表, 该表将待分析的两分类变量中一个变量的每一个类别设为列变量,另一个变量的每一个类别设为行变量,中间对应着不同变量不同类别下的频数。接下来探索分类变量是否违约(bad_ind)与分类变量是否破产(bankruptcy_ind)的关系,在Pandas中可以使用crosstab函数生成列联表。
accepts=pd.read_csv('C:/Users/lenovo/Desktop/accepts.csv')
cross_table=pd.crosstab(accepts.bankruptcy_ind,columns=accepts.bad_ind,margins=True)
cross_table
Out[26]:
bad_ind 0 1 All
bankruptcy_ind
N 4163 1017 5180
Y 345 103 448
All 4508 1120 5628
列联表显示破产状态(bankrupcy_ind=‘Y’)且违约状态正常(bad_ind =0)的客户有345个,破产状态(bankrupcy_ind=‘Y’) 且违约状态不正常(bad_ind=1)的客户相对较少,有103个。由于样本量的不同(bankrupcy_ind中N有5180个,而Y仅有448个),频数的差异不能直接反应离散变量之间的关系,我们需要将其转换为频率。例如将每个频数与行总计相数相除,就可以得到行百分比,代码如下所示:
cross_table_rowpct = cross_table.div(cross_table['All'],axis=0)
cross_table_rowpct
Out[27]:
bad_ind 0 1 All
bankruptcy_ind
N 0.803668 0.196332 1.0
Y 0.770089 0.229911 1.0
All 0.800995 0.199005 1.0
可以看到破产状态的(bankruptcy_ind=‘Y’)客户违约率为22.99%,非破产状态(bankruptcy ind=‘N’)的客户违约率为19.6%。如果我们认为这两个违约率没有差异(纵向比较),那么说明是否破产与是否违约不相关。同理可以将交叉表中的每个频数与列总计相除,计算所谓列轮廓并进行横向的比较,其结论应与比较行轮廓的结论是一致的:
cross_table_colpct = cross_table.div(cross_table.loc['All'],axis=1)
cross_table_colpct
Out[29]:
bad_ind 0 1 All
bankruptcy_ind
N 0.923469 0.908036 0.920398
Y 0.076531 0.091964 0.079602
All 1.000000 1.000000 1.000000
即无论是否违约,基本上都来自于没有破产的客户,因此是否破产和是否违约之间的相关关系应该不大。
列联表对比后发现的差异是否显著,需要在统计学意义上进行检验,可以使用卡方检验。
卡方检验
卡方检验的思想在于比较期望频数和实际频数的吻合程度,这里的实际频数指单元格内实际的观测数量(即上面生成的列联表),期望频数指行变量某类别与列变量某类别互相独立的时候的频数。
比如在期望频率表中,“破产=N”和“违约=0”的期望频率计算方法为92%×80.1%=73.7%,即假设两事件相互独立时的概率,最后再乘样本数量5628得到期望频数4149。期望频数的整个计算过程化简后为:
期望频数 = (行总/样本量 × 列总/样本量) × 样本量 = (行总 × 列总)/样本量。
同样,其他的单元格期望频数与实际频数的差异都可以计算出来。这些差异是否能够表明两个分类变量的差异具有统计学意义需要继续进行卡方检验。卡方检验的原假设是期望频数等于实际频数,即两个分类变量无关,备择假设为期望频数不等于实际频数,即两个变量有关。检验的统计量为:
其中Obsij指第i行第j列的单元格的实际频数,Expij指第i行第j列的单元格的期望频数,卡方统计量实际上是构造了列联表中每个单元格的残差(实际频数 - 期望频数)平方和除以每一个单元格的期望频数,然后再加总求和计算出卡方统计量。卡方统计量服从自由度为(r-1)(c-1)的卡方分布(r表示行个数,c表示列个数)。根据P值的大小和显著性水平就可以确定两分类变量是否相关了。
d=np.array([[4163,1017], [345,103]])#列联表
stats.chi2_contingency(d)
Out[31]:
(2.709816662738465,
0.09973245279763994,
1,
array([[4149.15422886, 1030.84577114],
[ 358.84577114, 89.15422886]]))
#第一个值为卡方值,第二个值为P值,第三个值为自由度,第四个为与原数据对应的期望频数
P值为0.09,在5%的显著性水平下表明没有理由拒绝违约与破产两个分类变量是独立的假设,即二者不相关。