Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext
比較學生t測試兩個樣本的均值(Comparing the means of two samples with the Students-t test)

設想你有兩個樣本,並且我們希望知道這兩個樣本的均值是否相同。這種情況經常發生在確定一個新過程或一個新的療法(treatment)是否比一個舊過程或一個舊療法更好的時候。

在這個例子中,我們將會使用來自於NIST 網站Car Mileage 樣本數據 。這些數據比較美國汽車每公里的耗油量與日本汽車每公里的耗油量。

例子程序代碼在students_t_two_samples.cpp

這種測試可以通過兩種方式來構造:我們可以假定這兩個樣本的標準差是相等的或不相等的。如果假定標準差是相等的,那麼計算t-statistic將會大大簡化,我們將會首先測試這種情況。在實際生活中我們應當使用一個相等方差的χ方形測試(Chi-Squared test)來檢驗這個假設是否成立。

我們通過定義構造一個假定方差相等的測試函數來開始:

// 需要的頭文件:
#include <boost/math/distributions/students_t.hpp>
#include <iostream>
#include <iomanip>
// 簡化使用:
using namespace boost::math;
using namespace std;

void two_samples_t_test_equal_sd(
        double Sm1,       // Sm1 = Sample 1 Mean.
        double Sd1,       // Sd1 = Sample 1 Standard Deviation.
        unsigned Sn1,     // Sn1 = Sample 1 Size.
        double Sm2,       // Sm2 = Sample 2 Mean.
        double Sd2,       // Sd2 = Sample 2 Standard Deviation.
        unsigned Sn2,     // Sn2 = Sample 2 Size.
        double alpha)     // alpha = Significance Level.
{

我們的函數將通過計算 t-statistic 開始,假定方差相等,那麼需要的方程為:

其中 Sp 是 兩個樣本標準差的"合併(pooled)",v 是兩個合併樣本的自由度。我們現在可以寫出代碼來計算 t-statistic:

// 自由度:
double v = Sn1 + Sn2 - 2;
cout << setw(55) << left << "Degrees of Freedom" << "=  " << v << "\n";
// 合併的方差:
double sp = sqrt(((Sn1-1) * Sd1 * Sd1 + (Sn2-1) * Sd2 * Sd2) / v);
cout << setw(55) << left << "Pooled Standard Deviation" << "=  " << v << "\n";
// t-statistic:
double t_stat = (Sm1 - Sm2) / (sp * sqrt(1.0 / Sn1 + 1.0 / Sn2));
cout << setw(55) << left << "T Statistic" << "=  " << t_stat << "\n";

下一步是定義分佈對象,並計算概率的補集:

students_t dist(v);
double q = cdf(complement(dist, fabs(t_stat)));
cout << setw(55) << left << "Probability that difference is due to chance" << "=  " 
   << setprecision(3) << scientific << 2 * q << "\n\n";

在這裡我們使用 t-statistic 的絕對值,因為我們只是想知道這兩個樣本是否有差別。然而,我們也可以測試第二個樣本的均值比第一個的均值大還是小:所有可能的測試都列舉在下面的表中:

假設(Hypothesis)

測試

虛假設(Null-hypothesis):均值之間沒有差別

對於 |t| < significance level / 2:

如果cdf(complement(dist, fabs(t))) < alpha / 2 則否決

另一個假設:均值之間有差別

對於 |t| > significance level / 2:

如果cdf(complement(dist, fabs(t))) < alpha / 2 則否決

另一個假設: 樣本1的均值小於樣本二的均值

對於 t > significance level:

如果cdf(dist, t) > alpha 則否決

另一個假設: 樣本1的均值大於樣本2的均值

對於 t > significance level:

如果cdf(complement(dist, t)) > alpha 則否決

[Note] 注意

對於一個雙側測試( two-sided test),我們必須比較 alpha / 2 而不是 alpha。

這個測試程序的大部分工作都是在打印結果,我們將跳過這些,並看一下對於 alpha=0.05 (95% 概率水平)時的樣本輸出。 為了比較NIST/SEMATECH e-Handbook of Statistical Methods.section 1.3.5.3 的相同數據。

   ________________________________________________
   Student t test for two samples (equal variances)
   ________________________________________________

   Number of Observations (Sample 1)                      =  249
   Sample 1 Mean                                          =  20.14458
   Sample 1 Standard Deviation                            =  6.41470
   Number of Observations (Sample 2)                      =  79
   Sample 2 Mean                                          =  30.48101
   Sample 2 Standard Deviation                            =  6.10771
   Degrees of Freedom                                     =  326.00000
   Pooled Standard Deviation                              =  326.00000
   T Statistic                                            =  -12.62059
   Probability that difference is due to chance           =  5.273e-030

   Results for Alternative Hypothesis and alpha           =  0.0500

   Alternative Hypothesis              Conclusion
   Sample 1 Mean != Sample 2 Mean       NOT REJECTED
   Sample 1 Mean <  Sample 2 Mean       NOT REJECTED
   Sample 1 Mean >  Sample 2 Mean       REJECTED

因為由於偶然性而產生差別的概率為 5.273e-030,所以,我們可以很有把握地判斷這兩個樣本之間確實存在差別。

對於其它假設的測試顯示我們也必須否決樣本1的均值大於樣本2的均值:在這種情況下,樣本1是日本汽車 的每公里耗油量,樣本2是美國汽車的每公里耗測量,所以我們推斷出日本汽車比美國汽車更省油。

由於已經解決了簡單的情形,現在讓我們看一下更複雜的情形:兩個樣本的標準差不相等。在這種情況下,t-statistic測試的方程變為:

並且對於組合的自由度,我們使用Welch-Satterthwaite 逼近:

注意這是一個很少見的情況:學生t分佈的自由度為浮點數而不是整數。

[Note] 注意

一些統計類庫將這個有效的自由度截斷為一個整數自由度:如果你依賴於查找表,這可能是必需的,但是因為我們的代碼完全支持非整數自由度,因此在這種情況下沒有必要將浮點數截斷。同樣也要注意當自由度小於 Welch-Satterthwaite 逼近值時,這可能是一個重要的錯誤源。

將這些方程轉化為代碼,我們得到:

// 自由度:
double v = Sd1 * Sd1 / Sn1 + Sd2 * Sd2 / Sn2;
v *= v;
double t1 = Sd1 * Sd1 / Sn1;
t1 *= t1;
t1 /=  (Sn1 - 1);
double t2 = Sd2 * Sd2 / Sn2;
t2 *= t2;
t2 /= (Sn2 - 1);
v /= (t1 + t2);
cout << setw(55) << left << "Degrees of Freedom" << "=  " << v << "\n";
// t-statistic:
double t_stat = (Sm1 - Sm2) / sqrt(Sd1 * Sd1 / Sn1 + Sd2 * Sd2 / Sn2);
cout << setw(55) << left << "T Statistic" << "=  " << t_stat << "\n";

在這之後,代碼和測試與之前進行的是一樣的。再一次使用上面的測試數據,下面是輸出結果:

   __________________________________________________
   Student t test for two samples (unequal variances)
   __________________________________________________

   Number of Observations (Sample 1)                      =  249
   Sample 1 Mean                                          =  20.145
   Sample 1 Standard Deviation                            =  6.4147
   Number of Observations (Sample 2)                      =  79
   Sample 2 Mean                                          =  30.481
   Sample 2 Standard Deviation                            =  6.1077
   Degrees of Freedom                                     =  136.87
   T Statistic                                            =  -12.946
   Probability that difference is due to chance           =  1.571e-025

   Results for Alternative Hypothesis and alpha           =  0.0500

   Alternative Hypothesis              Conclusion
   Sample 1 Mean != Sample 2 Mean       NOT REJECTED
   Sample 1 Mean <  Sample 2 Mean       NOT REJECTED
   Sample 1 Mean >  Sample 2 Mean       REJECTED

這一次允許兩個樣本的方差存在差別產生了一個更高的可能性:觀測到的可能性變為chance alone (1.571e-025 與假設方差相等時的方差5.273e-030相比 )。然而,推斷仍然是相同的:美國汽車沒有日本汽車省油。


PrevUpHomeNext