Tôi đang cố gắng viết mã Python của riêng mình để tính toán thống kê t và giá trị p cho các thử nghiệm t độc lập một và hai đuôi. Tôi có thể sử dụng xấp xỉ bình thường, nhưng hiện tại tôi đang cố gắng chỉ sử dụng phân phối t. Tôi đã không thành công trong việc khớp kết quả của thư viện thống kê SciPy trên dữ liệu thử nghiệm của tôi. Tôi có thể sử dụng một đôi mắt mới để xem liệu tôi có đang phạm phải một sai lầm ngớ ngẩn nào đó không.
Lưu ý, đây không phải là quá nhiều câu hỏi mã hóa vì nó là "tại sao tính toán này không mang lại chỉ số đúng?" Tôi cung cấp mã cho đầy đủ, nhưng không mong đợi bất kỳ lời khuyên phần mềm nào. Chỉ cần giúp hiểu lý do tại sao điều này là không đúng.
Mã của tôi:
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
Cập nhật:
Sau khi đọc thêm một chút về bài kiểm tra t của Welch, tôi thấy rằng tôi nên sử dụng công thức Welch-Satterthwaite để tính mức độ tự do. Tôi đã cập nhật mã ở trên để phản ánh điều này.
Với mức độ tự do mới, tôi có được một kết quả gần hơn. Giá trị p hai mặt của tôi bị giảm khoảng 0,008 so với phiên bản SciPy ... nhưng đây vẫn là một lỗi quá lớn nên tôi vẫn phải làm gì đó không đúng (hoặc các hàm phân phối SciPy rất tệ, nhưng thật khó tin chúng chỉ chính xác đến 2 chữ số thập phân).
Cập nhật thứ hai:
Trong khi tiếp tục thử mọi thứ, tôi nghĩ có lẽ phiên bản SciPy sẽ tự động tính toán xấp xỉ Bình thường với phân phối t khi mức độ tự do đủ cao (khoảng> 30). Vì vậy, tôi đã chạy lại mã của mình bằng phân phối Bình thường và kết quả được tính toán thực sự cách xa SciPy hơn so với khi tôi sử dụng phân phối t.
numpy.var
ddof=1
one_tailed_p_value = st.t.cdf(-t_stat,df)
two_tailed_p_value = 2*st.t.cdf(-np.abs(t_stat),df)