Linear and Quadratic Discriminant Analysis › Example

Michael BrenndoerferOctober 27, 20268 min read
Machine Learning from ScratchAll chapters
Part 7 of 15Supervised Learning Beyond Linear Models
Chapter 55Linear and Quadratic Discriminant Analysis › Example
Reading section 6 of 10 · Example · 8 minSection 6 of 10 · 8 min

Section 6 of 10 · 8 min read

Linear and Quadratic Discriminant Analysis › ExampleSection view · Sections in this chapter6 / 10 ↓
Reading tools Definitions, links & notes

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Notes & comments

We work through a small one-dimensional example with concrete numbers so that every step is visible. The point of the example is not to show a realistic data analysis, but to make the discriminant scores themselves tangible: we can compute them by hand, compare the LDA and QDA decisions, and see exactly where the quadratic boundary comes from. Consider a two-class problem with the following samples:

Class 0: {0,1,2,3},Class 1: {4,6,8,10}.\text{Class 0}:\ \{0, 1, 2, 3\}, \qquad \text{Class 1}:\ \{4, 6, 8, 10\}.

Both classes have four observations, so π^0=π^1=0.5\hat{\pi}_0 = \hat{\pi}_1 = 0.5. Equal priors keep the comparison focused on the densities: any difference in the decision must come from the class means and variances, not from one class being more common than the other.

Step 1: compute means and variances.

For class 0, the mean is μ^0=(0+1+2+3)/4=1.5\hat{\mu}_0 = (0 + 1 + 2 + 3)/4 = 1.5, and the unbiased variance is

σ^02=13∑i(xi−1.5)2=(−1.5)2+(−0.5)2+(0.5)2+(1.5)23=53≈1.667.\hat{\sigma}_0^2 = \frac{1}{3}\sum_{i}\bigl(x_i - 1.5\bigr)^2 = \frac{(-1.5)^2 + (-0.5)^2 + (0.5)^2 + (1.5)^2}{3} = \frac{5}{3} \approx 1.667.

For class 1, the mean is μ^1=(4+6+8+10)/4=7\hat{\mu}_1 = (4 + 6 + 8 + 10)/4 = 7, and the unbiased variance is

σ^12=(−3)2+(−1)2+(1)2+(3)23=203≈6.667.\hat{\sigma}_1^2 = \frac{(-3)^2 + (-1)^2 + (1)^2 + (3)^2}{3} = \frac{20}{3} \approx 6.667.

The empirical variance of class 1 is four times that of class 0, by construction of this small example. These sample spreads make the two fitted covariance conventions differ visibly. Four observations per class do not establish the covariances of an underlying population, so we treat this as a worked calculation rather than evidence that a real population violates LDA's assumption.

Step 2: pooled variance for LDA.

The pooled variance divides the total within-class squared deviations by the degrees of freedom N−K=8−2=6N - K = 8 - 2 = 6. The numerator is the sum of the within-class squared deviations: class 0 contributes 55 and class 1 contributes 2020, for a total of 5+20=255 + 20 = 25. Thus

σ^pooled2=5+206=256≈4.167.\hat{\sigma}_{\text{pooled}}^2 = \frac{5 + 20}{6} = \frac{25}{6} \approx 4.167.

This pooled value is a compromise between the tight class 0 variance and the broad class 1 variance. It is the single shape that LDA will use for both classes.

Step 3: LDA discriminant scores.

Using the exact pooled estimate σ^2=25/6≈4.167\hat{\sigma}^2=25/6\approx4.167, the one-dimensional linear discriminant is

δk(x)=μ^kσ^2 x−μ^k22σ^2+log⁡π^k\delta_k(x) = \frac{\hat{\mu}_k}{\hat{\sigma}^2}\, x - \frac{\hat{\mu}_k^2}{2 \hat{\sigma}^2} + \log \hat{\pi}_k

