如何用Python从零开始编写学生t检验

或许最广泛使用的统计假设检验之一是学生 t 检验。

由于您自己也可能在某天使用此测试,因此深入了解其工作原理非常重要。作为开发人员,最好通过自己动手从头开始实现假设检验来获得这种理解。

在本教程中,您将了解如何从头开始在 Python 中实现学生 t 检验统计假设检验。

完成本教程后,您将了解:

  • 学生 t 检验将对是否可能观察到两个样本发表评论,前提是这些样本是从同一总体中抽取的。
  • 如何从头开始为两个独立样本实现学生 t 检验。
  • 如何从头开始为两个相关样本实现配对学生 t 检验。

启动您的项目,阅读我的新书《机器学习统计学》,其中包括分步教程以及所有示例的Python源代码文件。

让我们开始吧。

How to Code the Student's t-Test from Scratch in Python

如何用Python从零开始编写学生t检验
照片由 n1d 拍摄,保留部分权利。

教程概述

本教程分为三个部分;它们是:

  1. 学生 t 检验
  2. 独立样本学生 t 检验
  3. 相关样本学生 t 检验

需要机器学习统计学方面的帮助吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

学生 t 检验

学生 t 检验是一种统计假设检验,用于检验两个样本是否预期是从同一总体中抽取的。

它以威廉·高赛特(William Gosset)使用的化名“Student”命名,他开发了该测试。

该测试通过检查两个样本的均值来查看它们是否显著不同。它通过计算均值差的标准误差来做到这一点,该标准误差可以解释为在两个样本具有相同均值(零假设)的情况下,观察到该差异的可能性有多大。

该测试计算出的 t 统计量可以通过与 t 分布的临界值进行比较来解释。临界值可以使用自由度和显著性水平通过百分点函数(PPF)来计算。

在双尾检验中,我们可以解释统计量值,这意味着如果我们拒绝零假设,可能是因为第一个均值小于或大于第二个均值。为此,我们可以计算检验统计量的绝对值,并将其与正(右尾)临界值进行比较,如下所示:

  • 如果 abs(t-statistic) <= critical value:接受均值相等的零假设。
  • 如果 abs(t-statistic) > critical value:拒绝均值相等的零假设。

我们还可以使用 t 分布的累积分布函数(CDF)来检索观察到 t 统计量绝对值的累积概率,以计算 p 值。然后可以将 p 值与所选的显著性水平(alpha),例如 0.05,进行比较,以确定是否可以拒绝零假设。

  • 如果 p > alpha:接受均值相等的零假设。
  • 如果 p <= alpha:拒绝均值相等的零假设。

在处理样本均值时,该测试假定两个样本都来自高斯分布。该测试还假定样本具有相同的方差和相同的大小,尽管如果这些假设不成立,则存在该测试的修正。例如,请参阅Welch's t-test

学生 t 检验主要有两种版本

  • 独立样本。两个样本不相关的案例。
  • 相关样本。样本相关的案例,例如对同一总体的重复测量。也称为配对检验。

学生 t 检验的独立样本和相关样本版本都可以在 Python 中通过 SciPy 函数 ttest_ind()ttest_rel() 分别获得。

注意:我建议在适用情况下使用这些 SciPy 函数来计算您应用程序的学生 t 检验。库实现会更快,并且不易出错。我只建议为了学习目的自己实现该测试,或者在需要对测试进行修改的情况下。

我们将使用 SciPy 函数来确认我们自己版本的测试结果。

请注意,仅供参考,本教程中提供的所有计算均直接摘自“ Statistics in Plain English”第三版(2010 年)的第 9 章“t 检验”。我提到这一点是因为您可能会根据您使用的参考文本看到不同形式的方程。

独立样本学生 t 检验

我们将从学生 t 检验最常见的形式开始:比较两个独立样本均值的情况。

计算

两个独立样本的 t 统计量计算如下:

或者

其中 X1X2 是第一个和第二个数据样本,sed 是均值之间差别的标准误差。

均值之间差别的标准误差可按以下方式计算:

其中 se1se2 是第一个和第二个数据集的标准误差。

样本的标准误差可计算为:

其中 se 是样本的标准误差,std 是样本标准差,n 是样本中的观测次数。

这些计算做出以下假设:

  • 样本是从高斯分布中抽取的。
  • 每个样本的大小大致相等。
  • 样本具有相同的方差。

实现

我们可以使用 Python 标准库、NumPy 和 SciPy 中的函数轻松实现这些方程。

