Saya mencoba untuk menulis kode Python saya sendiri untuk menghitung t-statistik dan nilai-p untuk satu dan dua uji t independen. Saya dapat menggunakan perkiraan normal, tetapi untuk saat ini saya hanya mencoba menggunakan distribusi-t. Saya tidak berhasil dalam mencocokkan hasil perpustakaan statistik SciPy pada data pengujian saya. Saya bisa menggunakan sepasang mata baru untuk melihat apakah saya hanya membuat kesalahan bodoh di suatu tempat.
Catatan, ini bukan pertanyaan coding karena ini adalah "mengapa perhitungan ini tidak menghasilkan t-stat yang tepat?" Saya memberikan kode untuk kelengkapan, tetapi jangan mengharapkan saran perangkat lunak. Hanya membantu memahami mengapa ini tidak benar.
Kode saya:
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
Memperbarui:
Setelah membaca sedikit lebih banyak tentang uji-Welch, saya melihat bahwa saya harus menggunakan rumus Welch-Satterthwaite untuk menghitung derajat kebebasan. Saya memperbarui kode di atas untuk mencerminkan ini.
Dengan derajat kebebasan baru, saya mendapatkan hasil yang lebih dekat. Nilai dua sisi saya mati sekitar 0,008 dari versi SciPy ... tapi ini masih merupakan kesalahan yang terlalu besar sehingga saya masih harus melakukan sesuatu yang salah (atau fungsi distribusi SciPy sangat buruk, tetapi sulit untuk percaya mereka hanya akurat di 2 tempat desimal).
Pembaruan kedua:
Sambil terus mencoba berbagai hal, saya pikir mungkin versi SciPy secara otomatis menghitung perkiraan Normal ke distribusi-t ketika derajat kebebasannya cukup tinggi (kira-kira> 30). Jadi saya kembali menjalankan kode saya menggunakan distribusi Normal, dan hasil yang dihitung sebenarnya jauh dari SciPy daripada ketika saya menggunakan distribusi-t.
numpy.var
. Versi yang saya lihat tampaknya mengindikasikan bahwa estimasi MLE dihitung secara default, bukan estimasi yang tidak bias. Untuk mendapatkan estimasi yang tidak bias kita perlu menyebutnya dengan opsional ddof=1
. ( 2 ) Untuk bagian atas ekor -nilai, menggunakan simetri dari -Distribusi, yaitu, dan ( 3 ) untuk dua ekor -nilai, melakukan sesuatu yang mirip: . one_tailed_p_value = st.t.cdf(-t_stat,df)
two_tailed_p_value = 2*st.t.cdf(-np.abs(t_stat),df)