where:

  • μ^k\hat{\mu}_k: the estimated mean of class kk
  • σ^2=25/6≈4.167\hat{\sigma}^2 = 25/6 \approx 4.167: the pooled variance shared by both classes
  • π^k=0.5\hat{\pi}_k = 0.5: the estimated prior probability of class kk
  • xx: the (scalar) feature value being classified

Working through the two classes:

δ0(x)=1.525/6x−2.252⋅(25/6)+log⁡(0.5)≈0.36x−0.27−0.693=0.36x−0.963,\delta_0(x) = \frac{1.5}{25/6}x - \frac{2.25}{2 \cdot (25/6)} + \log(0.5) \approx 0.36 x - 0.27 - 0.693 = 0.36 x - 0.963, δ1(x)=725/6x−492⋅(25/6)+log⁡(0.5)≈1.68x−5.88−0.693=1.68x−6.573.\delta_1(x) = \frac{7}{25/6}x - \frac{49}{2 \cdot (25/6)} + \log(0.5) \approx 1.68 x - 5.88 - 0.693 = 1.68 x - 6.573.

At a test point x=3x = 3:

δ0(3)≈1.08−0.963=0.117,δ1(3)≈5.04−6.573=−1.533.\delta_0(3) \approx 1.08 - 0.963 = 0.117, \qquad \delta_1(3) \approx 5.04 - 6.573 = -1.533.

The larger score is δ0\delta_0, so LDA predicts class 0. At a test point x=5x = 5:

δ0(5)≈1.80−0.963=0.837,δ1(5)≈8.40−6.573=1.827.\delta_0(5) \approx 1.80 - 0.963 = 0.837, \qquad \delta_1(5) \approx 8.40 - 6.573 = 1.827.

Here LDA predicts class 1. The boundary between the two classes is where δ0(x)=δ1(x)\delta_0(x) = \delta_1(x), i.e., 0.36x−0.963=1.68x−6.5730.36x - 0.963 = 1.68x - 6.573. Solving: subtract 0.36x0.36x from both sides to get −0.963=1.32x−6.573-0.963 = 1.32x - 6.573; add 6.5736.573 to both sides to get 5.61=1.32x5.61 = 1.32x; divide by 1.321.32 to get x≈4.25x \approx 4.25. As expected, this is the midpoint of the two class means, 12(1.5+7)=4.25\tfrac{1}{2}(1.5 + 7) = 4.25. The equal-prior assumption removes any prior-driven shift, and the shared variance makes the boundary exactly halfway between the centers.

Step 4: QDA discriminant scores.

QDA keeps the class-specific variances. The discriminant is

δkQDA(x)=−(x−μ^k)22σ^k2−12log⁡σ^k2+log⁡π^k.\delta_k^{\text{QDA}}(x) = -\frac{(x - \hat{\mu}_k)^2}{2 \hat{\sigma}_k^2} - \tfrac{1}{2} \log \hat{\sigma}_k^2 + \log \hat{\pi}_k.

For class 0:

δ0QDA(x)=−(x−1.5)22(5/3)−12log⁡(5/3)+log⁡(0.5)≈−0.3(x−1.5)2−0.949.\delta_0^{\text{QDA}}(x) = -\frac{(x-1.5)^2}{2(5/3)}-\tfrac{1}{2}\log(5/3)+\log(0.5) \approx -0.3(x-1.5)^2-0.949.

where:

  • μ^0=1.5\hat{\mu}_0 = 1.5: the estimated mean of class 0
  • σ^02=5/3≈1.667\hat{\sigma}_0^2 = 5/3 \approx 1.667: the unbiased estimated variance of class 0
  • π^0=0.5\hat{\pi}_0 = 0.5: the estimated prior probability of class 0
  • xx: the test point at which the class-0 QDA score is evaluated

For class 1:

δ1QDA(x)=−(x−7)22(20/3)−12log⁡(20/3)+log⁡(0.5)≈−0.075(x−7)2−1.642.\delta_1^{\text{QDA}}(x) = -\frac{(x-7)^2}{2(20/3)}-\tfrac{1}{2}\log(20/3)+\log(0.5) \approx -0.075(x-7)^2-1.642.

At x=3x = 3:

δ0QDA(3)=−0.675−12log⁡(5/3)+log⁡(0.5)≈−1.624,δ1QDA(3)=−1.200−12log⁡(20/3)+log⁡(0.5)≈−2.842.\begin{aligned} \delta_0^{\text{QDA}}(3) &= -0.675-\tfrac{1}{2}\log(5/3)+\log(0.5) \approx -1.624,\\ \delta_1^{\text{QDA}}(3) &= -1.200-\tfrac{1}{2}\log(20/3)+\log(0.5) \approx -2.842. \end{aligned}

The quadratic contributions are exactly −(3−1.5)2/[2(5/3)]=−0.675-(3-1.5)^2/[2(5/3)]=-0.675 for class 0 and −(3−7)2/[2(20/3)]=−1.200-(3-7)^2/[2(20/3)]=-1.200 for class 1. The combined log-variance and log-prior constants are approximately −0.948560-0.948560 and −1.641707-1.641707, respectively; retaining them until the final rounding gives the scores above.

In each score, the quadratic contribution is minus one-half of the squared standardized distance. The remaining terms are the log-variance penalty and log prior. Both classes are evaluated at the same test point x=3x=3.

QDA also predicts class 0 at x=3x=3 because −1.624>−2.842-1.624>-2.842. At x=4.25x=4.25, where the exact LDA scores tie:

δ0QDA(4.25)≈−3.217,δ1QDA(4.25)≈−2.209.\delta_0^{\text{QDA}}(4.25) \approx -3.217, \qquad \delta_1^{\text{QDA}}(4.25) \approx -2.209.

QDA favors class 1 at x=4.25x=4.25, while LDA is indifferent there; a claim about different hard labels at that exact point would require an LDA tie-breaking convention. This point is 2.75 raw units from both means. Relative to the class standard deviations, that is about 2.13 standard deviations for class 0 and 1.07 for class 1. The quadratic contributions are −2.26875-2.26875 and −0.5671875-0.5671875. Class 1 pays the larger log-variance penalty, approximately −0.949-0.949 rather than −0.255-0.255, but its less negative quadratic contribution more than offsets that penalty. Thus the broader class has the higher QDA score at the midpoint.

Step 5: QDA decision boundary.

Solving δ0QDA(x)=δ1QDA(x)\delta_0^{\text{QDA}}(x)=\delta_1^{\text{QDA}}(x) gives a quadratic equation. We keep the exact variances and logarithms until the numerical evaluation:

−(x−1.5)210/3−12log⁡(5/3)+log⁡(0.5)=−(x−7)240/3−12log⁡(20/3)+log⁡(0.5).-\frac{(x-1.5)^2}{10/3}-\frac{1}{2}\log(5/3)+\log(0.5) = -\frac{(x-7)^2}{40/3}-\frac{1}{2}\log(20/3)+\log(0.5).

The equal log-prior terms cancel. Multiplying by 40/340/3 and collecting the log-variance difference gives

4(x−1.5)2−(x−7)2=203log⁡ ⁣(20/35/3)=203log⁡4=403log⁡2.\begin{aligned} 4(x-1.5)^2-(x-7)^2 &=\frac{20}{3}\log\!\left(\frac{20/3}{5/3}\right)\\ &=\frac{20}{3}\log 4\\ &=\frac{40}{3}\log 2. \end{aligned}

The left-hand side expands to 4(x2−3x+2.25)−(x2−14x+49)=4x2−12x+9−x2+14x−49=3x2+2x−404(x^2-3x+2.25)-(x^2-14x+49)=4x^2-12x+9-x^2+14x-49=3x^2+2x-40. Define the boundary polynomial

