Sampling and Estimation
Standard Error
The standard error (SE) of the mean measures how much the sample mean
varies across repeated samples: SE = s/√n, where s is the sample standard
deviation (ddof=1). Two loops: mean, then sample std; divide by √n. Library:
scipy.stats.sem(sample) — defaults to ddof=1 (sample std), matching the
naive. Same fixed sample as seeded-sample-mean.
By hand
Sample [4, 7, 2, 9, 5, 9], n=6, mean=6.0. Loop 2: squared deviations [4,1,16,9,1,9] sum to 40; s=√(40/5)=√8≈2.828427. SE = √8/√6 = 2/√3 ≈ 1.154701.
import math
sample = [4, 7, 2, 9, 5, 9]
n = len(sample)
total = 0.0
for v in sample:
total = total + v
mean = total / n
sq_diff = 0.0
for v in sample:
sq_diff = sq_diff + (v - mean) ** 2
s = math.sqrt(sq_diff / (n - 1))
se = s / math.sqrt(n)
print('RESULT:', round(se, 6))
import math
1import math2sample = [4, 7, 2, 9, 5, 9]sample ← [4, 7, 2, 9, 5, 9]
1import math2sample = [4, 7, 2, 9, 5, 9]3n = len(sample)values this step[4, 7, 2, 9, 5, 9]samplen ← 6
2sample = [4, 7, 2, 9, 5, 9]3n = len(sample)4total = 0.0values this step6ntotal ← 0.0
3n = len(sample)4total = 0.05for v in sample:values this step0.0totalv ← 4, total ← 4.0
pass 1 of 64total = 0.05for v in sample:6 total = total + v7mean = total / nvalues this step4v0.0 → 4.0totalAll 6 passes — pass 1 is the card above pass vtotal1 4 0.0 → 4.0 2 4 → 7 4.0 → 11.0 3 7 → 2 11.0 → 13.0 4 2 → 9 13.0 → 22.0 5 9 → 5 22.0 → 27.0 6 5 → 9 27.0 → 36.0 for v in sample:
4total = 0.05for v in sample:6 total = total + vmean ← 6.0
6 total = total + v7mean = total / n8sq_diff = 0.0values this step6.0meansq_diff ← 0.0
7mean = total / n8sq_diff = 0.09for v in sample:values this step0.0sq_diffv ← 4, sq_diff ← 4.0
pass 1 of 68sq_diff = 0.09for v in sample:10 sq_diff = sq_diff + (v - mean) ** 211s = math.sqrt(sq_diff / (n - 1))values this step9 → 4v0.0 → 4.0sq_diffAll 6 passes — pass 1 is the card above pass vsq_diff1 9 → 4 0.0 → 4.0 2 4 → 7 4.0 → 5.0 3 7 → 2 5.0 → 21.0 4 2 → 9 21.0 → 30.0 5 9 → 5 30.0 → 31.0 6 5 → 9 31.0 → 40.0 for v in sample:
8sq_diff = 0.09for v in sample:10 sq_diff = sq_diff + (v - mean) ** 2s ← 2.8284271247461903
10 sq_diff = sq_diff + (v - mean) ** 211s = math.sqrt(sq_diff / (n - 1))12se = s / math.sqrt(n)values this step2.8284271247461903sse ← 1.1547005383792517
11s = math.sqrt(sq_diff / (n - 1))12se = s / math.sqrt(n)13print('RESULT:', round(se, 6))values this step1.1547005383792517sestdout ← RESULT: 1.154701
12se = s / math.sqrt(n)13print('RESULT:', round(se, 6))values this stepRESULT: 1.154701stdout
With the library
scipy.stats.sem(sample) uses ddof=1 by default — the same denominator as
numpy.std(ddof=1). The snapshot shows s separately so the two-step
structure is visible.
import numpy as np
from scipy.stats import sem
from dalib.display import set_display
set_display()
sample = [4, 7, 2, 9, 5, 9]
n = len(sample)
s = float(np.std(sample, ddof=1))
se = float(sem(sample))
print('n:', n)
print('s (ddof=1):', round(s, 6))
print('RESULT:', round(se, 6))
n: 6
s (ddof=1): 2.828427
RESULT: 1.154701
Honesty
This lesson shows the computation of the standard error exactly, on a tiny pinned sample. The value is arithmetically correct and reproducible, but computing SE from a handful of points demonstrates the formula, not a dependable estimate of precision — with so few observations the SE itself is unstable and rests on assumptions (independent, identically distributed draws). Read it as "how SE = s/√n is computed," not as a trustworthy margin; real precision claims need an adequate sample size and assumption checks.
Implementation notes
- SE = s/√n: larger n → smaller SE → more precise estimate. Quadrupling the sample size halves the SE (square-root law).
- ddof=1 trap:
scipy.stats.semdefaults to ddof=1; usingnp.std(ddof=0 default) for s and then dividing by √n would give a slightly different (biased) result. Always match ddof on both sides. - Cross-reference:
standard-deviation(ch02) for the s computation;seeded-sample-mean(this chapter) for the mean used here.