假设我们的两个数据样本存储在变量 data1data2 中。

我们可以首先计算这些样本的均值,如下所示:

我们已经完成了一半。

现在我们需要计算标准误差。

我们可以手动完成,首先计算样本标准差:

然后是标准误差:

或者,我们可以使用 SciPy 的 sem() 函数直接计算标准误差。

我们可以使用样本的标准误差来计算“样本之间差值的标准误差

我们现在可以计算 t 统计量了

我们还可以计算一些其他值来帮助解释和展示统计量。

该测试的自由度计算为两个样本的观测值总和减去二。

临界值可以使用给定显著性水平(例如 0.05(95% 置信度))的百分点函数(PPF)来计算。

该函数在 SciPy 中可用于 t 分布,如下所示:

p 值可以使用 t 分布的累积分布函数(同样在 SciPy 中)来计算。

在这里,我们假设是一个双尾分布,其中零假设的拒绝可以解释为第一个均值小于或大于第二个均值。

我们可以将所有这些部分整合到一个简单的函数中,用于计算两个独立样本的 t 检验。

实例演示

在本节中,我们将对一些合成数据样本计算 t 检验。

首先,让我们生成两个具有相同方差 5 和不同均值分别为 50 和 51 的 100 个高斯随机数样本。我们期望该测试会拒绝零假设,并发现样本之间存在显著差异。

我们可以使用内置的 SciPy 函数 ttest_ind() 在这些样本上计算 t 检验。这将为我们提供一个 t 统计量值和一个 p 值,供我们进行比较,以确保我们正确实现了该测试。

完整的示例如下所示。

运行示例,我们可以看到 t 统计量值和 p 值。

我们将使用这些值作为我们在这些数据上进行测试的预期值。

我们现在可以使用上一节中定义的函数,将我们自己的实现应用于相同的数据。

该函数将返回 t 统计量值和临界值。我们可以使用临界值来解释 t 统计量,以查看测试结果是否显著,并且如我们所料,均值确实不同。

该函数还返回一个 p 值。我们可以使用 alpha(例如 0.05)来解释 p 值,以确定测试结果是否显著,并且如我们所料,均值确实不同。

我们预计两种解释将始终匹配。

完整的示例如下所示。

运行示例首先计算测试。

将打印测试结果,包括 t 统计量、自由度、临界值和 p 值。

我们可以看到 t 统计量和 p 值都与 SciPy 函数的输出匹配。测试似乎已正确实现。

然后使用 t 统计量和 p 值来解释测试结果。我们发现,正如预期的那样,有足够的证据拒绝零假设,表明样本均值可能不同。

相关样本学生 t 检验

现在我们可以来看计算相关样本学生 t 检验的情况了。

这种情况是我们从总体中收集一些观测值,然后应用一些处理,然后从同一样本收集观测值。

结果是两个大小相同的样本,其中每个样本的观测值是相关的或成对的。

相关样本的 t 检验被称为配对学生 t 检验。

计算

配对学生 t 检验的计算与独立样本的情况类似。

主要区别在于分母的计算。

其中 X1X2 是第一个和第二个数据样本,sed 是均值之间差别的标准误差。

此处,sed 计算为:

其中 sd 是相关样本均值差的标准差,n 是配对观测值的总数(例如,每个样本的大小)。

sd 的计算首先需要计算样本之间平方差的总和:

它还需要样本之间(未平方)差值的总和:

然后我们可以将 sd 计算为:

就是这样。

实现

我们可以在 Python 中直接实现配对学生 t 检验的计算。

第一步是计算每个样本的均值。

接下来,我们将需要配对的数量(n)。我们将在几个不同的计算中使用它。

接下来,我们必须计算样本的平方差总和以及差值总和。

我们现在可以计算均值之间的标准差了。

这然后用于计算均值差别的标准误差。

最后,我们拥有了计算 t 统计量所需的一切。

此实现与独立样本实现之间的唯一其他关键区别是自由度的计算。

与之前一样,我们可以将所有这些整合成一个可重用的函数。该函数将接收两个配对样本和一个显著性水平(alpha),并计算 t 统计量、自由度、临界值和 p 值。

完整的函数如下所示。

实例演示

在本节中,我们将使用与独立学生 t 检验相同的示例数据集。

这些数据样本不是配对的,但我们将假装它们是。我们期望该检验拒绝零假设,并发现样本之间存在显著差异。

