文科生进阶python(七)|无需SPSS,pingouin库实现实验数据统计分析

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

好久没有更新文科生进阶python系列了,刚好最近和一位粉丝朋友合作进行了一个论文,用到了Python进行统计分析。

我们文科生学Python的一个目标就是要用到科研里,说到科研就需要进行统计分析,SPSS各种不好用,我们学会了万能的Python,替代SPSS实现我们科研论文中的统计分析部分那自然是手拿把掐。

今天用一个最简单的案例,配合脱敏数据例子,讲清楚实验数据进行假设检验的过程,以及Python在其中的作用。本文目录如下:

图片

在此之前,我们需要了解下pingouin库,这个库的名字是企鹅的意思。号称可以搞定各种假设检验和统计模型的Python 库。

官方网址:https://pingouin-stats.org/build/html/index.html

图片

数据猿认为这个库比scipy还好用,值得推荐。

具体的介绍就不赘述了,有兴趣的直接去官方文档查阅。

这里我们先生成一个示例数据,来看看pingouin库的功能——

定量数据分析基础代码:pingouin库和pandas库

1.导入库
importpandasaspd
importpingouinaspg
2.创建示例数据集

假设我们有一个包含身高和体重的数据集:

data = {
    'Height': [165, 170, 175, 180, 160],
    'Weight': [65, 70, 75, 80, 60]
}

df = pd.DataFrame(data)
print(df)
4.计算均值和标准差

使用Pandas计算身高和体重的均值和标准差:

# 计算身高和体重的均值
height_mean = df['Height'].mean()
weight_mean = df['Weight'].mean()

# 计算身高和体重的标准差
height_std = df['Height'].std()
weight_std = df['Weight'].std()

print("身高均值:", height_mean)
print("体重均值:", weight_mean)
print("身高标准差:", height_std)
print("体重标准差:", weight_std)
5. 使用pingouin库进行相关性分析

使用pingouin库计算身高和体重之间的相关性(Pearson相关系数):

# 使用pingouin库计算相关性
correlation_result = pg.corr(x=df['Height'], y=df['Weight'])

print("身高和体重的Pearson相关系数:", correlation_result['r'])
print("相关性显著性(p-value):", correlation_result['p-val'])
6. 使用pingouin库进行假设检验(示例:t检验)

假设我们要比较两组数据(例如男性和女性的体重是否有显著差异):

# 创建示例性别数据
gender = ['男', '男', '男', '女', '女']
df['Gender'] = gender

# 使用pingouin进行t检验
ttest_result = pg.ttest(x=df[df['Gender']=='男']['Weight'], y=df[df['Gender']=='女']['Weight'])

print("男性和女性体重的t检验结果:")
print(ttest_result)

当使用pingouin库进行回归分析、相关系数计算、随机抽样、统计推断和ANOVA分析时,可以按照以下步骤进行操作:

7 .回归分析(Regression Analysis)

假设我们想要分析身高对体重的影响,并进行线性回归分析:

# 使用pingouin进行线性回归分析
regression_result = pg.linear_regression(X=df['Height'], y=df['Weight'])

print("线性回归分析结果:")
print(regression_result)

以下是AI升级后的代码,使用Plotly绘制线性回归分析的图,包含了误差线和区间:

importplotly.graph_objectsasgo
importpingouinaspg
importpandasaspd


# 使用 pingouin 进行线性回归分析
regression_result = pg.linear_regression(X=df['Height'], y=df['Weight'])

# 提取回归系数和截距
coef = regression_result['coef'].values[0]
intercept = regression_result['intercept'].values[0]

# 创建线性回归模型
model_line = coef*df['Height'] +intercept

# 创建图表
fig = go.Figure()

# 绘制原始数据散点图
fig.add_trace(go.Scatter(x=df['Height'], y=df['Weight'], mode='markers', name='原始数据'))

# 绘制线性回归线
fig.add_trace(go.Scatter(x=df['Height'], y=model_line, mode='lines', name='线性回归线'))

# 绘制误差线
residuals = df['Weight'] -model_line
fig.add_trace(go.Scatter(x=df['Height'], y=residuals, mode='lines', line=dict(dash='dash'), name='误差线'))

