【假设检验之t检验、f检验】

您所在的位置:网站首页 正态分布的方差和标准差一样吗 【假设检验之t检验、f检验】

【假设检验之t检验、f检验】

2023-03-16 13:59| 来源: 网络整理| 查看: 265

上一篇文章讲述了什么是假设检验、为什么要假设检验以及该怎样进行假设检验,没想到获得大家的喜欢和收藏,挺开心的,本篇主要讲在假设检验中,应该采取怎样的检验方式,以及python代码的实现。

如果还有童鞋对假设检验的整体概念和原理没看懂的,可以先看看我上一篇文章。

在进行假设检验时,我们常常听到t检验、f检验以及卡方检验等,一开始接触时,觉得挺晕的,一个假设检验为啥需要用到这么多花样,他们之间有何区别呢?本篇结合自己的理解来陈述,主要还是梳理知识逻辑加深印象,其次呢,也希望能给一些还在假设检验中摸索的同行一点点帮助。

先写个结论吧,无论的哪种检验,首先它们得先有一个分布图,这个分布图展示的是理论值,我们检验的工作就是把算出来的统计量和其分布对应的理论值做比较,并以此做出接受或拒绝的判断。只是不同情况下,我们做检验时,需要用到不同的分布类型,于是便有了t检验、f检验及卡方检验的区分。

1、t检验,我理解,适用于连续性变量的检验,常见的两组数据有无差异之类的,有时候要搭配f检验一起用

2、卡方检验,我理解,主要适合分类变量的检验,一般是检验变量间有没关系,比如说性别这一变量对化不化妆有没关系

限于篇幅原因,本章先讲t检验和f检验

t检验和f检验

什么是t检验呢,还是先看官方定义,主要用于样本含量较小(例如n < 30),总体标准差σ未知的正态分布。t检验是用t分布理论来推论差异发生的概率,从而比较两个平均数的差异是否显著。

我个人理解,其实跟样本量关系不大,样本量大于30的,也可以用t检验,之所以强调样本量小,感觉是因为这是属于t检验的特色,它可以通过小样本量来推断差异发生的概率,并不是说大样本量就不行。里面提到的t分布,上篇文章也是讲述其由来,蒙圈的可以回去看下。

t检验有三个分类:单样本t检验、双样本t检验及配对样本t检验

通俗理解就是下面三种情况:

1、单样本t检验:已知总体均值,一组样本的均值和标准差,求证样本与总体是否有显著差别 。如已知全校某科考试均分80分,A班考试均分75分,两者有没区别;或已知生产线的不良率是0.5%,现在引入一条新的生产线,不良率是0.4%,两者有没区别;再如上文提到的已知A公司平均工资4200,B公司抽样平均工资4500,两家公司有没区别等等。

2、双样本t检验:有两组样本均值和标准差,不知道两组样本来自的总体情况,验证两个总体是否有显著差异。如两个学校考试,随机抽取两组样本,看两者有没差异。再如两个生产线,随机抽取两组样本,看两条生产线的不良率有没差别。再比如两个公司,随机抽取两组员工,看两组公司的平均工资是否有差别。

(以上两种情况是很相似的,区别是一个为一组样本数据且总体均值已知,一个为两组样本数据且两个总体均值未知)

3、配对样本t检验:顾名思义,就是一组样本,前后两次的数据对比,如一组学生,经过某个培训后,其培训效果有没提升,样本数据就是这组学生前后两次的做题结果。再如,一组高血糖患者,在吃了某种特效药后,对血糖的控制有无效果,样本数据就是这组高血糖患者在吃药前后的一些指标数据对比。

接下来,我会通过案例结合python来实证下这三种情况。

单样本t检验

还是以上文的工资为例,假设A公司平均工资4200,小王想跳槽B公司,通过几天的打探,他打探到30个来自B公司不同部门的员工工资情况,他想看看通过假设检验来决定自己要不要跳槽。

根据上述情况,明显适合单样本t检验,这时候就要引入另一个概念了,单边检验和双边检验,啥意思呢,很简单,以本题为例,既然要做假设检验,你首先要提假设吧,那假设怎么提呢?

1、假设B公司 \mu_{0} 和A公司 \mu 员工薪资无差异(双边检验,即 H0: \mu_{0}=\mu )

2、假设B公司 \mu_{0} 薪资大于A公司 \mu 薪资(单边检验,即 H0: \mu_{0}>\mu ,也叫单边左尾检验)

3、假设B公司 \mu_{0} 薪资小于A公司 \mu 薪资(单边检验,即 H0: \mu_{0}<\mu ,也叫单边右尾检验)

对于左尾右尾不理解的,可以这样想,备择假设要成立,即需要统计量落入拒绝域中,以第2种情况为例,备择假设H1 : \mu_{0}≤\mu ,小于说明要在均值左边才行,即要检验左边的拒绝域,所以是左尾检验。有点拗口,大家试着多理解下加深印象。

