📊 T-tests và Chi-square Test
Mục tiêu bài học
Sau bài học này, bạn sẽ:
- Thực hiện One-sample và Two-sample T-tests
- Hiểu Paired vs Independent samples
- Áp dụng Chi-square test cho categorical data
- Chọn đúng test cho từng tình huống
1. T-test Overview
1.1 Khi nào dùng T-test?
| Điều kiện | Z-test | T-test |
|---|---|---|
| σ known | ✓ | |
| σ unknown | ✓ | |
| n < 30 | ✓ | |
| Population normal | ✓ | ✓ |
1.2 Các loại T-test
Các loại T-test
2. One-sample T-test
2.1 Mục đích
So sánh sample mean với một giá trị cụ thể (population mean giả định).
2.2 Test Statistic
Degrees of freedom: df = n - 1
2.3 Ví dụ
Bài toán: Claim caffeine content = 200mg. Mẫu 10 lon: mean = 195mg, std = 8mg. Test ở α = 0.05.
1from scipy import stats2import numpy as np34# Dữ liệu mẫu5sample = [192, 198, 190, 195, 202, 188, 197, 194, 199, 195]67# H₀: μ = 200, H₁: μ ≠ 2008mu_0 = 2009alpha = 0.051011# One-sample t-test12t_stat, p_value = stats.ttest_1samp(sample, mu_0)1314print(f"Sample mean: {np.mean(sample):.2f}")15print(f"Sample std: {np.std(sample, ddof=1):.2f}")16print(f"t-statistic: {t_stat:.4f}")17print(f"P-value: {p_value:.4f}")18print(f"df: {len(sample) - 1}")1920if p_value < alpha:21 print(f"\n→ Reject H₀: Mean khác 200mg")22else:23 print(f"\n→ Fail to Reject H₀: Không đủ bằng chứng")2.4 Manual calculation
1import numpy as np2from scipy import stats34sample = [192, 198, 190, 195, 202, 188, 197, 194, 199, 195]5mu_0 = 20067n = len(sample)8x_bar = np.mean(sample)9s = np.std(sample, ddof=1)10df = n - 11112# T-statistic13t = (x_bar - mu_0) / (s / np.sqrt(n))14print(f"t = {t:.4f}")1516# P-value (two-tailed)17p_value = 2 * (1 - stats.t.cdf(abs(t), df))18print(f"P-value = {p_value:.4f}")1920# Critical value21t_critical = stats.t.ppf(0.975, df)22print(f"Critical value (α=0.05): ±{t_critical:.4f}")3. Independent Two-sample T-test
3.1 Mục đích
So sánh means của 2 nhóm độc lập.
3.2 Assumptions
- ✅ Hai samples độc lập
- ✅ Data approximately normal
- ✅ Equal variances (có thể điều chỉnh)
3.3 Test Statistic
Equal variances (pooled):
3.4 Ví dụ
Bài toán: So sánh điểm thi giữa 2 lớp.
1from scipy import stats2import numpy as np34# Dữ liệu5class_A = [85, 90, 78, 92, 88, 76, 95, 89, 82, 91]6class_B = [72, 85, 80, 78, 88, 70, 82, 75, 79, 84]78alpha = 0.05910# H₀: μ_A = μ_B, H₁: μ_A ≠ μ_B1112# Descriptive stats13print("Class A:", f"mean={np.mean(class_A):.2f}, std={np.std(class_A, ddof=1):.2f}")14print("Class B:", f"mean={np.mean(class_B):.2f}, std={np.std(class_B, ddof=1):.2f}")1516# Independent t-test (equal variances assumed)17t_stat, p_value = stats.ttest_ind(class_A, class_B)18print(f"\nt-statistic: {t_stat:.4f}")19print(f"P-value: {p_value:.4f}")2021# Welch's t-test (unequal variances)22t_stat_welch, p_value_welch = stats.ttest_ind(class_A, class_B, equal_var=False)23print(f"\nWelch's t-test:")24print(f"t-statistic: {t_stat_welch:.4f}")25print(f"P-value: {p_value_welch:.4f}")2627if p_value < alpha:28 print(f"\n→ Reject H₀: Hai lớp có điểm khác nhau")29else:30 print(f"\n→ Fail to Reject H₀: Không đủ bằng chứng")3.5 Kiểm tra Equal Variances (Levene's Test)
1from scipy import stats23# Levene's test4# H₀: σ₁² = σ₂²5stat, p_value = stats.levene(class_A, class_B)6print(f"Levene's test: stat={stat:.4f}, p-value={p_value:.4f}")78if p_value > 0.05:9 print("→ Variances are equal, use standard t-test")10else:11 print("→ Variances are unequal, use Welch's t-test")4. Paired T-test
4.1 Mục đích
So sánh means của cùng một nhóm ở 2 thời điểm hoặc 2 điều kiện.
4.2 Test Statistic
Với d = difference cho mỗi pair
4.3 Ví dụ
Bài toán: So sánh cân nặng trước và sau chương trình giảm cân.
1from scipy import stats2import numpy as np34# Dữ liệu (same subjects)5before = [85, 90, 78, 92, 88, 76, 95, 89, 82, 91]6after = [82, 86, 75, 88, 84, 74, 90, 85, 79, 87]78alpha = 0.05910# H₀: μ_diff = 0 (không thay đổi)11# H₁: μ_diff ≠ 0 (có thay đổi)1213# Calculate differences14differences = np.array(before) - np.array(after)15print(f"Differences: {differences}")16print(f"Mean difference: {np.mean(differences):.2f}")1718# Paired t-test19t_stat, p_value = stats.ttest_rel(before, after)20print(f"\nt-statistic: {t_stat:.4f}")21print(f"P-value: {p_value:.4f}")2223if p_value < alpha:24 print(f"\n→ Reject H₀: Chương trình có hiệu quả")25else:26 print(f"\n→ Fail to Reject H₀: Không đủ bằng chứng")5. Chọn đúng T-test
Chọn đúng T-test
| Tình huống | Test |
|---|---|
| Mean vs target value | One-sample |
| Before vs After (same people) | Paired |
| Group A vs Group B (different people) | Independent |
6. Chi-square Test
6.1 Mục đích
Kiểm định mối quan hệ giữa categorical variables.
6.2 Các loại
| Test | Mục đích |
|---|---|
| Goodness of Fit | Data có fit distribution mong đợi? |
| Independence | 2 categorical variables có độc lập? |
7. Chi-square Goodness of Fit
7.1 Test Statistic
Với:
- O = Observed frequency
- E = Expected frequency
7.2 Ví dụ: Xúc xắc có cân không?
1from scipy import stats2import numpy as np34# Tung xúc xắc 600 lần5observed = [95, 105, 98, 110, 92, 100] # Số lần mỗi mặt6expected = [100] * 6 # Expected nếu fair78# Chi-square test9chi2, p_value = stats.chisquare(observed, expected)1011print(f"Observed: {observed}")12print(f"Expected: {expected}")13print(f"\nChi-square: {chi2:.4f}")14print(f"P-value: {p_value:.4f}")15print(f"df: {len(observed) - 1}")1617if p_value < 0.05:18 print("\n→ Reject H₀: Xúc xắc không cân")19else:20 print("\n→ Fail to Reject H₀: Xúc xắc có vẻ cân")8. Chi-square Test of Independence
8.1 Contingency Table
| Prefer A | Prefer B | Total | |
|---|---|---|---|
| Male | 30 | 45 | 75 |
| Female | 40 | 35 | 75 |
| Total | 70 | 80 | 150 |
8.2 Expected Frequency
8.3 Ví dụ
Bài toán: Giới tính có liên quan đến preference không?
1from scipy import stats2import numpy as np3import pandas as pd45# Contingency table6observed = np.array([[30, 45], # Male: A, B7 [40, 35]]) # Female: A, B89# Chi-square test of independence10chi2, p_value, dof, expected = stats.chi2_contingency(observed)1112print("=== Observed ===")13print(pd.DataFrame(observed, 14 index=['Male', 'Female'], 15 columns=['Prefer A', 'Prefer B']))1617print("\n=== Expected ===")18print(pd.DataFrame(expected.round(2), 19 index=['Male', 'Female'], 20 columns=['Prefer A', 'Prefer B']))2122print(f"\nChi-square: {chi2:.4f}")23print(f"P-value: {p_value:.4f}")24print(f"Degrees of freedom: {dof}")2526if p_value < 0.05:27 print("\n→ Reject H₀: Giới tính và preference có liên quan")28else:29 print("\n→ Fail to Reject H₀: Không có mối liên hệ")8.4 Cramér's V (Effect Size)
1def cramers_v(contingency_table):2 chi2, p, dof, expected = stats.chi2_contingency(contingency_table)3 n = contingency_table.sum()4 min_dim = min(contingency_table.shape) - 15 return np.sqrt(chi2 / (n * min_dim))67v = cramers_v(observed)8print(f"Cramér's V: {v:.4f}")910# Interpretation11if v < 0.1:12 print("→ Negligible association")13elif v < 0.3:14 print("→ Small association")15elif v < 0.5:16 print("→ Medium association")17else:18 print("→ Large association")9. Assumptions và Điều kiện
9.1 T-test Assumptions
| Assumption | Cách kiểm tra |
|---|---|
| Normality | Shapiro-Wilk test, Q-Q plot |
| Equal variances | Levene's test |
| Independence | Study design |
9.2 Chi-square Assumptions
- Expected frequency ≥ 5 trong mỗi cell
- Observations độc lập
1from scipy import stats23# Kiểm tra normality4data = [85, 90, 78, 92, 88, 76, 95, 89, 82, 91]5stat, p_value = stats.shapiro(data)6print(f"Shapiro-Wilk: stat={stat:.4f}, p={p_value:.4f}")7if p_value > 0.05:8 print("→ Data is approximately normal")10. Summary Table
| Test | Khi nào dùng | scipy function |
|---|---|---|
| One-sample t | Mean vs value | ttest_1samp |
| Independent t | 2 group means | ttest_ind |
| Paired t | Before/After | ttest_rel |
| Chi-square GoF | Fit distribution | chisquare |
| Chi-square Ind | Independence | chi2_contingency |
11. Bài tập thực hành
Bài tập 1: One-sample t-test
Claim: Battery life = 10 hours. Sample (n=15): mean=9.5, std=1.2. Test tại α = 0.05.
Bài tập 2: Independent t-test
| Drug A | Drug B |
|---|---|
| 23, 25, 28, 22, 26 | 30, 32, 29, 31, 28 |
Hai loại thuốc có hiệu quả khác nhau không?
Bài tập 3: Chi-square
| Thành công | Thất bại | |
|---|---|---|
| Method A | 60 | 40 |
| Method B | 45 | 55 |
Có mối liên hệ giữa method và outcome không?
Tóm tắt
| Test | H₀ | Statistic |
|---|---|---|
| One-sample t | μ = μ₀ | t = (x̄ - μ₀)/(s/√n) |
| Independent t | μ₁ = μ₂ | t = (x̄₁ - x̄₂)/SE |
| Paired t | μ_d = 0 | t = d̄/(s_d/√n) |
| Chi-square | Independent | χ² = Σ(O-E)²/E |
- One-sample t: sample mean vs known value
- Independent t: 2 different groups
- Paired t: same subjects, 2 conditions
- Chi-square: categorical variables
- Luôn kiểm tra assumptions trước khi test
