如何使用numpy计算统计学中的"t检验"

27
我希望能够用Python生成一些有关模型的统计数据。我想要生成t检验,但不确定是否可以使用numpy/scipy轻松实现。是否有相关的好的解释文档?
例如,我有三个相关的数据集,如下所示:
[55.0, 55.0, 47.0, 47.0, 55.0, 55.0, 55.0, 63.0]

现在,我想对它们进行学生t检验。
3个回答

30

scipy.stats 包中有一些 ttest_... 函数。请参见来自此处的示例:

>>> print 't-statistic = %6.3f pvalue = %6.4f' %  stats.ttest_1samp(x, m)
t-statistic =  0.391 pvalue = 0.6955

谢谢您的回复。它似乎需要一个随机变量。我是否需要事先从我的样本人口中生成一个随机变量? - Mark
我认为你可以直接使用你的样本(而不是“样本总体”)。 - van
样本是指一个样本值吗?我原以为可以将多个结果的样本作为参数使用,但也许我被误导了 :) - Mark
在统计学上,样本是人口的一个子集(请参见http://en.wikipedia.org/wiki/Sample_%28statistics%29)。所以我的意思很简单,就是没有“样本人口”这个术语 :) 一个值只是样本(即一组值)中的一个值。 - van

11

Van 的回答使用了 scipy,scipy.stats.ttest_* 函数非常方便。这很正确。

但我来到这个页面是想寻找纯 numpy 的解决方案,就像标题所述,避免使用 scipy。为此,让我指出这里给出的示例:https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.standard_t.html

主要问题在于 numpy 没有累积分布函数,因此我的结论是你真的应该使用 scipy。无论如何,仅使用 numpy 是可能的:

从原始问题中,我猜测您想比较数据集,并通过 t-test 判断是否存在显着偏差?此外,样本成对吗? (见https://en.wikipedia.org/wiki/Student%27s_t-test#Unpaired_and_paired_two-sample_t-tests )。 在这种情况下,可以这样计算 t 值和 p 值:

import numpy as np
sample1 = np.array([55.0, 55.0, 47.0, 47.0, 55.0, 55.0, 55.0, 63.0])
sample2 = np.array([54.0, 56.0, 48.0, 46.0, 56.0, 56.0, 55.0, 62.0])
# paired sample -> the difference has mean 0
difference = sample1 - sample2
# the t-value is easily computed with numpy
t = (np.mean(difference))/(difference.std(ddof=1)/np.sqrt(len(difference)))
# unfortunately, numpy does not have a build in CDF
# here is a ridiculous work-around integrating by sampling
s = np.random.standard_t(len(difference), size=100000)
p = np.sum(s<t) / float(len(s))
# using a two-sided test
print("There is a {} % probability that the paired samples stem from distributions with the same means.".format(2 * min(p, 1 - p) * 100))

这将打印出有73.028%的概率,成对样本来自具有相同平均值的分布。 由于这远高于任何合理的置信区间(例如5%),因此您不应该针对具体情况得出任何结论。

-4

当你获得了你的t值,你可能会想知道如何将其解释为概率——我也是这样。这里是我编写的一段函数来帮助你。

它基于我从http://www.vassarstats.net/rsig.htmlhttp://en.wikipedia.org/wiki/Student%27s_t_distribution中收集到的信息。

# Given (possibly random) variables, X and Y, and a correlation direction,
# returns:
#  (r, p),
# where r is the Pearson correlation coefficient, and p is the probability
# of getting the observed values if there is actually no correlation in the given
# direction.
#
# direction:
#  if positive, p is the probability of getting the observed result when there is no
#     positive correlation in the normally distributed full populations sampled by X
#     and Y
#  if negative, p is the probability of getting the observed result, when there is no
#     negative correlation
#  if 0, p is the probability of getting your result, if your hypothesis is true that
#    there is no correlation in either direction
def probabilityOfResult(X, Y, direction=0):
    x = len(X)
    if x != len(Y):
        raise ValueError("variables not same len: " + str(x) + ", and " + \
                         str(len(Y)))
    if x < 6:
        raise ValueError("must have at least 6 samples, but have " + str(x))
    (corr, prb_2_tail) = stats.pearsonr(X, Y)

    if not direction:
        return (corr, prb_2_tail)

    prb_1_tail = prb_2_tail / 2
    if corr * direction > 0:
        return (corr, prb_1_tail)

    return (corr, 1 - prb_1_tail)

2
我只想指出相关系数没有任何概率解释,所以这很混淆。它只是一个线性相关度量,取值范围在[-1,1]之间。 - Ben Allison
相关系数测量了在已知另一个值的情况下可以预测一个值的程度:它是一个变量中由另一个变量解释的方差比例。仅仅因为它取值在0到1之间(或者它的绝对值是这样),并不意味着它是一个概率。因此,正如您所建议的那样,在极限情况下它不会取二进制值:对于无限的样本大小,它仍然可以取区间[-1,1]中的任何值。其值表示关系的强度,无论样本大小如何,都可能很弱。 - Ben Allison
我并不是说相关系数是概率。这个问题的主题是相关系数(t检验)的统计学意义。我提供了三个参考文献。这里有第四个参考文献,而且很简短明了。我希望你能抽出时间在回来给我的答案打差评之前阅读并理解相关系数与概率之间的关系:http://sahs.utmb.edu/pellinore/intro_to_research/wad/correlat.htm - Joshua Richardson
1
好的,我明白问题了:你的函数返回的p不是“不存在相关性的概率”。这在解释假设检验时是一个常见的错误。它是观察到在给定样本中rho=r的概率,而在总体中rho=0(零假设)的情况下。请参阅http://en.wikipedia.org/wiki/P-value#Misunderstandings 以获得详细的分解:“P值不是零假设为真的概率,也不是备择假设为假的概率。事实上,频率主义统计学不能将概率附加到假设中。” - Ben Allison
对于略带对抗性的语气,我表示歉意:在几百个字符的评论中很难表达愉快的情感! - Ben Allison
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接