先导入模块 import pandas as pd import numpy as np import random from scipy import stats #先生成一组B公司30个员工的工资,我们还是假设工资水平是2000到10000之间的 data=[random.randint(2000,10000) for i in range(30)] #列表推导式,这样生成的数据是一组列表,还是输出给大家看下 结果: [9177, 8009, 5857, 7212, 4482, 6698, 3440, 8319, 9974, 6163, 8300, 3539, 7331, 6289, 2046, 9010, 9973, 3394, 7147, 2329, 6428, 5004, 2760, 9990, 5918, 5750, 2562, 7228, 9113, 4138] #计算这组数据的均值 mean=sum(data)/len(data) #因为是列表,不能用mean方法计算,结果是6252,跟我们的4500差距比较大 data = [int(x + 4500 - mean) for x in data] #将这组数据的平均工资转为4500 #双边t检验 stats.ttest_1samp(data,4200,alternative='two-sided') 结果: Ttest_1sampResult(statistic=0.670736225929042, pvalue=0.5076957571266971) #P值大于0.05,不能拒绝原假设,接受AB公司员工薪资无差异 #单边左尾检验,H1样本均值小于总体,所以是less stats.ttest_1samp(data,4200,alternative='less') 结果: Ttest_1sampResult(statistic=0.670736225929042, pvalue=0.7461521214366513) #P值大于0.05,不能拒绝原假设,接受B公司薪资大于A公司 #单边右尾检验,H1样本均值大于总体,所以是greater print(stats.ttest_1samp(data,4200,alternative='greater')) #记住样本大于总体用greater就好 结果: Ttest_1sampResult(statistic=0.670736225929042, pvalue=0.25384787856334856) #P值大于0.05,不能拒绝原假设,接受B公司薪资小于A公司

好的,问题来了,同样的数据,不同的假设,出现三种结果,脑瓜子要短路,为什么会这样呢?

这就是数据与业务的差别,理论是死的,人是活的,我们通过计算机算出来的,是给定一组数据的情况下,系统输出的结果,是客观存在且不会改变的。怎么去判断,需要我们结合实际去看,即我们应该基于业务去做一个合理的假设即可

1、排除不符合逻辑的假设,结合以本文为例,B公司抽样的薪资已经大于A公司了,结合实际情况,我们不可能还去假设B公司薪资小于A公司(第3种假设,单边右尾检验),对吧,其实从数据也可以看到,P值是0.25,对比三种情况,它的值也是最小的。

你硬要说,你不管,你就是假设B公司薪资小于A公司,结果证明了接受原假设,B公司薪资小于A公司这一结论的对的,说实在的也没人阻止你,但是这样的检验结果不能让人家信服,毕竟以目前的情况看,B公司薪资要高于A公司,然后你结论告诉我,实际上A公司的薪资要比B公司高,人家一看你的结论恐怕都没兴趣往下深究了。

2、选一个你觉得比较可能或你更想验证的假设,于本文中,如果你对跳槽比较谨慎,你应该选第1种;如果你是B公司人事,要挖人来,你就选第2种。

综上,我们会发现,数据其实也是带有一定的欺骗性的,关键是你站在一个怎样的角度做看待,而数据分析师要做的工作,就是学会透过数据看到数据背后隐藏的信息,并将其运用到合适的地方。

扯远了,继续

双样本t检验

提到双样本t检验,就避不开一个名词【方差齐性】,那什么是方差齐性呢?方差齐性与双样本t检验又有什么关系呢?

什么是方差齐性,方差齐性指不同样本所代表的总体方差相等,这里的相等不是严格意义上绝对相等,即看起来差不多相等即可,即所谓的齐性。在统计描述中,方差用来计算每一个变量(观察值)与总体均数之间的差异或反映数据的离散程度,差异越小,方差越小,数据的波动性就越小,数据也就越集中。我们要求两个样本所代表的总体符合方差齐性,本质就是要求两个样本所代表的总体内,其数据波动程度差不多。

方差齐性跟双样本t检验有什么关系呢?我们要明白,双样本t检验的本质是什么?是检验两个总体的均值是否相等,假如这两个总体的方差差距很大,再检验两个总体均值是否相等就没有意义了,直接上图解释。

#先导入模块 import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt #中文乱码和坐标轴负号的处理 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False #创建两个正态分布的案例,a公司员工薪资4200,标准差100;b公司员工薪资4200,标准差300 test_a=np.random.normal(loc=4200,scale=100,size=10000) test_b=np.random.normal(loc=4200,scale=300,size=10000) #画图 plt.figure(figsize=(10,6)) plt.style.use('ggplot') sns.distplot(test_a,hist=True,color='red',label='u=4200,s=100') sns.distplot(test_b,hist=True,color='blue',label='u=4200,s=300') plt.xticks(range(3000,5500,200)) plt.legend() plt.show()

我们很容易发现,虽然A公司和B公司员工薪资均值都在4200元,但是两家公司薪资的集中水平明显不同,A公司标准差小,员工薪资相对更加集中,大部分员工工资在4000-4400之间;B公司标准差大,员工薪资相对更加分散,大部分员工工资在3600-4800之间。

回到最初的疑问,这样两家公司,做均值对比有意义吗?很明显没有,其工资范围差别太大了,即便你知道两家公司的员工薪资无差异,这样的结果给到你的参考意义已经不大。