与之前一样,我们可以使用 SciPy 函数来计算配对 t 检验来评估测试问题。在这种情况下,使用 `ttest_rel()` 函数。

完整的示例如下所示。

运行该示例将计算并打印 t 统计量和 p 值。

我们将使用这些值来验证我们自己的配对 t 检验函数的计算。

我们现在可以测试我们自己实现的配对学生 t 检验。

完整的示例,包括开发的函数和对函数结果的解释,列在下面。

运行示例将计算样本问题上的配对 t 检验。

计算出的 t 统计量和 p 值与我们从 SciPy 库实现中预期的相匹配。这表明实现是正确的。

t 检验统计量与临界值的解释,以及 p 值与显著性水平的解释,都得出了显著结果,拒绝了均值相等的零假设。

扩展

本节列出了一些您可能希望探索的扩展本教程的想法。

  • 将每个检验应用于您自己构造的样本问题。
  • 更新独立检验并添加对具有不同方差和样本量的样本的校正。
  • 对 SciPy 库中实现的其中一个检验进行代码审查,并总结实现细节上的差异。

如果您探索了这些扩展中的任何一个,我很想知道。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

书籍

API

文章

总结

在本教程中,您将学习如何从头开始在 Python 中实现学生 t 检验统计假设检验。

具体来说,你学到了:

  • 学生 t 检验将对是否可能观察到两个样本发表评论,前提是这些样本是从同一总体中抽取的。
  • 如何从头开始为两个独立样本实现学生 t 检验。
  • 如何从头开始为两个相关样本实现配对学生 t 检验。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

掌握机器学习统计学!

Statistical Methods for Machine Learning

培养对统计学的实用理解

...通过在 python 中编写代码

在我的新电子书中探索如何实现
机器学习的统计方法

它提供关于以下主题的自学教程
假设检验、相关性、非参数统计、重采样,以及更多...

探索如何将数据转化为知识

跳过学术理论。只看结果。

查看内容