# 添加区间(可根据需要调整)
ci_low = regression_result['CI[2.5%]'].values[0]
ci_high = regression_result['CI[97.5%]'].values[0]
fig.add_trace(go.Scatter(x=df['Height'], y=model_line+ci_low, mode='lines', line=dict(dash='dot'), name='95%置信区间下界'))
fig.add_trace(go.Scatter(x=df['Height'], y=model_line+ci_high, mode='lines', line=dict(dash='dot'), name='95%置信区间上界'))

# 设置图表布局和标题
fig.update_layout(title='线性回归分析结果',
                  xaxis_title='身高',
                  yaxis_title='体重')

# 显示图表
fig.show()

这段代码使用了Plotly绘制了原始数据散点图、线性回归线、误差线和95%置信区间,帮助可视化线性回归分析结果。

8. 相关系数(Correlation Coefficient)

除了前面提到的Pearson相关系数外,还可以计算Spearman相关系数等其他类型的相关系数:

# 使用pingouin计算Spearman相关系数
spearman_corr = pg.corr(x=df['Height'], y=df['Weight'], method='spearman')

print("身高和体重的Spearman相关系数:", spearman_corr['r'])
9. 随机抽样(Sampling)

使用Pandas进行随机抽样,以抽取示例数据样本为例——

# 使用Pandas进行随机抽样
sample = df.sample(n=3, replace=False)  # 抽取3个样本,不放回抽样

print("随机抽样结果:")
print(sample)
10. 统计推断(Statistical Inference)

假设我们想要推断总体的均值是否与样本均值有显著差异:

# 使用pingouin进行单样本t检验
ttest_inference = pg.ttest(df['Height'], mu=170)

print("单样本t检验结果:")
print(ttest_inference)
11. ANOVA分析(Analysis of Variance)

假设我们想要比较不同性别之间的体重是否有显著差异:

# 使用pingouin进行单因素方差分析
anova_result = pg.anova(data=df, dv='Weight', between='Gender')