所以,双样本t检验需要先做下方差齐性检验,只有两个样本的方差差别不大的情况下,我们才能去做双样本t检验。那问题来了,怎么去做方差齐性检验呢?

这里就引入了我们的f检验。

参考我们上篇文章讲t检验的由来,既然有f检验,那肯定有一个f分布,下面我们简单说下f分布是怎么来的。

我们知道,哪怕是从一个总体中随机抽取两个样本,这两个样本的方差都不一定相等,更何况是从两个不同总体中抽取到的两个样本,所以两个样本的方差有差异是必然的,关键在于找出这个差异的范围和临界点,只要在临界点内的差异我们就认为这两个样本是符合方差齐性的。一旦差异突破某个临界点,我们就可以认为两个样本不具备方差齐性。那我们怎么计算这个差异分布范围呢?

我们先假设两组样本来自同一个总体,我们对总体进行随机抽样,抽取两组样本,样本量为20,然后统计两组样本的方差比s_{1}^{2} / s_{2}^{2},重复抽取10000次,这样我们就可以得到一个s_{1}^{2} / s_{2}^{2}的概率分布图,这样的分布我们就叫它为F分布

继续,用代码来完成这个操作看看结果。

F=[] for i in range(10000): sample1=test.sample(20) sample2=test.sample(20) f=sample1.var()/sample2.var() F.append(f) sns.distplot(F)

如图,我们可以看到,f值呈现一个偏态分布,但其峰值是在1附近的,这个很好理解,因为如果两个样本来自同一个总体的话,其方差差距会比较小,方差比就会趋向1。

有了这个概率密度分布图,我们又可以用我们的假设检验了,但我们统计到的两个样本比值出现在最右边或者最左边区域时,其概率很低,依据小概率事假不可能发生原理,我们就可以做出拒绝原假设的判断。

这就是f检验,不知道大家懂了吗?

回到双样本检验,我这边没有好的案例,于是从统计学书里拿了一道题做案例,直接通过代码演示

#导入模块 from scipy import stats import pandas as pd #先把两组数据导入 male=pd.Series([82,80,85,85,78,87,82]) female=pd.Series([75,76,80,77,80,77,73]) #先做方差齐性检验,下面我们先根据上文提到,计算f值,比较f置信区间来检验方差齐性 f=male.var()/female.var() #两组样本的方差相除计算t值 结果: 1.5294117647058822 #然后计算两组样本的置信区间,显著性水平0.05,因为是齐性,一般选双边置信区间,样本都是6 stats.f.interval(0.95,6,6) 结果: (0.17182849255502158, 5.819756578960778)

我们发现求出来的f值,是在这个置信区间范围内的,所以没办法拒绝原假设,于是接受两组数据方差齐性假设成立 。码字的过程中发现,python还有一个函数也是求置信区间的,stats.f.ppf(),我也去研究了下,这个一般求的是单侧置信区间,下面我也讲下怎么通过这个函数求两边置信区间

#关键点在于显著性水平0.05,因为是是双边检验的,所以如果是单边的话就是0.025 stats.f.ppf(0.025,6,6) #左侧的临界值 stats.f.ppf(0.975,6,6) #右侧的临界值 结果都是一样的,大家也可以试下,当然还有另一个函数stats.f.isf(),也可以计算置信区间 stats.f.isf(0.975,6,6) #左侧的临界值 stats.f.isf(0.025,6,6) #右侧的临界值

三个函数计算出的结果都一样,算殊途同归吧,其实后面两个函数是用来计算单边的临界值的,所以如果用单边函数算双边的置信水平,他们的显著性水平就变成 \alpha/2 。

#当然,还有一个函数直接计算P值的 stats.f.cdf(0.95,6,6) 结果: 0.4759720726365217 #大于0.05,无法拒绝原假设,接受两组样本方差齐性 #值得注意的是,stats.f.cdf函数计算的是F分布的单尾概率(即左尾或右尾概率),如果需要计算双尾概率,需要将p-value乘以2。此外,还可以使用1-p_value计算另一个尾部的概率。

还有一种更常见的用于检验方差齐性的方法,是levene检验,具体原理我也没去研究,直接说代码吧,哈哈

stats.levene(male,female) 结果: LeveneResult(statistic=0.3749999999999997, pvalue=0.5517190949055959) #P值大于0.05,无法拒绝原假设 #这个函数可以用于两组以上的数据做齐性检验,相比上面的方法感觉会更方便的

终于把齐性检验讲完了,回到双样本t检验上,代码很简单

stats.ttest_ind(male,female, equal_var=True) #equal_var是否方差齐性 结果: Ttest_indResult(statistic=3.8288227591428385, pvalue=0.0024006953026618435) #P值小于0.05,拒绝原假设,说明男女得分是存在显著差异的

终于讲完了,感动自己,太难了,理论加代码,还差一个配对样本t检验,这个到时候就补上案例和代码吧

喜欢的朋友们,评论鼓励下咧,哈哈哈

(未完待续)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3