如何从头开始用 Python 编写学生 t 检验的 52 条回复

  1. Tim Levine 2018 年 8 月 3 日 上午 6:48 #

    Jason,

    很棒的帖子,我很喜欢。

    一个让我困惑了很长时间的问题是,t 检验不要求两个总体都服从正态分布,而是要求*抽样分布*服从正态分布,而这要归功于中心极限定理,在样本量较大的情况下会发生这种情况。

    因此,抽取 200 个样本,每个样本的大小为 30,这些样本均值的分布将接近正态。

    大样本只会复制父群体。这就是为什么 t 检验如此有用的原因,因为即使父群体分布很奇怪(三角形),它也仍然有效。

  2. Sanjan TP 2019 年 2 月 20 日 下午 12:45 #

    嗨,Jason,

    感谢这篇写得很好且信息丰富的博文!我有两个小问题

    1)在上面的帖子中,您建议使用 abs(t-statistic)。在单侧 t 检验中,t 统计量的符号是否重要,或者它总是正数?

    2)基于“观测到的统计量值 > t 临界值”的解释是否总是与通过 p 值得出的解释相符?[令我惊讶的是,前者的公式 cv = t.ppf(1.0 – alpha, df) 需要预先指定 alpha 或显著性水平,而后者的公式 p = (1 – t.cdf(abs(t_stat), df)) * 2 却不需要]

    • Jason Brownlee 2019 年 2 月 20 日 下午 2:10 #

      这真的取决于您希望通过检验发现的具体内容,例如单尾或双尾。在这种情况下,我们保持非常简单——例如,假设这是一个右尾检验。

      解释总是必须匹配的。

  3. sanju 2019 年 3 月 9 日 下午 5:01 #

    我对假设检验是新手。那么对于单尾检验,我们如何修改此代码?

  4. Imerdar2323 2019 年 10 月 22 日 上午 3:19 #

    您是否有关于 A/B 测试的教程?我想它可能很相似,或者不是?一个专门的教程可能会带来清晰的解释。

    • Jason Brownlee 2019 年 10 月 22 日 上午 5:57 #

      谢谢您的建议,但 A/B 测试并非真正意义上的机器学习。

      它更像是统计学或实验设计。

      • Imerdar2323 2019 年 10 月 22 日 上午 10:27 #

        谢谢您的回答和您出色的整体工作。您说得对,但上面的内容也是如此,不是吗?

  5. Lloyd Courtenay 2019 年 11 月 9 日 下午 8:13 #

    一如既往,Jason,这篇帖子太棒了。
    快速提问
    我正在对一个庞大的数据集进行一项研究,该数据集有 1500 个观测值和 270 个变量。我注意到每个变量的标准差很大,但每个样本的均值却重叠很多。我正在进行一些统计实验,并注意到样本均值以外的其他方面的差异。
    是否可以将均值替换为中位数或其他方差度量?而不是比较均值差异,我能否替换为其他内容?或者该检验并非如此?这可能是一个愚蠢的问题,所以请原谅!如果不行,您是否知道其他比较样本分布而不使用均值的检验?
    我读过一些关于双权中值方差的工作,但也在寻找其他选择来尝试。
    谢谢

    • Jason Brownlee 2019 年 11 月 10 日 上午 8:20 #

      如果变量不是高斯分布,也许可以使用秩检验(例如非参数检验)?
      https://machinelearning.org.cn/nonparametric-statistical-significance-tests-in-python/

      • Lloyd Courtenay 2019 年 11 月 11 日 下午 7:28 #

        太棒了,我会试试的!谢谢回复!

        • Jason Brownlee 2019 年 11 月 12 日 上午 6:36 #

          不客气。

          • Lloyd Courtenay 2019 年 11 月 18 日 下午 8:38 #

            更新
            成功了!Kruskal 检验在我的特定数据集上效果非常好,并且结合 Wilcoxon 检验,我能够检测到一些有趣的模式,这使得整个研究非常有趣。

            另外,我还应用了 Levene 检验(这是我通过随机博客搜索到的),它也帮助我克服了困扰我研究的关于均值的问题。

            非常感谢 Jason,很棒的建议!

          • Jason Brownlee 2019 年 11 月 19 日 上午 7:40 #

            干得好!

  6. Pawel 2019 年 11 月 26 日 下午 10:25 #

    谢谢你,Jason!
    终于找到有人能如此直观地解释这个主题了。

    此致,

  7. Michelle 2020 年 2 月 13 日 上午 5:23 #

    嗨,Jason

    当我比较两个回归器时,是将 t 检验应用于 R2 分数等评分技能,还是更好地应用于 MSE?它们是否会显示不同的结果来拒绝零假设?

    此致,
    Michelle

  8. Michelle 2020 年 2 月 14 日 上午 12:37 #

    谢谢 Jason,我试过了,当我将 t 检验应用于从 10 折交叉验证中收集的 R2 分数时,结果与使用 RMSE 或 MSE 的结果不同,您知道为什么吗?

    谢谢。

    • Jason Brownlee 2020 年 2 月 14 日 上午 6:37 #

      我不知道 R^2 分数的预期分布以及该检验是否适用。

      也许可以发布到 CrossValidated?

      • Michelle 2020 年 2 月 14 日 下午 8:55 #

        嗨,Jason,

        你的意思是,发布到 CrossValidated?
        顺便说一句,我注意到当我将 t 检验应用于 MSE 以比较 SVR 和决策树时,如果我执行 10 折交叉验证,每个 MSE 样本有 10 个变量,结果是拒绝零假设,这与执行 20 折交叉验证并获得 20 个 MSE 样本 20 个变量的结果不同。您知道如何处理这种情况吗?谢谢。

  9. uma 2020 年 2 月 24 日 上午 10:53 #

    您能分享如何对 t 检验单样本进行功效分析吗?

  10. Nick 2020 年 5 月 8 日 上午 2:32 #

    嗨,Jason,
    您能演示一下如何进行单尾 t 检验吗?双尾检验用于判断它们是否相等或不相等,但如果您想查看哪个大于或小于另一个怎么办?

    • Jason Brownlee 2020 年 5 月 8 日 上午 6:38 #

      谢谢您的建议,希望我将来能提供一个示例。

  11. Jason Brownlee 2020 年 5 月 17 日 上午 6:34 #

    谢谢。

    这是一个打印浮点数和整数的语句。也许可以看看这个
    https://docs.pythonlang.cn/3/tutorial/inputoutput.html

  12. asdf 2020 年 6 月 29 日 下午 5:08 #

    当我将分类数据编码为数值数据时,我是否应该使用配对 t 检验?有序数据(好、一般、差)呢?
    当我发现 p 值大于 alpha 时,是否意味着我不拒绝零假设?并且这两个变量是相同的?
    谢谢。

  13. hank cooper 2020 年 10 月 17 日 上午 8:09 #

    请帮助

    我想看到 scipy.stats.t.ppf(q, df) 函数调用中使用的实际代码。

    也就是说,计算特定 t 值的代码,以便为表中的列/行条目提供行(1-alpha),列为自由度。

    我想看到这个是因为我想从头开始计算它。我有 Gamma 函数,但它没有提供正确的值。

    • Jason Brownlee 2020 年 10 月 17 日 下午 1:42 #

      scipy 的所有代码都可用
      https://github.com/scipy/scipy

      • hank cooper 2020 年 10 月 20 日 下午 2:04 #

        您可能对我的初始问题感到好奇,但我猜对我来说,这确实是尝试从头开始编写和导入库代码来完成这项工作。

        感谢您的回复,是的,您是对的,它在那里,但无论我怎么努力都找不到。根据文档,scipy.special.stdr 返回从 minus INF 到 t 的积分,根据以下计算:

        gamma((df+1)/2)/(sqrt(df*pi)*gamma(df/2) * intergral((1+x**2)/df)**(-df/2-1/2), x=-inf..t)
        这是 CDF……

        PPF 使用 stdtrit (df, q) 通过 stdtr(df.f) 返回上述 CDF 的逆。

        仍然找不到代码,所以我无法替换实际代码(scipy 存储库)来替换简单的 t.ppf(1 – alpha, df) 调用。

        我知道您很忙,但如果您有时间找到文件和行号,我很想知道。

        也许因为它有类抽象,所以很难提取!

  14. kh1994 2020 年 12 月 8 日 上午 4:26 #

    亲爱的杰森,您好,
    感谢您的精彩文章。我有一个问题。在许多文章中,我看到进行了单变量和多变量分析以进行特征选择。一些文章通过学生 t 检验报告了单变量分析的结果。他们为特征报告了 p 值和 AUC,并选择 AUC 较高的特征。实际上,我不知道在这种情况下 AUC 是什么(我已经知道 ROC AUC 用于多变量分析)。您能解释一下吗?在这种情况下 AUC 是如何计算的?

    • Jason Brownlee 2020 年 12 月 8 日 上午 7:47 #

      不客气。

      AUC 可能是 ROC AUC,但我建议直接询问作者。

  15. ranjeet shrivastav 2021 年 1 月 18 日 上午 1:21 #

    嗨,Jason,
    我有一个问题,如果两种情况下的打印语句中的均值相等,那么为什么我们在第一个打印语句中接受零假设而在 else 语句中拒绝它?

  16. Rupert 2021 年 3 月 8 日 上午 9:48 #

    嗨 Jason,总结得很棒——谢谢!

    使用 scipy.stats.t.ppf() 时,是否应设置位置和尺度参数?它们默认为 0 和 1,但这些数据围绕 50 中心分布,扩散度为 5。

    谢谢,Rupert

    • Jason Brownlee 2021 年 3 月 8 日 下午 1:34 #

      不客气。

      我不这么认为。也许可以查看使用文档。

  17. Desmond 2021 年 4 月 12 日 下午 6:51 #

    嗨 Jason,这非常有帮助。

    您能演示一下如何进行一个检验来比较两个独立样本均值之差吗?

    例如
    H0: u1 – u2 >= d
    H1: u1 – u2 < d
    其中 d 是用户定义的阈值

    我在网上搜索了很长时间但找不到演示。提前感谢。

  18. Alphonse 2021 年 11 月 24 日 下午 3:53 #

    嗨,Jason,
    感谢这篇帖子,

    如果我们不知道数据的方差是否相同,那么我们就不能使用这些方法,对吗?
    我们应该遵循这个
    https://machinelearning.org.cn/nonparametric-statistical-significance-tests-in-python/
    我说的对吗?

    • Adrian Tam
      Adrian Tam 2021 年 11 月 25 日 上午 3:35 #

      是的。基本上所有统计检验都有一些你必须遵守的假设,否则你会错误地解释结果。

  19. Alphonse 2021 年 11 月 24 日 下午 3:56 #

    我们可以对未知样本方差进行这 3 种检验:
    – Mann-Whitney U 检验
    – Wilcoxon 符号秩检验
    – Kruskal-Wallis H 检验
    from
    https://machinelearning.org.cn/statistical-hypothesis-tests-in-python-cheat-sheet/
    我说的对吗?

  20. Mus 2022 年 1 月 4 日 下午 11:52 #

    如果一个样本服从正态分布而另一个不服从,那么应该运行哪种检验?

    • James Carmichael 2022 年 1 月 13 日 上午 8:38 #

      嗨 Mus……T 检验就足够了。

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。