Data Preparation
Standardize Features
Standardize a feature list to mean 0 and unit variance via (x − mean)/std,
where std uses ddof=0 (population std). Three loops: accumulate mean, accumulate
variance sum, apply transform. Library: sklearn.preprocessing.StandardScaler ().fit_transform(X). RESULT: standardized list (rounded). CRITICAL: sklearn
StandardScaler uses population std (ddof=0), NOT sample std (ddof=1).
By hand
data=[1,2,3,4,5], mean=3.0, population std=√(10/5)=√2≈1.4142 (ddof=0). Each value: (v−3)/1.4142. Standardized: [−1.4142, −0.7071, 0.0, 0.7071, 1.4142].
naive.py
Replay: real traced execution (multi-file project)
import math
data = [1, 2, 3, 4, 5]
n = len(data)
total = 0.0
for v in data:
total = total + v
mean = total / n
var_sum = 0.0
for v in data:
var_sum = var_sum + (v - mean) ** 2
std = math.sqrt(var_sum / n)
scaled = []
for v in data:
scaled.append(round((v - mean) / std, 4))
print('RESULT:', scaled)
import math
1import math2data = [1, 2, 3, 4, 5]data ← [1, 2, 3, 4, 5]
1import math2data = [1, 2, 3, 4, 5]3n = len(data)values this step[1, 2, 3, 4, 5]datan ← 5
2data = [1, 2, 3, 4, 5]3n = len(data)4total = 0.0values this step5ntotal ← 0.0
3n = len(data)4total = 0.05for v in data:values this step0.0totalv ← 1, total ← 1.0
pass 1 of 54total = 0.05for v in data:6 total = total + v7mean = total / nvalues this step1v0.0 → 1.0totalAll 5 passes — pass 1 is the card above pass vtotal1 1 0.0 → 1.0 2 1 → 2 1.0 → 3.0 3 2 → 3 3.0 → 6.0 4 3 → 4 6.0 → 10.0 5 4 → 5 10.0 → 15.0 for v in data:
4total = 0.05for v in data:6 total = total + vmean ← 3.0
6 total = total + v7mean = total / n8var_sum = 0.0values this step3.0meanvar_sum ← 0.0
7mean = total / n8var_sum = 0.09for v in data:values this step0.0var_sumv ← 1, var_sum ← 4.0
pass 1 of 58var_sum = 0.09for v in data:10 var_sum = var_sum + (v - mean) ** 211std = math.sqrt(var_sum / n)values this step5 → 1v0.0 → 4.0var_sumAll 5 passes — pass 1 is the card above pass vvar_sum1 5 → 1 0.0 → 4.0 2 1 → 2 4.0 → 5.0 3 2 → 3 — 4 3 → 4 5.0 → 6.0 5 4 → 5 6.0 → 10.0 for v in data:
8var_sum = 0.09for v in data:10 var_sum = var_sum + (v - mean) ** 2std ← 1.4142135623730951
10 var_sum = var_sum + (v - mean) ** 211std = math.sqrt(var_sum / n)12scaled = []values this step1.4142135623730951stdscaled ← []
11std = math.sqrt(var_sum / n)12scaled = []13for v in data:values this step[]scaledv ← 1, scaled ← [-1.4142]
pass 1 of 512scaled = []13for v in data:14 scaled.append(round((v - mean) / std, 4))15print('RESULT:', scaled)values this step5 → 1v[] → [-1.4142]scaledAll 5 passes — pass 1 is the card above pass vscaled1 5 → 1 [] → [-1.4142] 2 1 → 2 [-1.4142] → [-1.4142, -0.7071] 3 2 → 3 [-1.4142, -0.7071] → [-1.4142, -0.7071, 0.0] 4 3 → 4 [-1.4142, -0.7071, 0.0] → [-1.4142, -0.7071, 0.0, 0.7071] 5 4 → 5 [-1.4142, -0.7071, 0.0, 0.7071] → [-1.4142, -0.7071, 0.0, 0.7071, 1.4142] for v in data:
12scaled = []13for v in data:14 scaled.append(round((v - mean) / std, 4))stdout ← RESULT: [-1.4142, -0.7071, 0.0, 0.7071, 1.4142]
14 scaled.append(round((v - mean) / std, 4))15print('RESULT:', scaled)values this stepRESULT: [-1.4142, -0.7071, 0.0, 0.7071, 1.4142]stdout
With scikit-learn
StandardScaler().fit_transform(X) computes the same formula with ddof=0
internally. The snapshot shows the learned mean and scale for verification.
library.py
import numpy as np
from sklearn.preprocessing import StandardScaler
from dalib.display import set_display
set_display()
data = [1, 2, 3, 4, 5]
X = np.array(data).reshape(-1, 1)
scaler = StandardScaler()
scaled = [round(v, 4) for v in scaler.fit_transform(X).ravel().tolist()]
print('mean:', round(float(scaler.mean_[0]), 4))
print('std (ddof=0):', round(float(scaler.scale_[0]), 4))
print('RESULT:', scaled)
mean: 3.0
std (ddof=0): 1.4142
RESULT: [-1.4142, -0.7071, 0.0, 0.7071, 1.4142]
Implementation notes
- ddof trap: StandardScaler uses population std (ddof=0), dividing by n.
The
z-scoreslesson in python-stats ch02 used sample std (ddof=1, dividing by n−1) — the two produce different results for finite samples. Always match the formula to what the library uses when verifying parity. scaler.scale_equalsnp.std(data)(ddof=0 default), NOTnp.std(data, ddof=1).- After standardization the population mean is 0 and population std is 1; the sample std (ddof=1) is slightly above 1 for finite n.
- Cross-reference:
min-max-scale(this chapter) for the [0,1] alternative;z-scores(python-stats ch02) for the ddof=1 variant.