print("单因素方差分析结果:")
print(anova_result)
12.卡方检验(chi-squared test

可以分析两个或多个分类变量之间是否存在关联或独立性。例如,研究两种不同治疗方法对疾病治愈率的影响,性别与购买偏好之间的关联等。检验观察频数与期望频数之间的差异。在实际应用中,观察频数是指在一项研究或调查中实际观察到的频数,期望频数是基于某种假设模型(通常是独立性假设)得到的理论预期频数。比较多个分类变量的分布是否相同。例如,在市场调查中比较不同年龄组的购买偏好是否相似。

这里,我们来研究性别和身高、体重之间的是否存在显著性关联。

importpandasaspd
importpingouinaspg

# 数据
data = {
    'Height': [165, 170, 175, 180, 160],
    'Weight': [65, 70, 75, 80, 60]
}
df = pd.DataFrame(data)
gender = ['男', '男', '男', '女', '女']
df['Gender'] = gender

# 创建身高的分类变量
df['Height_Category'] = pd.cut(df['Height'], bins=[150, 165, 170, 175, 180, 200], labels=['<165', '165-170', '170-175', '175-180', '>180'])

# 执行卡方独立性检验
expected, observed, stats = pg.chi2_independence(df, x='Height_Category', y='Gender')

# 输出结果
chi2_val = stats['chi2'][0]
p_val = stats['pval'][0]
dof = stats['dof'][0]

print("卡方值:", chi2_val)
print("P值:", p_val)
print("自由度:", dof)

# 根据P值做出结论
alpha = 0.05
ifp_val<alpha:
    print("在显著性水平0.05下,拒绝原假设,认为身高和性别之间存在显著关联。")
else:
    print("在显著性水平0.05下,不拒绝原假设,认为身高和性别之间不存在显著关联。")

上述代码演示了如何使用pingouin库进行回归分析、相关系数计算、随机抽样、统计推断和ANOVA分析。

但是,在实际操作中,我们需要清楚什么数据适合什么样的数据量计算来进行分析。

回到我们的出发点——实验数据的统计分析。

所以,接下来,数据猿就一步步展示,如何将一个包含实验组(男)和对照组(女)的实验数据进行假设检验的。

我们的假设是:

H1:得分在男性组和女性组之间具有显著差异。

H2:男性组得分低于女性组。

实验数据统计分析步骤

话不多说,我们开始实验数据的统计分析。主要是如下步骤:

1.数据导入与清洗- 导入数据并处理缺失值、异常值2.描述性统计- 计算均值、标准差等关键指标3.正态性检验- 验证数据是否符合正态分布4.方差齐性检验- 检查不同组间方差是否齐性5.假设检验- 根据数据特性选择参数检验(如t检验、ANOVA)或非参数检验(如Mann-Whitney U)6.效应量计算- 量化差异大小(如Cohen's d)7.结果可视化- 使用图表直观展示数据分布
1.数据导入与清洗
  • 导入数据并处理缺失值、异常值

#过程示例
importpandasaspd
importpingouinaspg
importseabornassns
importmatplotlib.pyplotasplt

# 1. 数据导入
data = pd.read_csv("experiment_data.csv")  # 假设数据包含'group'和'score'两列
#  数据清洗
print("缺失值统计:\n", data.isnull().sum())

运行过程截图:

图片

这里先看看我这个示例数据的缺失值,再看看删除缺失值之后的情况。

看原数据内的缺失值位置:

图片

接下来直接删除缺失值。使用df.dropna()函数。

data = data.dropna()  # 删除缺失值
data

运行过程截图:

图片

发现,有缺失值的2行数据已经被删除。

当然,这是数据清洗最简单的一种。

有时候,我们还需要统一数据单位,给部分数据补数据等等复杂操作。

可以看看文科数据员的古早文章,看看数据清洗的步骤,此处不再赘述:

python的pandas库清洗数据

2.描述性统计
  • 计算均值、标准差等关键指标

\# 2. 描述性统计

desc_stats = data.groupby("group")["score"].describe()

print("\n描述性统计:\n", desc_stats)

describe()函数会计算基本的数据指标。

图片

可以发现,describe()函数已经将2个组的频数、平均值、标准差、最小值、三分位、最大值列出来了。

如果需要更多pandas库的操作,可以看往期文章:

文科生进阶python(三)|全面掌握pandas库基础用法

3.正态性检验
  • 验证数据是否符合正态分布

# 4. 正态性检验
normality = pg.normality(data, dv="score", group="group")
print("\n正态性检验结果:\n", normality)

在进行假设检验前,需要验证数据是否符合正态分布,不符合的话,有意义的统计量就会比较少,假设检验的方法也较少了。

运行过程截图:

图片

可以发现女性组的Shapiro-Wilk检验统计量W为0.89420,p值为0.016249。通常情况下,如果p值小于显著性水平(如0.05),则拒绝原假设(数据符合正态分布的假设),即认为数据不是正态分布的。

在本例中,p值小于0.05,因此女性组数据不是正态分布。男性组的Shapiro-Wilk检验统计量W为0.75944,p值为0.000039。同样的,p值远小于0.05,因此男性组数据也不是正态分布的。

这里可以强行绘制直方图看看。

男性组:

图片

女性组:

图片

当然,实际操作中,如果计算出了p值不符合正态分布了,那就没必要绘制直方图和核密度图了。

4.方差齐性检验
  • 检查不同组间方差是否齐性

# 5. 方差齐性检验(仅用于参数检验)
homogeneity = pg.homoscedasticity(data, dv="score", group="group")
print("\n方差齐性检验结果:\n", homogeneity)

运行过程截图:

图片

p值 > 0.05(显著性水平通常设为0.05),说明各组数据的方差无显著差异。 可以进行t检验和ANOVA方差分析,但是由于不符合正态分布,谨慎起见还是不采用t检验和ANOVA方差来进行假设检验。

5.假设检验
  • 根据数据特性选择参数检验(如t检验、ANOVA)或非参数检验(如Mann-Whitney U)

# 6. 根据检验结果选择假设检验方法
control = data[data["group"] == "control"]["score"]
experiment = data[data["group"] == "experiment"]["score"]

# 如果正态且方差齐性,使用独立样本t检验
ifnormality["normal"].all() andhomogeneity["equal_var"].bool():
    ttest = pg.ttest(control, experiment, paired=False)
    print("\n独立样本t检验结果:\n", ttest)
# 否则使用Mann-Whitney U检验
else:
    mwu = pg.mwu(control, experiment)
    print("\nMann-Whitney U检验结果:\n", mwu)

这里我们的数据不符合正态分布,只能用非参数检验。

运行过程截图:

图片

可以发现,p值 > 0.05(0.14 > 0.05),当前数据不支持男与女这2个组存在显著差异,但RBC = -0.245(RBC衡量两组关联方向和强度(范围:-1~1),小到中等效应(Cohen标准:0.1小,0.3中,0.5大)),提示男性组可能存在轻微低于女性组的趋势。

CLES共同语言效应量,这里计算的是男生组大于女生组的概率(范围:0~1)。CLES<0.5,支持男性组更低,但效应微弱(0.377接近中性值0.5)。

6.效应量计算

如果正态分布且方差齐性,就需要计算Cohen's d效应量

注意,这里的数据不符合正态分布,所以到了上述非参数检验,得到了RBC和CLES的值,即可发现统计结论,所以实际操作中无需使用下面的方法。

这里演示下如何计算

  • 量化差异大小(如Cohen's d)

# 7. 效应量(例如Cohen's d)
cohend = pg.compute_effsize(control, experiment, eftype="cohen")
print(f"\nCohen's d效应量: {cohend:.2f}")

运行过程截图:

图片

结果为负值(d = -0.41)表示 男性组的均值低于女性组(计算顺序为 男性组 vs 女性组)。

计算公式

图片

注意:Cohen's d假设数据近似正态分布且方差齐性。若数据严重偏态或方差不齐,建议使用 Hedges' g(小样本校正)或 非参数效应量(如CLES)。

所以,可以理解为女性组平均得分比男性组高(约0.41个标准差)。效应量的实际意义因领域而异。心理学中,|d|=0.4可能被视为有意义。医学中,|d|=0.4可能需结合临床重要性判断。这里|d|=0.41,表明男性组得分略低于女性组,差异为小到中等效应。

7.结果可视化
  • 使用图表直观展示数据分布

# 8. 可视化
sns.boxplot(x="group", y="score", data=data)
plt.title("实验组与对照组得分分布")
plt.show()

运行过程截图:

图片

所以,假设H1、H2基本成立。

相关性辅助的情形

除此之外,我们还需要了解下需要相关性分析的情形:

1.如果需要探索性的数据分析,可以先进行探索性分析,如数据可视化、聚类分析、相关性分析等,然后再进行假设检验。 

 一般需要如下流程:- 数据清洗 → 描述性统计 → 相关性分析 → 根据结果选择假设检验 → 效应量 → 可视化。

2.如果发现其他变量(如年龄、性别)与目标变量显著相关,且可能干扰组间比较,需在假设检验中控制这些变量。

# Python示例(协方差分析ANCOVA):
importpingouinaspg

# 假设数据包含组别(group)、结果变量(score)、协变量(age)
anova_cov = pg.ancova(data=data, dv='score', between='group', covar='age')
print(anova_cov)

3.相关性的呈现,可以查看数据猿之前原创的文章:

数据可视化入门(五)|快速制作论文相关性矩阵,并用seaborn库绘制热力图

好的,pingouin库和实验数据的统计分析介绍完毕。

在实际的科研过程中,我们可以根据对数据的理解,让AI写代码帮助我们对数据进行分析。

当然,前提是看过了数据猿的文章,明白统计分析的大概流程,这样才能最大限度发挥Python和AI的作用。需要合作进行科研的,可以后台私信数据猿Riggle。

此外,我们文科数据员乐享群也有不少朋友,可以付费数据分析代做。

如需本文全部代码,请关注文科数据员公众号,在后台回复“实验数据”获取。


欢迎添加数据猿微信(后台回复【0】即可获得微信号)

往期经典文章:

文科生进阶python(六)|CustomTkinter库开发图片管理工具

DeepSeek制作一个可“视频”对话的程序员鼓励师

指南更新 | python下载全球各大影音网站音视频

Python办公自动化(十一) | Dash开发海报自动生成工具

Python办公自动化(十) | 利用PyPDF2库批量合并PDF文件

社会网络分析(六) | ROSTCM6+Gephi的网络语义分析详细教程

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值