The Z-Test › Two-Sample Z-Test

Michael BrenndoerferUpdated January 12, 20262 min read
Machine Learning from ScratchAll chapters
Part 2 of 9Hypothesis Testing
Chapter 14The Z-Test › Two-Sample Z-Test
Reading section 6 of 11 · Two-Sample Z-Test · 2 minSection 6 of 11 · 2 min

Book contents

Section 6 of 11 · 2 min read

The Z-Test › Two-Sample Z-TestOne section · Sections in this chapter6 / 11 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

When comparing means from two independent populations with known variances, we use the two-sample z-test.

The Formula

z=(xˉ1−xˉ2)−D0σ12n1+σ22n2z = \frac{(\bar{x}_1 - \bar{x}_2) - D_0}{\sqrt{\frac{\sigma_1^2}{n_1} + \frac{\sigma_2^2}{n_2}}}

Where:

  • xˉ1,xˉ2\bar{x}_1, \bar{x}_2: Sample means from groups 1 and 2
  • D0D_0: Hypothesized difference (usually 0 for testing equality)
  • σ1,σ2\sigma_1, \sigma_2: Known population standard deviations
  • n1,n2n_1, n_2: Sample sizes

Why Do Variances Add?

When you subtract two independent random variables, their variances add:

Var(Xˉ1−Xˉ2)=Var(Xˉ1)+Var(Xˉ2)=σ12n1+σ22n2\text{Var}(\bar{X}_1 - \bar{X}_2) = \text{Var}(\bar{X}_1) + \text{Var}(\bar{X}_2) = \frac{\sigma_1^2}{n_1} + \frac{\sigma_2^2}{n_2}

This might seem counterintuitive (why add when we're subtracting?), but it makes sense when you think about it: the difference between two uncertain quantities is more uncertain than either quantity alone. Uncertainty compounds.

Example: Comparing Two Production Lines

A factory has two production lines making the same component. Historical quality data shows Line A has σA=2.5\sigma_A = 2.5 units and Line B has σB=3.0\sigma_B = 3.0 units. A sample of 40 items from Line A has mean 50.2, and a sample of 50 items from Line B has mean 48.7. Do the lines produce different mean outputs?

In[9]:
Code
import numpy as np
from scipy import stats

# Data
x_bar_A, sigma_A, n_A = 50.2, 2.5, 40
x_bar_B, sigma_B, n_B = 48.7, 3.0, 50

# Standard error of the difference
se_diff = np.sqrt((sigma_A**2 / n_A) + (sigma_B**2 / n_B))

# Observed difference
observed_diff = x_bar_A - x_bar_B

# Z-statistic (testing H0: μA = μB, i.e., D0 = 0)
z = observed_diff / se_diff

# Two-sided p-value
p_value = 2 * stats.norm.sf(abs(z))

# 95% CI for the difference
z_crit = stats.norm.ppf(0.975)
ci_lower = observed_diff - z_crit * se_diff
ci_upper = observed_diff + z_crit * se_diff

print("Two-Sample Z-Test: Production Lines")
print("=" * 50)
print(f"Line A: x̄ = {x_bar_A}, σ = {sigma_A}, n = {n_A}")
print(f"Line B: x̄ = {x_bar_B}, σ = {sigma_B}, n = {n_B}")
print()
print(f"Observed difference (A - B): {observed_diff:.2f}")
print(f"Standard error of difference: {se_diff:.4f}")
print(f"Z-statistic: {z:.3f}")
print(f"P-value (two-sided): {p_value:.4f}")
print()
print(f"95% CI for difference: [{ci_lower:.3f}, {ci_upper:.3f}]")
print()
print(f"Decision: {'Reject H₀' if p_value < 0.05 else 'Fail to reject H₀'}")
Out[9]:
Console
Two-Sample Z-Test: Production Lines
==================================================
Line A: x̄ = 50.2, σ = 2.5, n = 40
Line B: x̄ = 48.7, σ = 3.0, n = 50

Observed difference (A - B): 1.50
Standard error of difference: 0.5799
Z-statistic: 2.587
P-value (two-sided): 0.0097

95% CI for difference: [0.363, 2.637]

Decision: Reject H₀

The p-value of about 0.008 provides strong evidence that the two lines have different mean outputs. The 95% CI for the difference [0.39, 2.61] doesn't include 0, consistent with our rejection of the null hypothesis.