Null and Alternative Hypothesis
Every hypothesis test pits two competing claims against each other. Getting the setup right is crucial — the rest of the test follows mechanically from here.
The Two Hypotheses
Null Hypothesis (H₀)
The "status quo" or "no effect" claim. It is the claim we assume true until evidence forces us to reject it.
- Always contains an equality: =, ≤, or ≥
- Example: μ = 500 (mean equals 500)
Alternative Hypothesis (H₁ or Hₐ)
The research claim — what the investigator believes or wants to show evidence for.
- Always contradicts H₀: ≠, <, or >
- Example: μ ≠ 500 (mean differs from 500)
Important: We never "prove" H₀ or H₁. We either reject H₀ (strong evidence against it) or fail to reject H₀ (insufficient evidence).
One-Tailed vs Two-Tailed Tests
Two-tailed (non-directional)
Used when you are looking for a difference in either direction.
Left-tailed (lower one-tailed)
Used when you predict the parameter is less than the null value.
Right-tailed (upper one-tailed)
Used when you predict the parameter is greater than the null value.
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(42)
# Scenario: manufacturer claims batteries last 500 hours
# We sample 30 batteries and test if mean differs from 500
true_mean = 485 # batteries actually last less
sample = np.random.normal(true_mean, 40, 30)
x_bar = sample.mean()
s = sample.std(ddof=1)
n = len(sample)
print("=== Battery Life Test ===")
print(f"H₀: μ = 500 (manufacturer's claim)")
print(f"H₁: μ ≠ 500 (two-tailed: we check both directions)")
print(f"\nSample: n={n}, x̄={x_bar:.2f}, s={s:.2f}")
# Compute t-statistic
t_stat = (x_bar - 500) / (s / np.sqrt(n))
p_value_two = 2 * stats.t.sf(abs(t_stat), df=n-1)
p_value_left = stats.t.cdf(t_stat, df=n-1)
p_value_right = stats.t.sf(t_stat, df=n-1)
print(f"\nt-statistic = {t_stat:.4f}")
print(f"p-value (two-tailed): {p_value_two:.4f}")
print(f"p-value (left-tailed, H₁: μ<500): {p_value_left:.4f}")
print(f"p-value (right-tailed, H₁: μ>500): {p_value_right:.4f}")
alpha = 0.05
for tail, p in [("Two-tailed", p_value_two),
("Left-tailed", p_value_left),
("Right-tailed", p_value_right)]:
conclusion = "Reject H₀" if p < alpha else "Fail to reject H₀"
print(f"{tail}: p={p:.4f} → {conclusion}")
Formulating Hypotheses: A Framework
Step 1: Identify the parameter of interest (μ, p, σ², etc.)
Step 2: State H₀ — always includes equality, reflects current assumption
Step 3: State H₁ — reflects what you're testing for
Step 4: Determine one-tailed vs two-tailed based on the research question:
- "Is there a difference?" → Two-tailed
- "Is it larger than?" → Right-tailed
- "Is it less than?" → Left-tailed
| Research Question | H₀ | H₁ | Tail |
|---|---|---|---|
| Is treatment different? | μ₁ = μ₂ | μ₁ ≠ μ₂ | Two |
| Does drug reduce BP? | μ ≥ μ₀ | μ < μ₀ | Left |
| Does method increase yield? | μ ≤ μ₀ | μ > μ₀ | Right |
Common Mistakes
Mistake 1: Stating H₀ as what you want to prove
Wrong: H₀: The treatment works
Right: H₀: The treatment has no effect (H₁: it works)
Mistake 2: Using one-tailed when two-tailed is appropriate One-tailed gives a smaller p-value for results in the predicted direction — don't choose the tail after seeing the data (p-hacking!).
Mistake 3: Confusing "fail to reject H₀" with "H₀ is true" Absence of evidence is not evidence of absence.
Key Takeaways
- H₀ always contains equality and represents the status quo
- H₁ is the research hypothesis — what you're trying to demonstrate
- Choose one-tailed or two-tailed based on the question before collecting data
- Rejecting H₀ means the data is unlikely under H₀, not that H₁ is proven
- Failing to reject H₀ does not prove it true — you may just have low power