The perceptron
Run the perceptron update rule and prove convergence on linearly separable data with Novikoff's theorem.
The perceptron is the simplest classifier with a learning rule[1]: a linear discriminant trained by walking through the data and nudging the weight vector each time it misclassifies. It is a useful first stop because the algorithm is trivial, its convergence proof is short, and the geometric intuition (margin matters) seeds the SVM that comes next.
The classifier
For binary labels and features (with a constant 1 appended for an intercept), predict
A point is classified correctly when . The decision boundary is the hyperplane .
The update rule
Start with and pass through the data. On a mistake (a point with ), update
Geometrically: rotate slightly toward the side of the misclassified point. Repeat until no mistakes occur in a full pass.
Novikoff's convergence theorem
If the data are linearly separable with a margin , the perceptron makes a bounded number of mistakes[2].
Theorem. Assume there is a unit-norm vector () and such that for all , and that for all . Then the perceptron converges after at most updates.
Proof. Let be the weight after updates. Two invariants:
Lower bound on alignment with . Each update with example increases by . So , and by Cauchy-Schwarz .
Upper bound on weight norm. The squared norm grows by
using that updates happen only on mistakes (). So , i.e. .
Combining, , so .
The bound depends on the margin , not on the dataset size or dimension. A large margin makes learning fast; a tiny margin makes it slow. This is exactly the geometric quantity the SVM will maximize.
What the perceptron does not do
- It does not give probabilities.
- On nonseparable data it cycles forever (no convergence). Variants like the averaged perceptron or kernel perceptron address this.
- The hyperplane it finds is any separating hyperplane, not the maximum-margin one. The next lesson fixes this by explicitly maximizing the margin.
Check it on arrays
import numpy as np
rng = np.random.default_rng(0)
# Linearly separable dataset
n_per = 100
X_pos = rng.normal(loc=[2.5, 1.0], size=(n_per, 2))
X_neg = rng.normal(loc=[-1.5, -1.0], size=(n_per, 2))
X = np.vstack([X_pos, X_neg])
X = np.column_stack([np.ones(len(X)), X])
y = np.array([1] * n_per + [-1] * n_per)
def perceptron(X, y, max_passes=100):
w = np.zeros(X.shape[1])
mistakes = 0
for _ in range(max_passes):
any_mistake = False
for i in range(len(y)):
if y[i] * (w @ X[i]) <= 0:
w += y[i] * X[i]
mistakes += 1
any_mistake = True
if not any_mistake:
return w, mistakes
return w, mistakes
w, mistakes = perceptron(X, y)
print(f"converged after {mistakes} mistakes")
# Margin and bound: estimate gamma and R, check Novikoff prediction
acc = np.mean(np.sign(X @ w) == y)
print(f"training accuracy: {acc:.3f}")
R = np.max(np.linalg.norm(X, axis=1))
margins = y * (X @ w) / np.linalg.norm(w[1:]) # geometric margins (ignore intercept)
gamma = margins.min()
bound = (R / gamma)**2 if gamma > 0 else float("inf")
print(f"R = {R:.2f}, geometric margin gamma = {gamma:.3f}")
print(f"Novikoff bound (R/gamma)^2 = {bound:.0f}, actual mistakes = {mistakes}")The perceptron separates the two Gaussian blobs, achieves 100% training accuracy, and the actual mistake count sits below the Novikoff bound.
Exercises
Exercise 1. Two one-dimensional points are given: with and with . Using (unit norm in 1D), compute the margin and radius , then the Novikoff bound on the number of perceptron updates.
Solution
Step 1. The functional score of each point under is . For : . For : . Both equal , so the margin is .
Step 2. The radius bounds the input norm: .
Step 3. Novikoff's theorem caps the updates at
A single mistake suffices: starting from , the first misclassified point updates to a separating direction, after which both points are correct.
Exercise 2. Show that scaling every input by a constant (so ) leaves the geometric margin unchanged, hence leaves the Novikoff bound unchanged.
Solution
Step 1. Under , the separating direction is unchanged (the same hyperplane through the origin separates the rescaled data). The functional margin scales: , so the new margin is .
Step 2. The radius scales the same way: , so .
Step 3. The Novikoff bound depends on the ratio:
The cancels. Rescaling all inputs cannot make the perceptron converge in fewer steps; only the dimensionless ratio controls the bound.
Exercise 3 (code). The XOR labels are not linearly separable. Run the perceptron on the four XOR points for up to 1000 passes and confirm it never completes a mistake-free pass (it cycles), and that no setting of it reaches classifies all four correctly.
Solution
import numpy as np
# Bias-augmented XOR: first column is the constant intercept feature
X = np.array([[1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]], float)
y = np.array([-1, 1, 1, -1]) # XOR: differ -> +1, same -> -1
def perceptron(X, y, max_passes):
w = np.zeros(X.shape[1])
converged = False
for _ in range(max_passes):
any_mistake = False
for i in range(len(y)):
if y[i] * (w @ X[i]) <= 0:
w += y[i] * X[i]
any_mistake = True
if not any_mistake:
converged = True
break
return w, converged
w, converged = perceptron(X, y, max_passes=1000)
acc = np.mean(np.sign(X @ w) == y)
print(f"converged: {converged}, accuracy at stop: {acc:.2f}")
assert not converged # no mistake-free pass in 1000 tries
assert acc < 1.0 # the final w cannot separate XORThe loop exhausts all 1000 passes without a clean sweep: XOR has no linear separator, so Novikoff's premise (a positive margin) fails and the convergence guarantee does not apply. This is the gap the next lessons close by lifting the data into a richer feature space.
The next lesson asks for more: among all separating hyperplanes, which one is the best by a margin argument?
References
- [1]Rosenblatt, F. (1958). "The perceptron: a probabilistic model for information storage and organization in the brain". Psychological Review, 65(6), 386-408. The original perceptron model and learning rule (doi:10.1037/h0042519).↩
- [2]Bishop, C. M. (2006). Pattern Recognition and Machine Learning. Springer. §4.1.7 states and proves the perceptron convergence theorem.↩