Как выполнить односторонний t-тест с двумя выборками в Python

Я хочу выполнить двухвыборочный односторонний 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). Значение альфа равно 0,05, а значение p намного меньше, чем значение, которое означало бы, что нулевая гипотеза отклоняется. Однако моя интуиция подсказывает мне, что нулевую гипотезу не следует отвергать, потому что mu_2 явно больше mu_1 (как минимум я ожидал бы, что p-значение будет больше). Поэтому мне кажется, что я либо неправильно интерпретирую результаты, либо мне нужны дополнительные вычисления, чтобы получить правильный ответ.

Буду признателен за любую дополнительную помощь и руководство. Спасибо!


person Jane Sully    schedule 23.04.2020    source источник
comment
Из документации я прочитал, что stats_ttest_ind проверяет гипотезу NULL о том, что два средства идентичны, поэтому тот факт, что возвращает такое маленькое значение p, указывает на то, что эти два средства слишком разные, чтобы их можно было объяснить случайным образом. Гипотеза NULL в этом случае должна быть mu_1 = mu_2, чтобы проверка была простой.   -  person Francesco Di Lauro    schedule 23.04.2020


Ответы (3)


Вы правы, если вы проводите односторонний тест, он должен иметь большое значение p. ttest_ind выполняет двусторонний тест, который дает вероятность того, что вы наблюдаете что-то более экстремальное, чем абсолютное значение вашей t-статистики.

Чтобы выполнить односторонний t-тест, вы можете использовать cdf, который представляет собой сумму вероятностей до вашей t-статистики.

Немного изменив этот код:

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)

Вы можете использовать то же значение p, что и двухсторонний t-тест scipy, теперь мы проводим необходимый вам односторонний тест:

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

Я предоставил другое решение для вычисления p-значения t-критерия.

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
person Dolittle Wang    schedule 25.06.2020

SciPy ›= 1,6

Теперь вы можете выполнить два образца теста с одним хвостом, используя альтернативный параметр в документации. В приведенном ниже примере я использую меньше, но это альтернативные варианты {"двусторонний", "меньше", "больше"}

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")
person Joe Rivera    schedule 15.02.2021