【问题标题】:How to perform two-sample, one-tailed t-test in Python如何在 Python 中执行两样本单尾 t 检验
【发布时间】:2020-08-06 08:16:05
【问题描述】:

我想执行一个双样本单尾 t 检验来比较两个均值。对于我正在寻找的具体问题,我希望仅在一个方向进行比较。我希望原假设是mu_2 > mu_1,而备择假设是mu_1 <= mu_2。或者,即使对于单尾情况,原假设仍然是 mu_1 - mu_2 = 0

我正在处理一个大型数据集,但如果我要提取和四舍五入参数,对于 data_1,它是 mu_1 = 4.3, s_1 = 4.8, and n_1 = 40000,而对于 data_2,它是 mu_2 = 4.9, s_2 = 4.4, n_2 = 30000。我正在使用 scipy 执行两个样本的 t 检验:

stats.ttest_ind(data1,
                data2,
                equal_var = False)

鉴于 scipy 仅考虑双尾测试,我不确定如何解释这些值。 Ttest_indResult(statistic=-19.51646312898464, pvalue=1.3452106729078845e-84)。 alpha 值为 0.05,p 值远小于表示拒绝原假设的值。但是,我的直觉告诉我不应该拒绝原假设,因为 mu_2 明显大于 mu_1(至少我希望 p 值更大)。因此,我觉得我要么错误地解释了结果,要么需要额外的计算才能得到正确的答案。

如果有任何额外的帮助和指导,我将不胜感激。谢谢!

【问题讨论】:

  • 从我读到的文档中,我读到 stats_ttest_ind 测试了两个均值相同的 NULL 假设,因此返回一个如此小的 p 值这一事实表明这两个均值差异太大而无法被偶然解释。在这种情况下,NULL 假设应该是 mu_1=mu_2,以保持测试简单。

标签: python scipy statistics inference t-test


【解决方案1】:

我为t检验p值计算提供了另一种解决方案。

from scipy.stats import ttest_ind
def t_test(x,y,alternative='both-sided'):
    _, double_p = ttest_ind(x,y,equal_var = False)
    if alternative == 'both-sided':
        pval = double_p
    elif alternative == 'greater':
        if np.mean(x) > np.mean(y):
            pval = double_p/2.
        else:
            pval = 1.0 - double_p/2.
    elif alternative == 'less':
        if np.mean(x) < np.mean(y):
            pval = double_p/2.
        else:
            pval = 1.0 - double_p/2.
    return pval

【讨论】:

    【解决方案2】:

    SciPy >= 1.6

    您现在可以使用文档中的“替代”参数进行两个样本一尾测试。在下面的示例中,我使用的是“less”,但这些是选项 Alternative{‘two-sided’, ‘less’, ‘greater’}

    https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind.html

    from scipy.stats import ttest_ind
    
    ttest, pval = ttest_ind(data1, data2, alternative="less")
    
    print("t-test", '{0:.10f}'.format(ttest[0]))
    print("p-value", '{0:.10f}'.format(pval[0]))
    
    if pval <0.05:
          print("we reject null hypothesis")
        else:
          print("we accept null hypothesis")
    

    【讨论】:

      【解决方案3】:

      你是对的,如果你在做一个单方面的测试,它应该有一个很大的 p 值。 ttest_ind 执行一个双边检验,它给出了您观察到比您的 t 统计量的绝对值更极端的概率。

      要进行单边 t 检验,您可以使用 cdf,它是直到您的 t 统计量的概率之和。

      稍微修改this code

      def welch_ttest(x1, x2,alternative):
          n1 = x1.size
          n2 = x2.size
          m1 = np.mean(x1)
          m2 = np.mean(x2)
          v1 = np.var(x1, ddof=1)
          v2 = np.var(x2, ddof=1)
          tstat = (m1 - m2) / np.sqrt(v1 / n1 + v2 / n2)
          df = (v1 / n1 + v2 / n2)**2 / (v1**2 / (n1**2 * (n1 - 1)) + v2**2 / (n2**2 * (n2 - 1)))
          if alternative == "equal":
              p = 2 * t.cdf(-abs(tstat), df)
          if alternative == "lesser":
              p = t.cdf(tstat, df)
          if alternative == "greater":
              p = 1-t.cdf(tstat, df)
          return tstat, df, p
      

      我模拟了一些数据:

      import numpy as np
      from scipy.stats import ttest_ind
      from scipy.stats import t
      
      np.random.seed(seed=123)
      data1 = np.random.normal(4.3,4.8,size=40000)
      np.random.seed(seed=123)
      data2 = np.random.normal(4.9,4.4,size=30000)
      ndf = len(data1) +len(data2) - 2
      ttest_ind(data1,data2,equal_var = False)
      
      Ttest_indResult(statistic=-16.945279258324227, pvalue=2.8364816571790452e-64)
      

      你得到类似你的结果,我们可以测试上面的代码替代 == "equal" 这是一个双面测试:

      welch_ttest(data1,data2,"equal")
      
          (<scipy.stats._continuous_distns.t_gen at 0x12472b128>,
           67287.08544468222,
           2.8364816571790452e-64)
      

      您可以使用与 scipy 2 边 t 检验相同的 p 值,现在我们进行您需要的单边检验:

      welch_ttest(data1,data2,"greater")
      (<scipy.stats._continuous_distns.t_gen at 0x12472b128>, 67287.08544468222, 1.0)
      

      【讨论】:

        猜你喜欢
        • 2018-10-09
        • 2020-02-05
        • 2020-09-05
        • 2014-05-01
        • 1970-01-01
        • 2020-06-25
        • 2020-06-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多