配对样本T检验:
在数学分析中,有些数据往往是成对出现的,是双样本的一种特殊状态。
配对样本T检验是用于检验两配对样本数据的均值是否存在显著性差异。零假设是两样本数据的均值不存在显著差异。举个例子:比如比较使用高血压药物是否能影响血压
代码实现
首先导入需要的包:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
#导入统计模块
from scipy import stats
#读取数据
#数据用的是spss课堂上的数据集
data = pd.read_csv(r'C:\Users\86135\Desktop\例4-3 配对样本T检验.csv')
#描述统计
data.describe()
print(data)
1a738493aea3b3f131a66d5ca554331.png
进行进行推断性统计分析
假设验证
提出问题
零假设:治疗无用,疗程初与疗程末的患者血压值相同
备择假设:治疗有用,疗程初患者的血压制不等于疗程末的患者血压值
接着做个分组柱形图看看血压差异
plt.rcParams['font.sans-serif']=['SimHei']
x = data['测试编号'].values.tolist()
y1 = data['疗程初血压'].values.tolist()
y2 = data['疗程末血压'].values.tolist()
width=0.3
xx=np.arange(len(x))
plt.bar(x=xx-width/2+1,height=y1,label="疗程初血压",color="red",width=width)
plt.bar(x=xx+width/2+1,height=y2,label="疗程末血压",color="blue",width=width)
# lable的位置,左上解
plt.legend(loc="upper right")
plt.xticks(x) # 设置具体刻度。
# 紧凑型的布局
plt.tight_layout()
plt.show()
6ea6afe6601303609f9b9a380e67e44.png
可以看出变化情况不太规律
接着看样本分布总体符不符合正态分布
cb13ba648c90885fb66dc24fe7b7dd9.png
data['Difference']=data['疗程初血压']-data['疗程末血压']
print(data.head())
sns.distplot(data['Difference'])
plt.title('差值数据集分布')
plt.show()
af4d5e4a891ea50fe91bcab5bab7c62.png
由图看出,差值数据的分布符合正态分布,且样本量<30,因此可以用t检验。
一般而言,如果要比较两组中哪一个更好(更大、更有成效等),
尤其是在对其中一组进行特殊的或者非常昂贵的干预时,或者有大量的资料表明这种干预会导致预期的变化时候,
就要使用单尾检验。当研究者想知道两组之间是否存在差异,而不考虑差异的方向时,需要使用双尾检验。
验证大于还是小于那就单边检验
①适合单尾检验的案例:一位治疗专家设计了一种新的干预方法来治疗某症,
他认为新的方法比目前使用的方法费用更低、效果更好;对被试冥想前和后的血压进行比较,看看其血压是否显著下降。
验证是否有差异,那就双边检验
②适合双尾检验的案例:某心理学家对男女性进行比较,想知道他们在过去的一年里与异性冲突的平均次数是否有差异;
比较在嘻哈和爵士两种音乐背景下老鼠的活动水平。
t检验,计算p值,并进行判断
#检验方向
#如果原假设:,疗程初血压>疗程末血压。使用单尾检验。
# 相关样本t检验
t, p_twoTail = stats.ttest_rel(data['疗程初血压'], data['疗程末血压'])
# 单尾p值
p_oneTail = p_twoTail / 2
# 输出t,p_twoTail,p_oneTail
print('t值为:', t, ';双尾检验p值为:', p_twoTail, ';单尾检验p值为:', p_oneTail)
#判断标准(显著水平)使用alpha=5%
alpha=0.05
# 单尾检验的p值
p_oneTail = p_twoTail / 2
# 判断标准的显著水平
alpha = 0.05
# 使用if函数进行判断
#如果是单边话需要有t,t的判断需要以原假设为判断依据,比如原假设是治疗后降血压t>0且显著,反之大于
if (p_twoTail < alpha):
print('接受备择假设,疗程初与疗程末的患者血压值不相同')
else:
print('接受原假设,治疗无用,疗程初与疗程末的患者血压值相同')
#t值为: 1.2000008533342437 ;双尾检验p值为: 0.24874946576903698 ;单尾检验p值为: 0.12437473288451849
#接受原假设,治疗无用,疗程初与疗程末的患者血压值相同
接着求置信区间
#置信区间
# 95%置信水平,自由度为23的t值
t_ci = 0.0634
# 差值数据集的平均值
sample_mean = data['Difference'].mean()
# 差值数据集的标准误差
se = stats.sem(data['Difference'])
# 置信区间上限
a = sample_mean - t_ci * se
# 置信区间下限
b = sample_mean + t_ci * se
print('置信水平为95%%的置信区间为(%f,%f)' % (a, b))
#置信水平为95%的置信区间为(13.319532,14.805468)
再求效应量
#效应量
# 计算效应量Cohen's d
# 差值数据集对应的总体均值为0
pop_mean = 0
# 差值数据集的标准差
sample_std = data['Difference'].std()
# d
d = (sample_mean - pop_mean) / sample_std
print('d='+ str(d))
#d=0.3000002133335609
源代码
# -*- coding = utf-8 -*-
# @Time : 2022/4/26 18:30
# @Author : eee
# @File :main“独立样本T检验”.py
# @Software : PyCharm
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import statsmodels.stats.weightstats as st
from scipy import stats
#读取数据
df = pd.read_csv(r'C:\Users\86135\Desktop\例4-2 独立样本T检验.csv')
data1 = df['Math1']
data2 = df['Math2']
print(data1.head())
print(data2.head())
print(data1.describe())
print(data2.describe())
list1=[]
for i in data1:
list1.append(i)
list2=[]
for i in data2:
list2.append(i)
m1 = pd.Series(list1)
m2 = pd.Series(list2)
# print(m1.describe())
# print(m2.describe())
list1 = [a for a in list1 if a == a]
print(list1)
print(list2)
'''
1.1 零假设和备选假设
根据这个问题我提出来下面两个互为相反的假设。
原假设H0:1班与2班学生的数学成绩相同。
备择假设H1:1班与2班学生的数学成绩不相同。
1.3 抽样分布类型
我们还要判断抽样分布是哪种?因为抽样分布的类型,决定了后面计算p值的不同。
在我们这个一二班数学案例中,样本大小是39和41(大于30),属于大样本。
之后要看数据是否呈正态分布
'''
# 解决图标签中文乱码
matplotlib.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
#查看数据集分布
sns.distplot(df['Math1'])
plt.title('Math1数据集分布')
plt.show()
sns.distplot(df['Math2'])
plt.title('Math2数据集分布')
plt.show()
#看图判断是否满足正态分布
'''
Levene's方差齐性检验(α=0.05)
根据两总体方差是否相等判断使用标准student t还是Welch t。
'''
#因为服从正态分布,所以用mean
W, levene_P = stats.levene(list1, list2, center='mean')
print("Levene's方差齐性检验的W统计量为" + str(W))
print("Levene's方差齐性检验的P值为" + str(levene_P))
#P>α=0.05,不能拒绝原假设,两总体方差无显著差异,应使用标准student t。
#P<α=0.05,拒绝原假设,两总体方差有显著差异,应使用Welch t。。
'''
1.4 检验方向
单尾检验(左尾,右尾),还是双尾检验?
因为是比较均值相不相等,所以我们使用双尾检验。
ttest_ind:独立双样本t检验,
usevar='unequal'两个总体方差不一样
返回的第1个值t是假设检验计算出的(t值),
第2个p_two是双尾检验的p值
第3个df是独立双样本的自由度
'''
t, p_two, df = st.ttest_ind(list1, list2)
#如果是watch t检验,应该列下面这个式子
#t, p_two, df = st.ttest_ind(list1, list2,usevar='unequal')
print('t=' + str(t))
print('P值=' + str(p_two))
print('自由度=' + str(df))
alpha = 0.05
if(p_two < alpha):
print('P<α,拒绝原假设,接受备择假设H1:1班与2班学生的数学成绩不相同。')
else:
print('P>α,不能拒绝原假设H0:1班与2班学生的数学成绩相同。')
#求置信区间
#1班均值与标准差
n1_mean = m1.mean()
n1_std = m1.std()
#2班均值与标准差
n2_mean = m2.mean()
n2_std = m2.std()
t_cv = 1.667
n1 = 39
n2 = 41
#合并方差
pooled_s2 = ((n1 - 1) * np.square(n1_std) +
(n2 - 1) * np.square(n2_std)) / (n1 + n2 - 2)
#标准误差值
se_diff = np.sqrt(pooled_s2 * (1 / n1 + 1 / n2))
#置信区间
a = (n1_mean - n2_mean) - t_cv * se_diff
b = (n1_mean - n2_mean) + t_cv * se_diff
print('置信水平为95%%的置信区间为(%f,%f)' % (a, b))
#效应量Cohen's d
#合并标准差计算
pooled_std = np.sqrt(pooled_s2)
d = (n1_mean - n2_mean) / pooled_std
print('d=' + str(d))