Я пытаюсь написать свой собственный код на Python для вычисления t-статистики и p-значений для одно- и двусторонних независимых t-тестов. . Я могу использовать нормальное приближение, но на данный момент я пытаюсь просто использовать t-распределение. Мне не удалось сопоставить результаты библиотеки статистики SciPy с моими тестовыми данными. Я мог бы использовать свежую пару глаз, чтобы увидеть, не делаю ли я где-то глупую ошибку.
Обратите внимание, что это перекрестное сообщение из Cross-Validated, потому что оно какое-то время находилось там без ответов, поэтому я подумал, что не повредит также узнать мнение разработчиков программного обеспечения. Я пытаюсь понять, есть ли ошибка в используемом мной алгоритме, который должен воспроизвести результат SciPy.Это простой алгоритм, поэтому непонятно, почему я не могу найти ошибку.
Мой код:
import numpy as np
import scipy.stats as st
def compute_t_stat(pop1,pop2):
num1 = pop1.shape[0]; num2 = pop2.shape[0];
# The formula for t-stat when population variances differ.
t_stat = (np.mean(pop1) - np.mean(pop2))/np.sqrt( np.var(pop1)/num1 + np.var(pop2)/num2 )
# ADDED: The Welch-Satterthwaite degrees of freedom.
df = ((np.var(pop1)/num1 + np.var(pop2)/num2)**(2.0))/( (np.var(pop1)/num1)**(2.0)/(num1-1) + (np.var(pop2)/num2)**(2.0)/(num2-1) )
# Am I computing this wrong?
# It should just come from the CDF like this, right?
# The extra parameter is the degrees of freedom.
one_tailed_p_value = 1.0 - st.t.cdf(t_stat,df)
two_tailed_p_value = 1.0 - ( st.t.cdf(np.abs(t_stat),df) - st.t.cdf(-np.abs(t_stat),df) )
# Computing with SciPy's built-ins
# My results don't match theirs.
t_ind, p_ind = st.ttest_ind(pop1, pop2)
return t_stat, one_tailed_p_value, two_tailed_p_value, t_ind, p_ind
Обновление:
Прочитав немного больше о t-критерии Уэлча, я понял, что должен использовать формулу Уэлча-Саттертуэйта для вычисления степеней свободы. Я обновил код выше, чтобы отразить это.
С новыми степенями свободы я получаю более близкий результат. Мое двустороннее значение p отличается примерно на 0,008 от версии SciPy... но это все еще слишком большая ошибка, поэтому я все еще должен делать что-то неправильное (или функции распределения SciPy очень плохие, но в это трудно поверить). они точны только до 2 знаков после запятой).
Второе обновление:
Продолжая экспериментировать, я подумал, что, возможно, версия SciPy автоматически вычисляет нормальное приближение к t-распределению, когда степени свободы достаточно высоки (примерно > 30). Поэтому я повторно запустил свой код, используя вместо этого нормальное распределение, и вычисленные результаты на самом деле оказались дальше от SciPy, чем при использовании t-распределения.
Бонусный вопрос :) (Подробнее о статистической теории; не стесняйтесь игнорировать)
Кроме того, t-статистика отрицательна. Мне просто интересно, что это значит для одностороннего t-теста. Означает ли это обычно, что я должен смотреть в отрицательном направлении оси для теста? В моих тестовых данных популяция 1 — это контрольная группа, которая не проходила определенную программу профессионального обучения. Население 2 действительно получало его, и измеренные данные представляют собой разницу в заработной плате до/после лечения.
Итак, у меня есть основания полагать, что среднее значение для населения 2 будет больше.Но с точки зрения статистической теории кажется неправильным придумывать тест таким образом. Откуда я мог знать, что нужно проверить (для одностороннего теста) в отрицательном направлении, не полагаясь на субъективное знание данных? Или это просто одна из тех частых вещей, которые, хотя и не строги с философской точки зрения, необходимо делать на практике?