Hypothesis Tests
Chi-Square Goodness-of-Fit Statistic
Compute the chi-square statistic: χ² = Σ (obs − exp)² / exp, summed over k
categories. A single loop accumulates the per-category contributions using a
diff intermediate. Library: scipy.stats.chisquare(observed, f_exp=expected)
— snapshot shows statistic + pvalue; RESULT is the statistic only, matching
.statistic. Observed and expected must share the same total.
By hand
4 categories, observed=[6,14,10,10] (total=40), expected=[10,10,10,10] (uniform, total=40). Per-category: (6−10)²/10=1.6, (14−10)²/10=1.6, (10−10)²/10=0, (10−10)²/10=0. χ² = 1.6+1.6+0+0 = 3.2.
observed = [6, 14, 10, 10]
expected = [10, 10, 10, 10]
k = len(observed)
chi2 = 0.0
for i in range(k):
diff = observed[i] - expected[i]
chi2 = chi2 + diff * diff / expected[i]
print('RESULT:', round(chi2, 4))
observed ← [6, 14, 10, 10]
1observed = [6, 14, 10, 10]2expected = [10, 10, 10, 10]values this step[6, 14, 10, 10]observedexpected ← [10, 10, 10, 10]
1observed = [6, 14, 10, 10]2expected = [10, 10, 10, 10]3k = len(observed)values this step[10, 10, 10, 10]expectedk ← 4
2expected = [10, 10, 10, 10]3k = len(observed)4chi2 = 0.0values this step4kchi2 ← 0.0
3k = len(observed)4chi2 = 0.05for i in range(k):values this step0.0chi2i ← 0
4chi2 = 0.05for i in range(k):6 diff = observed[i] - expected[i]values this step0idiff ← -4
5for i in range(k):6 diff = observed[i] - expected[i]7 chi2 = chi2 + diff * diff / expected[i]values this step-4diffchi2 ← 1.6
6 diff = observed[i] - expected[i]7 chi2 = chi2 + diff * diff / expected[i]8print('RESULT:', round(chi2, 4))values this step0.0 → 1.6chi2i ← 1
4chi2 = 0.05for i in range(k):6 diff = observed[i] - expected[i]values this step0 → 1idiff ← 4
5for i in range(k):6 diff = observed[i] - expected[i]7 chi2 = chi2 + diff * diff / expected[i]values this step-4 → 4diffchi2 ← 3.2
6 diff = observed[i] - expected[i]7 chi2 = chi2 + diff * diff / expected[i]8print('RESULT:', round(chi2, 4))values this step1.6 → 3.2chi2i ← 2
4chi2 = 0.05for i in range(k):6 diff = observed[i] - expected[i]values this step1 → 2idiff ← 0
5for i in range(k):6 diff = observed[i] - expected[i]7 chi2 = chi2 + diff * diff / expected[i]values this step4 → 0diffchi2 = chi2 + diff * diff / expected[i]
6 diff = observed[i] - expected[i]7 chi2 = chi2 + diff * diff / expected[i]8print('RESULT:', round(chi2, 4))i ← 3
4chi2 = 0.05for i in range(k):6 diff = observed[i] - expected[i]values this step2 → 3idiff = observed[i] - expected[i]
5for i in range(k):6 diff = observed[i] - expected[i]7 chi2 = chi2 + diff * diff / expected[i]chi2 = chi2 + diff * diff / expected[i]
6 diff = observed[i] - expected[i]7 chi2 = chi2 + diff * diff / expected[i]8print('RESULT:', round(chi2, 4))for i in range(k):
4chi2 = 0.05for i in range(k):6 diff = observed[i] - expected[i]stdout ← RESULT: 3.2
7 chi2 = chi2 + diff * diff / expected[i]8print('RESULT:', round(chi2, 4))values this stepRESULT: 3.2stdout
With the library
scipy.stats.chisquare(observed, f_exp=expected) returns statistic and
pvalue (df=k−1=3). The snapshot shows both; RESULT is the statistic.
from scipy import stats
from dalib.display import set_display
set_display()
observed = [6, 14, 10, 10]
expected = [10, 10, 10, 10]
result = stats.chisquare(observed, f_exp=expected)
print('statistic:', round(float(result.statistic), 4))
print('pvalue:', round(float(result.pvalue), 4))
print('RESULT:', round(float(result.statistic), 4))
statistic: 3.2
pvalue: 0.3618
RESULT: 3.2
Honesty
This lesson shows the computation exactly, on a tiny pinned sample. The arithmetic is correct and reproducible, but with a sample this small the result is not a valid statistical finding — it demonstrates the mechanism, not evidence. Real inference needs an adequate sample size and assumption checks (e.g. independence and expected counts ≥ 5 per cell); the p-value / interval here should be read as "how the formula is computed," not as a conclusion about a population.
Implementation notes
- Design rule §7: RESULT = statistic only; p-value is snapshot-only.
- df = k−1 = 3 (one degree of freedom lost because observed counts sum to a fixed total). Under H0 (observed follows the expected distribution), χ² follows a chi-square distribution with df=3.
- Requirement: observed and expected must sum to the same total; if expected are proportions, scale them to counts first.
- Valid when each expected count ≥ 5 (normal approximation to Poisson holds). Here all expected=10 ✓.
- Cross-reference:
frequency-count(data-basics) for computing raw observed counts from raw data before passing them here.