使用计算机语言玩数理统计
使用Python进行两组数据的比较
使用Python进行两组数据的比较

使用Python进行两组数据的比较

两组数据的比较方法通常为t检验和非参数检验,若两组数据均服从正态分布可使用t检验,否则使用非参数检验。


部分生物学或基础医学研究中会设两个实验组(如对照组和模型组),两组数据比较的基本思路如下:

图PT1. 两组数据比较

Python的实现大概需要2~3步:正态性检验,方差齐性检验(部分教材亦称为方差同质性检验),假设检验。

一、正态性检验

SPSS 22.0提供了两个正态性检验的结果:Kolmogorov-Smirnov(下文简称KS)检验和Shapiro-Wilk(下文简称SW)检验(其中 KS检验进行了Lilliefors 显著更正),而prism 8.0除了这两种检验外还提供了Anderson-Darling检验和D’Agostino & Pearson检验。以SPSS 22.0首选项为例,我们采用Lilliefors检验。

Python实现Lilliefors校正的KS检验如下:

from statsmodels.stats.diagnostic import lilliefors  # 导入相应模块
lilliefors(data)

data可以为元组,也可以为列表,但不可以为字典。此外,lilliefors还有一个参数为pvalmethod,默认为“table”,也可改为“approx”,相应说明搬运如下:

The method used to compute the p-value of the test statistic. In general, ‘table’ is preferred and makes use of a very large simulation. ‘approx’ is only valid for normality. if dist = 'exp' table is always used. ‘approx’ uses the approximation formula of Dalal and Wilkinson, valid for pvalues 0.1. If the pvalue is larger than 0.1, then the result of table is returned.

lillefors返回一个元组,其中包含两个元素:(KS距离,P值)。通常P > 0.05可认为数据通过正态检验(方积乾教授编写的《生物医学研究的统计方法(第一版)》建议检验水准α设置为0.1)。

二、方差齐性检验

SPSS 22.0会自动为两组数据进行Levene方差齐性检验,Prism 8.0暂未找到相应的检验方法。

Python实现Levene检验如下:

from scipy import stats  # 导入相应模块
stats.levene(data1, data2, center="mean")

stats.levene 可传入两组或两组以上的数据,数据类型可以为列表或元组,center参数默认为“median”(中位数)。考虑到前面我们的数据已经通过了正态检验,此处要把center参数改为“mean”

stats.levene返回的数据类型为<class ‘scipy.stats.morestats.LeveneResult’>,但其可转换为含有两个元素的元组或列表,包含有levene统计量和P 值。也可以为该方法直接声明变量,写作以下形式:

fVal, pSD = stats.levene(data1, data2, center="mean")

通常P > 0.05可认为数据通过方差齐性检验 (方积乾教授编写的《生物医学研究的统计方法(第一版)》建议检验水准α设置为0.1)。

三、独立样本t检验

SPSS 22.0会自动进行“采用相等变异数”和“不采用相等变异数”两种检验方法(前者为标准的t检验,后者为校正t检验,或称t’检验)。Prism 8.0则需要自行选择SD(方差)是否相同(两组数据方差不同需要选择“Welch’s correction”)。

Python实现独立样本t检验如下:

from scipy import stats # 导入相应模块
stats.ttest_ind(data1, data2) 

若两组数据未通过方差齐性检验,则需要在以上方法中声明方差不齐:equal_car = False,如下所示:

stats.ttest_ind(data1, data2, equal_var=False)

stats.ttest_ind 返回的数据和stats.levene 类似,包含t检验的统计量和P 值。

四、配对样本t检验

和独立样本t检验不同,SPSS 22.0需要将配对的数据分别输到两列;Prism 8.0需要将Experimental Design自行改为Paired。

Python实现配对样本t检验如下:

stats.ttest_rel(data1, data2)

返回结果与数据处理方法与独立样本t检验类似。

五、非参数检验

若样本从一开始不服从正态分布,则需要用非参数检验(部分课本称为秩和检验,直接免去方差齐性检验)。独立样本的非参数检验称为Mann-Whitney U检验,配对样本的非参数检验称为Wilcoxon检验。Python实现方法分别如下:

from scipy import stats # 导入相应模块
stats.mannwhitneyu(data1, data2)  # 独立样本的非参数检验
stats.wilcoxon(data1, data2)  # 配对样本的非参数检验

总结

以上基本为两组数据差异分析的全部方法。数据量少的话确实用SPSS或Prism等商业软件更方便一些,用计算机语言反而还要操心数据的排列等问题。然而当数据多的时候,如果能够灵活运用循环、判断语句,和Python的pandas模块批量读取Excel等数据,则可实现高度自动化的分析,很大程度上避免了手工操作失误。

两组数据的比较全部代码如下:

from statsmodels.stats.diagnostic import lilliefors
L1, pVal1 = lilliefors(数据1, pvalmethod="table")
L2, pVal2 = lilliefors(数据2, pvalmethod="table")
if pVal1 and pVal2 > 0.1:
    print("两组数据均服从正态分布")
    fVal, pSD = stats.levene(数据1, 数据2, center="mean")
    if pSD > 0.1:
        print("两组数据方差齐")
        tVal, pVal = stats.ttest_ind(数据1, 数据2)
        # 以上为非配对样本的检验方法,配对样本语句如下:
        # tStat, pVal = stats.ttest_rel(数据1, 数据2)
        if pVal < 0.05:
            print("两组数据有统计学差异")
        else:
            print("两组数据没有统计学差异")
    else:
        print("两组数据方差不齐")
        t_val, pVal = stats.ttest_ind(数据1, 数据2, equal_var=False)
        # 以上为非配对样本的检验方法,配对样本不需要考虑方差齐性检验
        if pVal < 0.05:
            print("两组数据有统计学差异")
        else:
            print("两组数据没有统计学差异")
else:
        print("两组数据不全服从正态分布")
        uStat, pVal = stats.mannwhitneyu(self.data_1, self.data_2)
        # 以上为非配对样本的非参数检验,配对样本的非参数检验语句如下:
        # wStat, p_val = stats.wilcoxon(self.data_1, self.data_2)
        if pVal < 0.05:
            print("两组数据有统计学差异")
        else:
            print("两组数据没有统计学差异")

发表评论

您的电子邮箱地址不会被公开。