EE 541 - Unit 5
Dr. Brandon Franzke
Fall 2026
Task: Given features \(\mathbf{x} \in \mathbb{R}^d\), predict class \(y \in \{0, 1\}\)
Classical approach: Find decision boundary
Probabilistic approach: Estimate \(P(y=1|\mathbf{x})\)
Main challenges:
Classification pipeline:
The decision rule maps \(p\) to \(\hat{y}\):
Simple threshold:
This assumes all errors cost the same
Example: Credit card fraud
Optimal threshold depends on these costs
Different thresholds lead to different decisions
States (observations): \(\Omega = \{\omega_1, \omega_2, \ldots\}\)
Actions: \(\mathcal{A} = \{a_1, a_2, \ldots\}\)
Decision rule: \(\delta: \mathcal{X} \to \mathcal{A}\)
Loss function: \(L: \Omega \times \mathcal{A} \to \mathbb{R}\)
Objective: Minimize expected loss
Bayes risk: Minimum achievable expected loss
Bayes risk minimization:
Given observation \(\mathbf{x}\), choose action to minimize expected loss:
Expanding the expectation:
For binary classification with \(y \in \{0, 1\}\):
where \(p = P(Y=1|\mathbf{x})\)
Optimal decisions depend on:
Bayes rule minimizes expected loss at each point
0-1 Loss (uniform error cost):
Expected loss for action \(a\):
Minimizing expected loss:
This is the MAP rule!
MAP minimizes error probability when all errors cost the same
Bayes error rate (irreducible error):
No classifier can do better — this is the error from class overlap
Each region: highest posterior probability wins
Binary Bayes decision rule:
Choose class 1 if “expected loss of choosing 1” < “expected loss of choosing 0”:
where \(L_{ij}\) = loss of predicting \(j\) when true class is \(i\)
Using Bayes theorem:
Rearranging:
Likelihood Ratio Test:
where threshold \(\tau = \frac{L_{01}P(Y=0)}{L_{10}P(Y=1)}\)
Log-likelihood ratio (more stable):
Linear boundary in log-space → stability
Binary classification with costs:
where:
Expected loss of predicting 1:
Expected loss of predicting 0:
Optimal decision: Predict 1 if \(R_1(\mathbf{x}) < R_0(\mathbf{x})\)
Optimal threshold: \(\tau^* = \frac{c_{01}}{c_{01} + c_{10}}\)
Cancer screening scenario:
Realistic costs:
Loss matrix:
Note: treatment cost even for true positives
Optimal threshold:
Treat if \(P(\text{cancer}|\text{test}) > 0.05\)
Three-way decision:
Extended loss matrix:
where \(c_r\) = cost of rejection (expert review)
Decision regions:
Optimal thresholds (for symmetric costs):
Reject when model confidence is low
Reject option reduces error on uncertain samples
:::: {.columns}
K-class cost matrix: \(L \in \mathbb{R}^{K \times K}\)
Expected loss for action \(a\):
Optimal decision:
Example: 3-class with varying costs
Must compute expected loss for each action
Special case: If \(L_{ij} = 1 - \delta_{ij}\) (0-1 loss), reduces to argmax of posteriors
:::
Hard decisions: \(\hat{y} \in \{0, 1, ..., K-1\}\)
Soft decisions: \(\mathbf{p} = [p_0, p_1, ..., p_{K-1}]\)
Soft decisions ideal for:
Cascaded systems: Next stage uses probabilities
Confidence assessment: Reliability measures
Cost-sensitive decisions: Context-dependent losses
Ensemble methods: Combining multiple models
1. Discrimination (ranking ability):
2. Calibration (probability accuracy):
3. Proper scoring rules:
These penalize both discrimination and calibration errors
Note: Good discrimination ≠ Good calibration
Imbalanced data: 99% negative, 1% positive
Problem with accuracy:
Metrics for imbalanced data:
Precision: Of predicted positives, how many correct?
Recall (Sensitivity): Of true positives, how many found?
F1 Score: Harmonic mean
Connection to costs: Optimize threshold based on
where \(\pi\) = class prior P(y=1)
Try modeling probability directly:
With \(w = 0.3\), \(b = 0.5\):
Problem: Linear outputs \(\in (-\infty, \infty)\) but probabilities need \(\in [0, 1]\)
Need transformation \(\mathbb{R} \to [0, 1]\) that:
Candidates:
Odds: Alternative to probability
For binary outcome
Examples:
Range: \([0, \infty)\)
Log-odds (logit):
Range: \((-\infty, \infty)\)
Model log-odds linearly:
Solving for \(p(\mathbf{x})\):
Let \(z = \mathbf{w}^T\mathbf{x} + b\)
Gives the logistic (sigmoid) function
Inputs: \(\mathbf{x} = [x_1, x_2, \ldots, x_d]^T\)
Weights: \(\mathbf{w} = [w_1, w_2, \ldots, w_d]^T\)
Bias: \(b\)
Linear combination:
Activation function:
Output: \(p = P[\text{class 1}] \in (0, 1)\)
Decision rule: Predict class 1 if \(p > 0.5\)
Learning requires \(\frac{\partial \ell}{\partial \mathbf{w}}\). Since \(p = \sigma(\mathbf{w}^T\mathbf{x} + b)\), the chain rule needs \(\frac{d\sigma}{dz}\).
Start with: \(\sigma(z) = \frac{1}{1 + e^{-z}}\)
Apply chain rule:
Rewriting:
And:
This equals \(\sigma(-z) = 1 - \sigma(z)\)
Therefore:
Properties:
Computing \(p = \sigma(z)\) first gives derivative as \(p(1-p)\).
Other candidates that map \(\mathbb{R} \to [0,1]\):
Probit (cumulative normal):
Complementary log-log:
Logistic function advantages:
The sigmoid function \(\sigma(z) = \frac{1}{1 + e^{-z}}\):
Valid probabilities: \(\sigma(z) \in (0, 1)\) always
Smooth and differentiable:
Linear decision boundary:
Interpretable coefficients:
Logistic regression assumes:
Nonlinear boundaries: Concentric classes, XOR — no linear \(f(\mathbf{x})\) works
Outlier sensitivity: One extreme point pulls \(\|\mathbf{w}\| \to \infty\)
High dimensions (\(d > n\)): Perfect separation \(\Rightarrow\) \(\hat{\mathbf{w}}_{\text{MLE}}\) diverges
Misspecification: MLE finds best sigmoid approximation in KL divergence
Model: \(P(y=1|\mathbf{x}) = \sigma(\mathbf{w}^T\mathbf{x} + b)\)
Training data: \(\{(\mathbf{x}_i, y_i)\}_{i=1}^n\)
Objective: Find \(\mathbf{w}, b\) that make observed labels most probable
Equivalent to minimizing cross-entropy:
Gradient: \(\nabla_\mathbf{w} \ell = \sum_{i=1}^n (y_i - p_i)\mathbf{x}_i\)
Errors weighted by features — intuitive and cheap to compute
Problem: Classify emails as spam or legitimate
Features extracted from email:
Example vector \(\mathbf{x} \in \mathbb{R}^6\):
Email: "FREE OFFER! Click HERE!!!"
x = [2, 0.1, 2, 3, 1, 0.3]
↑ ↑ ↑ ↑ ↑ ↑
FREE low 2 3 1 3am
offer rep CAPS !! link
In practice, \(d\) = 100–10,000 features (bag-of-words counts, TF-IDF weights, metadata)
Goal: Learn \(P(\text{spam}|\mathbf{x})\)
Spam filters use 1000s of features
Model:
Training (gradient ascent on log-likelihood):
# Initialize w = np.random.randn(100) * 0.01 b = 0 for epoch in range(100): # Compute predictions z = X @ w + b p = sigmoid(z) # Gradient step grad_w = X.T @ (y - p) / n grad_b = np.mean(y - p) w += learning_rate * grad_w b += learning_rate * grad_b
Learned weights reveal spam indicators:
Target: >95% detection, <0.1% false positive, <10ms latency
Inference for new email:
def classify_email(email_text, w, b): # Extract features x = extract_features(email_text) # Compute probability z = np.dot(w, x) + b p_spam = sigmoid(z) # Decision with threshold if p_spam > 0.95: # High threshold return "spam", p_spam else: return "legitimate", p_spam
Example performance:
Advantages:
Threshold tuning possible since calibrated probabilities
Bayes theorem for weights (i.e., parameters):
Maximum a posteriori (MAP):
With uniform prior \(P(\mathbf{w}) = \text{const}\):
“Find parameters that make observed data most probable”
MLE properties:
For regression: Gaussian noise → squared loss
For classification: Bernoulli observations → cross-entropy loss
Each observation \(y_i \in \{0, 1\}\) is Bernoulli:
Compact form:
Check: \(y_i = 1\) gives \(p\), \(y_i = 0\) gives \(1-p\)
Likelihood (independent observations):
where \(p_i = \sigma(\mathbf{w}^T\mathbf{x}_i + b)\)
Log-likelihood (products become sums):
Why log?
Maximizing log-likelihood = Minimizing NLL:
This is binary cross-entropy loss
Dataset: 4 points in 1D
X = [-2, -1, 1, 2] y = [0, 0, 1, 1]
Current Model: \(p(x) = \sigma(wx + b)\)
with \(w = 0.5\), \(b = 0\)
Compute predictions:
Errors \(y - p\):
Log-likelihood:
So:
Total: \(\ell = -1.58\)
Negative log-likelihood: \(\text{NLL} = 1.58\)
Minimize this loss function
Gradient formulas (from earlier):
For our example:
\(\frac{\partial \ell}{\partial w}\):
\(\frac{\partial \ell}{\partial b}\):
Computing contributions:
| \(i\) | \(x_i\) | \(y_i\) | \(p_i\) | \((y_i - p_i)x_i\) |
|---|---|---|---|---|
| 1 | -2 | 0 | 0.27 | 0.54 |
| 2 | -1 | 0 | 0.38 | 0.38 |
| 3 | 1 | 1 | 0.62 | 0.38 |
| 4 | 2 | 1 | 0.73 | 0.54 |
Sum: \(\nabla_w \ell = 1.84\)
Gradient w.r.t. \(w\) positive: increase \(w\)
Gradient w.r.t. \(b\) zero: \(b\) locally optimal
Larger errors \(|y_i - p_i|\) contribute more to gradient.
Model: \(p = \sigma(\mathbf{w}^T\mathbf{x} + b)\)
Objective: Maximize log-likelihood
Gradient:
Update: Gradient ascent
Converge: When \(||\nabla \ell|| < \epsilon\)
Iterate until convergence (typical: 100s of steps)
Standard initialization:
w = np.random.randn(d) * 0.01 b = 0
Why random: Zero works but random is standard
Why small (0.01 scale):
Update rule (minimize NLL):
Addition follows from maximizing log-likelihood (equivalent to subtracting gradient of NLL)
With learning rate \(\eta = 0.5\):
New predictions:
NLL decreased from 1.582 to 0.506
Hessian = matrix of second derivatives
For logistic regression:
For our 1D example with current \(p = [0.27, 0.38, 0.62, 0.73]\):
Weights: \(p_i(1-p_i)\)
Hessian matrix:
For NLL minimization, consider \(-\mathbf{H}\):
Positive definite → Convex
Convexity guarantees convergence to global optimum
Generalize to \(n\) samples, \(d\) features:
Data matrix: \(\mathbf{X} \in \mathbb{R}^{n \times d}\)
Predictions: \(\mathbf{p} = \sigma(\mathbf{X}\mathbf{w} + b)\)
Gradient:
This equals \(\sum_{i=1}^n (y_i - p_i)\mathbf{x}_i\)
Hessian:
where \(\mathbf{D} = \text{diag}(p_1(1-p_1), \ldots, p_n(1-p_n))\)
Example for our 4-point dataset:
Theorem: NLL is strictly convex if \(\mathbf{X}\) has full rank.
Proof sketch:
Hessian: \(\mathbf{H} = -\mathbf{X}^T\mathbf{D}\mathbf{X}\)
For any \(\mathbf{v} \neq \mathbf{0}\):
Let \(\mathbf{u} = \mathbf{X}\mathbf{v}\):
Since \(0 < p_i < 1\): all \(p_i(1-p_i) > 0\)
Sum of positive terms → \(\geq 0\)
Equals 0 only if \(\mathbf{u} = \mathbf{0}\)
If \(\mathbf{X}\) full rank: \(\mathbf{X}\mathbf{v} = \mathbf{0} \Rightarrow \mathbf{v} = \mathbf{0}\)
Therefore: \(-\mathbf{H} \succ 0\) (positive definite)
Convexity implications:
| Property | Convex (Logistic) | Non-convex (Neural Net) |
|---|---|---|
| Local minima | None (only global) | Many |
| Optimization | Any method works | Can get stuck |
| Convergence | Guaranteed | No guarantee |
| Initial point | Doesn’t matter | Critical |
| Solution | Unique (if full rank) | Multiple |
Gradient Descent:
Newton’s Method:
Trade-off:
Fisher Information measures parameter certainty:
At convergence for our example:
Weights at optimum:
Low weights everywhere → High certainty
Asymptotic distribution:
High Fisher information → Low variance → Confident estimates
One-vs-Rest approach:
Problem: Probabilities do not sum to 1
Example with 3 classes:
Sum = 1.7 ≠ 1
Not valid probabilities for the K classes
Generalize sigmoid to K dimensions:
For binary case (K=2):
Softmax reduces to sigmoid when K=2
Valid probabilities: All outputs in (0,1), sum to 1
Preserves order: If \(z_i > z_j\), then \(p_i > p_j\)
Translation invariant:
Since: \(\frac{e^{z_k + c}}{\sum_j e^{z_j + c}} = \frac{e^c \cdot e^{z_k}}{e^c \cdot \sum_j e^{z_j}} = \frac{e^{z_k}}{\sum_j e^{z_j}}\)
Temperature scaling:
Problem: Exponentials overflow/underflow
z = [1000, 999, 998] exp(1000) → inf # Overflow
Solution: Take advantage of translation invariance
Subtract maximum before exponent
z = [1000, 999, 998] z_stable = z - max(z) = [0, -1, -2] softmax(z_stable) = [0.665, 0.245, 0.090] # Valid
Computing log of sum of exponentials:
Needed for:
Naive approach fails:
log(sum(exp([1000, 999, 998]))) → log(inf) → inf
Corrected approach is stable:
where \(m = \max(\mathbf{z})\)
m = max([1000, 999, 998]) = 1000 log_sum_exp = 1000 + log(sum(exp([0, -1, -2]))) = 1000 + log(1 + 0.368 + 0.135) = 1000 + 0.408 = 1000.408
For K classes, we need:
Model:
Over-parameterized:
Each boundary is linear (hyperplane)
One-hot encoding for labels:
Cross-entropy loss:
Since only one \(y_k = 1\):
For entire dataset:
where \(p_{i,y_i}\) is predicted probability for true class of sample \(i\)
The gradient has the same form as binary case
For sample \(i\) with true class \(y_i\):
where:
Derivation sketch:
For loss \(\ell = -\log p_k\) where \(k\) is the true class:
Scalar form: \(\frac{\partial \ell}{\partial z_k} = p_k - y_k\)
Matrix form: \(\nabla_{\mathbf{W}} \ell = \mathbf{X}^T(\mathbf{P} - \mathbf{Y})\)
Data: 3 points, 3 classes
X = [[1, 0], [-1, 0], [0, 1]] y = [0, 1, 2] # Class labels
Current parameters:
W = [[0.5, 0.2, 0], # w for class 0 [0.1, 0.3, 0]] # w for class 1,2 b = [0.1, 0, -0.1]
Computing predictions:
Point 1: \(\mathbf{x} = [1, 0]\)
The softmax has vector input and vector output, so its derivative is a Jacobian matrix:
3×3 Example with \(\mathbf{p} = [0.5, 0.3, 0.2]\):
General formula:
For this example:
Rows sum to 0 (probabilities sum to 1)
Perfect separation scenario:
# 2D data with polynomial features X = [[-2, -1], [-1, -2], [1, 2], [2, 1]] y = [0, 0, 1, 1] # Add polynomial features X_poly = [[x1, x2, x1², x2², x1x2] for x1, x2 in X]
With 5 features for 4 points:
The problem:
As ||w|| increases:
Example: 100 features, 80 samples
Without regularization:
n, d = 80, 100 # More features than samples X = np.random.randn(n, d) y = (X @ w_true + noise > 0).astype(int)
What happens during optimization:
Weight explosion occurs when:
Loss decreases but weights are unstable.
Modified objective:
Gradient with regularization:
Compare to unregularized:
Effect: Pull weights toward zero
Update rule:
Weight decay: Shrink by factor \((1 - 2\eta\lambda)\)
L2 Regularization = Bias toward smaller weights.
Larger λ → Smaller weights → More stable model
L2 regularization = Gaussian prior
Prior on weights:
MAP estimation:
Taking logarithm:
With \(\lambda = \frac{1}{2\sigma^2}\):
This is Ridge regression
Smaller σ gives stronger regularization
LASSO (Least Absolute Shrinkage and Selection Operator)
L1 penalty:
Subgradient (not differentiable at 0):
where \(\text{sign}(w) = \begin{cases} +1 & w > 0 \\ [-1, 1] & w = 0 \\ -1 & w < 0 \end{cases}\)
Induces exact sparsity: Many weights become exactly zero
Bayesian view: Laplace prior
L1 hits corners → Some weights exactly 0
Combine L1 and L2:
Alternative parameterization:
where:
Advantages:
Elastic Net: Selects groups of correlated features
k-fold cross-validation:
Split data into \(k\) “folds”
For each \(\lambda\):
Average validation error
Choose \(\lambda\) with lowest error
Common choices:
One standard error rule:
Larger λ within 1 SE yields simpler models with comparable performance
import numpy as np from scipy.special import expit as sigmoid def logistic_regression_l2(X, y, lambda_reg=0.1, lr=0.01, max_iter=1000): """Logistic regression with L2 regularization.""" n, d = X.shape w = np.zeros(d) b = 0 losses = [] for iteration in range(max_iter): # Forward pass z = X @ w + b p = sigmoid(z) # Loss = NLL + penalty nll = -np.mean(y * np.log(p + 1e-10) + (1-y) * np.log(1-p + 1e-10)) penalty = lambda_reg * np.sum(w**2) loss = nll + penalty losses.append(loss) # Gradients with regularization grad_w = -X.T @ (y - p) / n + 2 * lambda_reg * w grad_b = -np.mean(y - p) # Update parameters w -= lr * grad_w b -= lr * grad_b if iteration % 200 == 0: print(f"Iter {iteration}: Loss = {loss:.4f}, ||w|| = {np.linalg.norm(w):.4f}") return w, b, losses # Generate synthetic data np.random.seed(42) n, d = 100, 10 X = np.random.randn(n, d) w_true = np.random.randn(d) * 2 y = (X @ w_true + 0.5 * np.random.randn(n) > 0).astype(float) # Compare different λ values for lambda_val in [0, 0.1, 1.0]: print(f"\nλ = {lambda_val}:") w, b, losses = logistic_regression_l2( X, y, lambda_reg=lambda_val, lr=0.1, max_iter=400 ) print(f"Final ||w|| = {np.linalg.norm(w):.3f}")
λ = 0:
Iter 0: Loss = 0.6931, ||w|| = 0.0390
Iter 200: Loss = 0.2209, ||w|| = 2.6773
Final ||w|| = 3.670
λ = 0.1:
Iter 0: Loss = 0.6931, ||w|| = 0.0390
Iter 200: Loss = 0.5105, ||w|| = 0.9713
Final ||w|| = 0.972
λ = 1.0:
Iter 0: Loss = 0.6931, ||w|| = 0.0390
Iter 200: Loss = 0.6575, ||w|| = 0.1738
Final ||w|| = 0.174
Linear decision boundaries cannot solve XOR.
XOR (Exclusive OR):
No linear boundary exists
Any line through the space:
Logistic regression fails because:
enforces linear decision boundary
Solution: Add hidden layer
Neuron 1 (OR-like): \(h_1 = \sigma(x_1 + x_2 - 0.5)\)
Neuron 2 (NAND-like): \(h_2 = \sigma(-x_1 - x_2 + 1.5)\)
Output (AND): \(y = \sigma(h_1 + h_2 - 1.5)\)
Hidden representation \((h_1, h_2)\):
| Input | \(h_1\) | \(h_2\) | XOR |
|---|---|---|---|
| (0,0) | 0 | 1 | 0 |
| (0,1) | 1 | 1 | 1 |
| (1,0) | 1 | 1 | 1 |
| (1,1) | 1 | 0 | 0 |
In \((h_1, h_2)\) space: linearly separable
Same equations, different vocabulary:
| Logistic Regression | Neural Network |
|---|---|
| \(z = \mathbf{w}^T\mathbf{x} + b\) | pre-activation |
| \(p = \sigma(z)\) | activation |
| \(\mathcal{L} = -[y\log p + (1-y)\log(1-p)]\) | cross-entropy loss |
| \(\nabla_\mathbf{w}\ell = (y-p)\mathbf{x}\) | backpropagation (1 layer) |
Forward pass:
Backward pass (chain rule):
A single neuron with sigmoid activation is logistic regression. The gradient computation is backpropagation through one layer.
Two-layer network:
What stays the same:
What changes:
Each hidden unit: one linear boundary
Hidden layer: learned feature extractor
Output layer: linear classifier on \(\mathbf{h}\)
The key idea:
This is representation learning — the central idea behind deep learning
Logistic regression (convex):
Neural networks (non-convex):
Zero initialization breaks symmetry:
Random initialization:
Permutation symmetry: \(m\) hidden units → \(m!\) equivalent solutions from reordering alone
Logistic regression = neural network with 0 hidden layers
Adding layers:
What breaks:
Parameter growth:
| Architecture | Parameters |
|---|---|
| Single neuron | \(d + 1\) |
| 1 hidden (\(m\) units) | \((d+1)m + (m+1)\) |
| \(L\) layers | \(\sum_{l=1}^{L} (d_{l-1}+1)d_l\) |