首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >stats.ttest_ind()与“手动”计算学生的独立t检验:不同的结果

stats.ttest_ind()与“手动”计算学生的独立t检验:不同的结果
EN

Stack Overflow用户
提问于 2021-02-07 03:49:48
回答 1查看 150关注 0票数 2

我比较了stats.ttest_ind()和相同测试的“手动”计算,得到不同的结果。

代码语言:javascript
运行
复制
import numpy as np
import pandas as pd
import scipy.stats as stats
import math

stats.ttest_ind()方法:

代码语言:javascript
运行
复制
#generate data
np.random.seed(123)
df = pd.DataFrame({ 
    'age':np.random.normal(40,5,200).round(),
    'sex':np.random.choice( ['male', 'female'], 200, p=[0.4, 0.6]),
     })

#define groups
men = df.age[df.sex == 'male']
women = df.age[df.sex == 'female']

#run t-test
test_stat, test_p = stats.ttest_ind(men, women)
print(test_stat, test_p)

输出:

代码语言:javascript
运行
复制
-0.9265613940505325 0.355282312357339

手动方法:

代码语言:javascript
运行
复制
#mean
men_mean, women_mean = men.mean(), women.mean()
#standard deviation
men_sd, women_sd = men.std(ddof=1), women.std(ddof=1)
#standard error
men_n, women_n = len(men), len(women)
men_se, women_se = men_sd/math.sqrt(men_n), women_sd/math.sqrt(women_n)
#standard error on the difference between men and women
se_diff = math.sqrt(men_se**2.0 + women_se**2.0)
#t-stat
t_stat = (men_mean - women_mean) / se_diff
#degrees of freedom
df = men_n + women_n - 2
#critical value
alpha = 0.05
cv = stats.t.ppf(1.0 - alpha, df)
# p-value
p = (1 - stats.t.cdf(abs(t_stat), df)) * 2
print(t_stat, cv, p)

输出:

代码语言:javascript
运行
复制
-0.9244538916746341 0.3563753194455255

我们可以看到有一个很小的区别。为什么?也许是因为stats.ttest_ind()计算自由度的方式?任何有见地的人都非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-07 08:53:39

以下是有效的方法。这是上面的代码,只更改了两行。

代码语言:javascript
运行
复制
import numpy as np
import pandas as pd
import scipy.stats as stats
import math
#generate data
np.random.seed(123)
df = pd.DataFrame({ 
    'age':np.random.normal(40,5,200).round(),
    'sex':np.random.choice( ['male', 'female'], 200, p=[0.4, 0.6]),
     })

#define groups
men = df.age[df.sex == 'male']
women = df.age[df.sex == 'female']

#run t-test
############################### CHANGED THE ROW BELOW HERE
test_stat, test_p = stats.ttest_ind(men, women,equal_var=False)  
print(test_stat, test_p)
#mean
men_mean, women_mean = men.mean(), women.mean()
#standard deviation
men_sd, women_sd = men.std(ddof=1), women.std(ddof=1)
#standard error
men_n, women_n = len(men), len(women)
men_se, women_se = men_sd/math.sqrt(men_n), women_sd/math.sqrt(women_n)
#standard error on the difference between men and women
se_diff = math.sqrt(men_se**2.0 + women_se**2.0)
#t-stat
t_stat = (men_mean - women_mean) / se_diff
#degrees of freedom
############################### CHANGED THE ROW BELOW HERE
df = (men_sd**2/men_n + women_sd**2/women_n)**2 / ( men_sd**4/men_n**2/(men_n-1)  + women_sd**4/women_n**2/(women_n-1)   )
#critical value
alpha = 0.05
cv = stats.t.ppf(1.0 - alpha, df)
# p-value
p = (1 - stats.t.cdf(abs(t_stat), df)) * 2
print(t_stat, cv, p)

并且它输出

代码语言:javascript
运行
复制
-0.9244538916746341 0.356441636045986
-0.9244538916746341 1.6530443278019797 0.3564416360459859

代码不一致的原因是:

test_stat, test_p = stats.ttest_ind(men, women)行上,您接受了默认设置,即t检验将根据等方差假设进行计算。因此,scipy.stats给出的计算是一个纯粹的等方差t检验。scipy.stats.ttest_ind的文档中对此进行了描述

在您自己的代码中,您通常遵循Welch test:分别计算男性和女性的平均值及其标准误差的估计值,并以这种方式计算t统计量。

你确实在一个地方偏离了韦尔奇测试:自由度的计算。自由度应该近似于我在代码中输入的公式(并链接到上面),但您使用的是在equal-variance assumptions下适用的计算。

如果您想了解有关如何计算这些统计信息的更多详细信息,或者为什么它们是这样定义的,或者为什么您的代码不是您期望的那样,我建议您查看更适合处理统计问题的https://stats.stackexchange.com/https://datascience.stackexchange.com/,而不是更多关于编程的https://stackoverflow.com/。这两个社区都精通python,所以他们应该能够很好地帮助您。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66081234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档