以下教程基于数据分析;我们将详细讨论方差分析(ANOVA) ,以及用 Python 编程语言实现它的过程。ANOVAs 通常用于心理学研究。
在接下来的教程中,我们将了解如何借助 SciPy 库进行方差分析,利用 Pyyttbl 和 Statsmodels 在 Python 中对其进行【手工】评估。
理解方差分析检验
我们可以想到一个方差分析检验,也称为方差分析,来概括多组的 T 检验。通常,我们使用独立的 T 检验来比较两组之间的状态均值。每当我们需要比较两个以上组之间的状态平均值时,我们使用方差分析检验。
方差分析检验模型中某处的平均值是否有差异(检验是否有整体效应);然而,这种方法不能告诉我们区别的地方(如果有的话)。通过进行事后检验,我们可以发现小组之间的差异点。
然而,为了进行任何检验,我们首先必须定义无效假设和替代假设:
- 无效假设:各组之间没有显著差异。
- 交替假设:各组之间有一个值得注意的差异。
我们可以通过比较两种变异来进行方差分析。第一个变化是在样本装置和每个样本中的另一个之间。下面显示的公式描述了单向方差分析检验统计。
方差分析公式的输出,即 F 统计量(也称为 F 比),能够分析多组数据,以确定样本之间和样本内部的可变性。
我们可以写出单向方差分析的公式,如下所示:
哪里,
y i -样本均值在 i 第T5】组
n i -第 i 第T5】组观察次数
y -数据的总平均值
k -组的总数
yij-jthT5【观察中出 k 组
总样本量
无论何时绘制方差分析表,我们都可以看到以下格式的所有上述组件:
通常,如果属于 F 的 p 值小于 0.05,则排除零假设,保持替代假设。在否定零假设的情况下,我们可以说所有集合/组的平均值不相等。
注:如果被测组之间没有真正的差异,这就是所谓的零假设,方差分析检验的 F 比统计将接近 1。
方差分析检验假设
在进行方差分析检验之前,我们必须做一些假设,如下所示:
- 我们可以从因子水平定义的总体中随机独立地获得观察值。
- 因子的每个级别的数据通常是分布的。
- 病例独立:样本病例必须相互独立。
- 方差同质性:同质性表示组之间的方差需要大约相等。
我们可以借助布朗-福赛思检验或莱文检验来检验方差齐性的假设。我们还可以借助直方图、峰度或偏度值,或者借助像科尔莫戈罗夫-斯米尔诺夫、夏皮罗-维尔克或 Q-Q 图这样的检验来检验分数分布的正态性。我们也可以确定独立于研究设计的假设。
值得注意的是,方差分析检验对违反独立性假设并不稳健。这是为了告诉人们,即使有人试图违反正态性或同质性的假设,他们也可以进行检验并相信结果。
然而,如果独立性的假设被拒绝,方差分析的结果是不可接受的。通常,如果我们有同等规模的小组,分析以及违反同质性被认为是稳健的。如果我们有大样本量,恢复方差分析检验并违反正态性通常是可以的。
了解方差分析检验的类型
方差分析检验可以分为三种主要类型。这些类型如下所示:
- 单向方差分析检验
- 双向方差分析检验
- n 向方差分析检验
单向方差分析检验
只有一个自变量的方差分析检验被称为单向方差分析检验。
例如,一个国家可以评估冠状病毒病例的差异,一个国家可以有多个类别进行比较。
双向方差分析检验
有两个独立变量的方差分析检验被称为双向方差分析检验。这项检验也被称为因子方差分析检验。
例如,扩展上述示例,双向方差分析可以通过年龄组(第一自变量)和性别(第二自变量)来检查冠状病毒(因变量)病例的差异。双向方差分析可以用来检验这两个独立变量之间的相互作用。交互作用表示所有类别的自变量之间的差异是不均匀的。
假设老年组与青年组相比,冠状病毒总体病例可能更高;然而,与亚洲国家相比,这种差异在欧洲国家(T4)和亚洲国家(T7)可能有所不同。
n 向方差分析检验
如果研究人员使用两个以上的独立变量,方差分析检验被认为是一个 n 向方差分析检验。这里 n 代表我们拥有的独立变量的数量。该检验也称为马诺娃检验。
例如,我们可以同时使用国家、年龄组、性别、种族等独立变量来检查冠状病毒病例的潜在差异。
方差分析检验将为我们提供单个(单变量)F 值;然而,一个 MANOVA 检验将为我们提供一个多元 F 值。
方差分析中有无复制的理解
一般来说,在方差分析检验中,我们中的一些人可能会听到有复制和没有复制的声音。让我们了解这些是什么:
复制双向方差分析检验
当两个组和这些组的成员执行多个任务时,进行带有复制的双向方差分析检验。
例如,假设冠状病毒疫苗仍在研发中。医生正在进行两种不同的治疗,以治愈两组感染病毒的患者。
无复制的双向方差分析检验
没有复制的双向方差分析检验是在我们只有一个组时进行的,我们对同一组进行双重检验。
例如,假设疫苗已经研制成功,研究人员在志愿者接种疫苗前后检验了一组志愿者,以观察疫苗接种是否正常。
理解后方差分析检验
在进行方差分析检验时,我们试图确定各组之间的统计学显著差异(如果有的话)。如果我们找到一个,我们将不得不检验群体差异点在哪里。
因此,研究人员使用事后检验来检查哪些组彼此不同。
我们可以进行事后检验,即检验各组间平均差异的 t 检验。我们可以进行多次比较检验来控制第一类错误率,包括邦费罗尼、邓尼特、谢菲和土耳其检验。
现在,我们将只理解使用 Python 编程语言的单向方差分析检验。
理解 Python 中的单向方差分析检验
我们将进行方差分析检验的过程分为不同的部分。
导入所需的库
为了开始进行方差分析检验,让我们为项目导入一些必要的库和模块。
语法:
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
from statsmodels.formula.api import ols
import seaborn as sns
import numpy as np
import pandas.tseries
plt.style.use('fivethirtyeight')
假设
让我们考虑这个问题的一个假设:
“每种饮食,人的体重平均值都是一样的。”
加载数据
在下面的问题中,我们将使用谢菲尔德大学设计的饮食数据集。数据集包含一个作为性别的二进制变量,其中 1 代表男性,0 代表女性。
让我们考虑以下语法:
语法:
mydata = pd.read_csv('Diet_Dataset.csv')
理解数据集
一旦我们成功导入数据集,让我们打印一些数据来了解它。
示例-
print(mydata.head())
输出:
Person gender Age Height pre.weight Diet weight6weeks
0 25 41 171 60 2 60.0
1 26 32 174 103 2 103.0
2 1 0 22 159 58 1 54.2
3 2 0 46 192 60 1 54.0
4 3 0 55 170 64 1 63.3
现在让我们打印数据集中存在的总行数。
示例-
print('The total number of rows in the dataset:', mydata.size)
输出:
The total number of rows in the dataset: 546
检查缺失值
现在,我们必须看看数据集中是否缺少任何值。我们可以使用以下语法来检查这一点。
示例-
print(mydata.gender.unique())
# displaying the person(s) having missing value in gender column
print(mydata[mydata.gender == ' '])
输出:
[' ' '0' '1']
Person gender Age Height pre.weight Diet weight6weeks
0 25 41 171 60 2 60.0
1 26 32 174 103 2 103.0
我们可以观察到两个条目在“性别”列中包含缺失的值。现在让我们找出数据集中缺失值的总百分比。
示例-
print('Percentage of missing values in the dataset: {:.2f}%'.format(mydata[mydata.gender == ' '].size / mydata.size * 100))
输出:
Percentage of missing values in the dataset: 2.56%
我们可以观察到,数据集中大约有 3%的缺失值。我们可以忽略、删除或借助最接近的高度平均值对其性别进行分类。
了解重量的分布
在接下来的步骤中,我们将使用 distplot() 函数绘制图表,以了解样本数据中的权重分布。让我们考虑代码片段。
示例-
f, ax = plt.subplots( figsize = (11,9) )
plt.title( 'Weight Distributions among Sample' )
plt.ylabel( 'pdf' )
sns.distplot( mydata.weight6weeks )
plt.show()
输出:
我们还可以绘制数据集中每个性别的分布图。下面是相同的语法:
示例-
f, ax = plt.subplots( figsize = (11,9) )
sns.distplot( mydata[mydata.gender == '1'].weight6weeks, ax = ax, label = 'Male')
sns.distplot( mydata[mydata.gender == '0'].weight6weeks, ax = ax, label = 'Female')
plt.title( 'Weight Distribution for Each Gender' )
plt.legend()
plt.show()
输出:
我们也可以使用下面的函数来显示每个性别的分布图。
示例:
def infergender(x):
if x == '1':
return 'Male'
if x == '0':
return 'Female'
return 'Other'
def showdistribution(df, gender, column, group):
f, ax = plt.subplots( figsize = (11, 9) )
plt.title( 'Weight Distribution for {} on each {}'.format(gender, column) )
for groupmember in group:
sns.distplot(df[df[column] == groupmember].weight6weeks, label='{}'.format(groupmember))
plt.legend()
plt.show()
uniquediet = mydata.Diet.unique()
uniquegender = mydata.gender.unique()
for gender in uniquegender:
if gender != ' ':
showdistribution(mydata[mydata.gender == gender], infergender(gender), 'Diet', uniquediet)
输出:
图 1:
图 2:
现在,我们将使用下面给出的代码片段根据“性别”列计算平均值、中位数、非零计数和标准差:
示例-
print(mydata.groupby('gender').agg(
[ np.mean, np.median, np.count_nonzero, np.std ]
).weight6weeks)
输出:
mean median count_nonzero std
gender
81.500000 81.5 2.0 30.405592
0 63.223256 62.4 43.0 6.150874
1 75.015152 73.9 33.0 4.629398
正如我们所观察到的,我们已经基于性别估计了所需的统计测量。我们也可以根据性别和饮食对这些统计数据进行分类。
示例-
print(mydata.groupby(['gender', 'Diet']).agg(
[np.mean, np.median, np.count_nonzero, np.std]
).weight6weeks)
输出:
mean median count_nonzero std
gender Diet
2 81.500000 81.50 2.0 30.405592
0 1 64.878571 64.50 14.0 6.877296
2 62.178571 61.15 14.0 6.274635
3 62.653333 61.80 15.0 5.370537
1 1 76.150000 75.75 10.0 5.439414
2 73.163636 72.70 11.0 3.818448
3 75.766667 76.35 12.0 4.434848
我们可以观察到,饮食中女性的体重略有差异;然而,它似乎不会影响男性。
进行单向方差分析检验
单向方差分析检验的零假设是
这个检验试图检验这个假设是否成立。
让我们考虑初步确定 95%的置信水平,这也意味着我们将只接受 5%的误差率。
示例-
mymod = ols('Height ~ Diet', data = mydata[mydata.gender == '0']).fit()
# performing type 2 anova test
aovtable = sm.stats.anova_lm(mymod, typ = 2)
print('ANOVA table for Female')
print('----------------------')
print(aovtable)
print()
mod = ols('Height ~ Diet', data = mydata[mydata.gender=='1']).fit()
# performing type 2 anova test
aovtable = sm.stats.anova_lm(mymod, typ = 2)
print('ANOVA table for Male')
print('----------------------')
print(aovtable)
输出:
ANOVA table for Female
----------------------
sum_sq df F PR(>F)
Diet 559.680764 1.0 7.17969 0.010566
Residual 3196.086677 41.0 NaN NaN
ANOVA table for Male
----------------------
sum_sq df F PR(>F)
Diet 559.680764 1.0 7.17969 0.010566
Residual 3196.086677 41.0 NaN NaN
在上面的输出中,我们可以观察到两个 p 值(PR (> F)):男性和女性。
在男性的情况下,我们不能接受低于 95%置信水平的零假设,因为 p 值大于α值,即 0.05 < 0.512784。因此,在提供这三种类型的饮食后,男性的体重没有发现差异。
就女性而言,由于 p 值 PR (> F)低于误差率,即 0.05 > 0.010566,我们可以拒绝零假设。这种说法表明,我们对女性在饮食方面的身高差异非常有信心。
所以,现在我们明白了饮食对女性的影响;然而,我们没有意识到这两种饮食之间的区别。因此,我们将在 Tukey HSD(诚实显著差异)检验的帮助下进行事后分析。
让我们考虑下面的代码片段。
示例-
from statsmodels.stats.multicomp import pairwise_tukeyhsd, MultiComparison
# using the female data only
mydf = mydata[mydata.gender == '0']
# comparing the height between each diet, using 95% confidence interval
multiComp = MultiComparison(mydf['Height'], mydf['Diet'])
tukeyres = multiComp.tukeyhsd(alpha = 0.05)
print(tukeyres)
print('Unique diet groups: ', multiComp.groupsunique)
输出:
Multiple Comparison of Means - Tukey HSD, FWER=0.05
=====================================================
group1 group2 meandiff p-adj lower upper reject
-----------------------------------------------------
1 2 -3.5714 0.5437 -11.7861 4.6432 False
1 3 -8.7714 0.0307 -16.848 -0.6948 True
2 3 -5.2 0.2719 -13.2766 2.8766 False
-----------------------------------------------------
Unique diet groups: [1 2 3]
从上面的输出中我们可以观察到,我们只能拒绝第一种和第三种饮食类型中的无效假设,这意味着饮食 1 和饮食 3 的体重存在统计学上的显著差异。