Logistic Classification
Sigmoid Function
Compute sigmoid(z) = 1/(1+e^{−z}) for a list of z values via a loop using
math.exp. Library: scipy.special.expit — numerically stable sigmoid for
arrays. RESULT: sigmoid values (rounded).
By hand
z=[-2,-1,0,1,2]. s(0)=0.5; s(1)=1/(1+e^{-1})≈0.7311; s(-1)≈0.2689; s(2)≈0.8808; s(-2)≈0.1192. Symmetric: s(-z)=1−s(z).
naive.py
Replay: real traced execution (multi-file project)
import math
z_vals = [-2, -1, 0, 1, 2]
result = []
for z in z_vals:
s = 1 / (1 + math.exp(-z))
result.append(round(s, 4))
print('RESULT:', result)
import math
1import math2z_vals = [-2, -1, 0, 1, 2]z_vals ← [-2, -1, 0, 1, 2]
1import math2z_vals = [-2, -1, 0, 1, 2]3result = []values this step[-2, -1, 0, 1, 2]z_valsresult ← []
2z_vals = [-2, -1, 0, 1, 2]3result = []4for z in z_vals:values this step[]resultz ← -2
3result = []4for z in z_vals:5 s = 1 / (1 + math.exp(-z))values this step-2zs ← 0.11920292202211755
4for z in z_vals:5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))values this step0.11920292202211755sresult ← [0.1192]
5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))7print('RESULT:', result)values this step[] → [0.1192]resultz ← -1
3result = []4for z in z_vals:5 s = 1 / (1 + math.exp(-z))values this step-2 → -1zs ← 0.2689414213699951
4for z in z_vals:5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))values this step0.11920292202211755 → 0.2689414213699951sresult ← [0.1192, 0.2689]
5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))7print('RESULT:', result)values this step[0.1192] → [0.1192, 0.2689]resultz ← 0
3result = []4for z in z_vals:5 s = 1 / (1 + math.exp(-z))values this step-1 → 0zs ← 0.5
4for z in z_vals:5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))values this step0.2689414213699951 → 0.5sresult ← [0.1192, 0.2689, 0.5]
5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))7print('RESULT:', result)values this step[0.1192, 0.2689] → [0.1192, 0.2689, 0.5]resultz ← 1
3result = []4for z in z_vals:5 s = 1 / (1 + math.exp(-z))values this step0 → 1zs ← 0.7310585786300049
4for z in z_vals:5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))values this step0.5 → 0.7310585786300049sresult ← [0.1192, 0.2689, 0.5, 0.7311]
5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))7print('RESULT:', result)values this step[0.1192, 0.2689, 0.5] → [0.1192, 0.2689, 0.5, 0.7311]resultz ← 2
3result = []4for z in z_vals:5 s = 1 / (1 + math.exp(-z))values this step1 → 2zs ← 0.8807970779778823
4for z in z_vals:5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))values this step0.7310585786300049 → 0.8807970779778823sresult ← [0.1192, 0.2689, 0.5, 0.7311, 0.8808]
5 s = 1 / (1 + math.exp(-z))6 result.append(round(s, 4))7print('RESULT:', result)values this step[0.1192, 0.2689, 0.5, 0.7311] → [0.1192, 0.2689, 0.5, 0.7311, 0.8808]resultfor z in z_vals:
3result = []4for z in z_vals:5 s = 1 / (1 + math.exp(-z))stdout ← RESULT: [0.1192, 0.2689, 0.5, 0.7311, 0.8808]
6 result.append(round(s, 4))7print('RESULT:', result)values this stepRESULT: [0.1192, 0.2689, 0.5, 0.7311, 0.8808]stdout
With SciPy
scipy.special.expit(z) computes 1/(1+exp(−z)) in a numerically stable way
(avoids overflow for large negative z). Works element-wise on lists or arrays.
library.py
from scipy.special import expit
from dalib.display import set_display
set_display()
z_vals = [-2, -1, 0, 1, 2]
result = [round(float(v), 4) for v in expit(z_vals)]
print('z_vals:', z_vals)
print('RESULT:', result)
z_vals: [-2, -1, 0, 1, 2]
RESULT: [0.1192, 0.2689, 0.5, 0.7311, 0.8808]
Implementation notes
- Sigmoid maps any real z to (0,1), making it suitable as a probability output. s(0)=0.5 is the decision boundary when thresholding at 0.5.
- Symmetric: s(−z) = 1 − s(z). Large positive z→1; large negative z→0.
expitis the canonical name in scipy (inverse of the logit function). For extreme z values, direct1/(1+exp(-z))can overflow in exp; expit uses a numerically stable equivalent.- Cross-reference:
normal-pdf-point(python-stats ch05) is another nonlinear function applied point-wise to transform a real input. - Used in:
logistic-predict-given-weights(this chapter) to turn a linear score into a class probability.