P(x)=3x2+2x−40−403log⁡2.P(x)=3x^2+2x-40-\frac{40}{3}\log 2.

Here P(x)P(x) is the exact quadratic whose zeros are the QDA ties, and log⁡\log is the natural logarithm. Since 403log⁡2≈9.241962\frac{40}{3}\log 2\approx9.241962, the constant term is approximately −49.241962-49.241962. The quadratic formula gives

x=−2± 4+12(40+403log⁡2) 6≈−4.398441or3.731774.\begin{aligned} x &=\frac{-2\pm\sqrt{\,4+12\left(40+\frac{40}{3}\log 2\right)\,}}{6}\\ &\approx -4.398441 \quad\text{or}\quad 3.731774. \end{aligned}

To determine the winning regions, subtract the exact class-0 score from the class-1 score:

403(δ1QDA(x)−δ0QDA(x))=P(x).\frac{40}{3}\left(\delta_1^{\text{QDA}}(x)-\delta_0^{\text{QDA}}(x)\right)=P(x).

The multiplier is positive, so the score difference has the same sign as P(x)P(x). Its positive leading coefficient makes P(x)P(x) negative between the roots and positive outside them. Class 0 therefore wins between the two roots, class 1 wins outside, and the endpoints are ties. The wider class wins in both far tails because its quadratic Mahalanobis contribution grows more slowly, while the class-0 penalty along its own metric dominates far from both centers. This two-tail allocation cannot be expressed by a single nondegenerate LDA threshold.

The worked example produces more than isolated labels: it produces two score curves whose crossings define the decision regions. The figure below evaluates the fitted LDA and QDA scores on a grid whose interval spans both QDA roots and the LDA midpoint. Compare the two classes within one method: each method may discard a different term common to its classes, so score heights across methods are not on a shared probability scale.

PythonIn [10]
CollapseExpand
qda_poly = np.array([3.0, 2.0, -40.0 - (40.0 / 3.0) * np.log(2.0)])
qda_roots_example = np.sort(np.roots(qda_poly))
x_example = np.linspace(
    min(-1.0, qda_roots_example[0] - 1.0),
    max(11.0, qda_roots_example[-1] + 1.0),
    500,
)
mu0_example, mu1_example = 1.5, 7.0
var0_example, var1_example = 5.0 / 3.0, 20.0 / 3.0
pooled_example = 25.0 / 6.0
log_prior_example = np.log(0.5)

lda0_example = (
    (mu0_example / pooled_example) * x_example
    - mu0_example**2 / (2.0 * pooled_example)
    + log_prior_example
)
lda1_example = (
    (mu1_example / pooled_example) * x_example
    - mu1_example**2 / (2.0 * pooled_example)
    + log_prior_example
)
qda0_example = (
    -0.5 * (x_example - mu0_example) ** 2 / var0_example
    - 0.5 * np.log(var0_example)
    + log_prior_example
)
qda1_example = (
    -0.5 * (x_example - mu1_example) ** 2 / var1_example
    - 0.5 * np.log(var1_example)
    + log_prior_example
)

lda_boundary_example = 0.5 * (mu0_example + mu1_example)
VisualizationOut [11]
CollapseExpand
LDA and QDA score curves with one linear crossing and two quadratic crossings.
LDA and QDA discriminant scores for the worked one-dimensional example evaluated on a dense grid. LDA scores cross once at the midpoint, while QDA scores cross twice, so class 0 wins between the roots and class 1 wins in both tails. The doubled crossings show how class-specific variances produce a two-tail allocation that no single nondegenerate LDA threshold can express.

Comments

Add to the conversation

A question, a correction, or an example from your own work.

No comments yet. Be the first to share your thoughts!

Newsletter

Stay up to date

Get new articles, book updates, and notes on AI and technology.

Unsubscribe at any time. Privacy policy