Maximum Likelihood Estimation

Michael BrenndoerferOctober 25, 202651 min read

Learn maximum likelihood estimation from scratch, including Bernoulli and Gaussian estimators, log-likelihood, score, curvature, and NumPy/SciPy implementation.

Machine Learning from ScratchAll chapters
Part 3 of 15Model Fundamentals and Diagnostics
Chapter 29Maximum Likelihood Estimation
Reading the full chapter · 10 sections · 51 min10 sections · 51 min

All 10 sections · 51 min read

Maximum Likelihood EstimationFull chapter · Sections in this chapter1 / 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

Maximum Likelihood Estimation

Suppose we watch twenty visitors arrive at a website and twelve of them click a button. We want to estimate the underlying click probability. Or suppose a sensor returns five readings around 10 volts, and we want to estimate the true voltage and the measurement noise. In both cases we have data and a probability model with unknown parameters. Maximum likelihood estimation gives us a single, general recipe for turning those data into estimates. You choose the parameter values that make the observed data as plausible as possible under the model.

The likelihood is not the probability that a parameter is correct. Instead, we hold the observed data fixed and vary the parameter. For each candidate parameter value, we ask how likely the data would have been if that value had generated them. The maximum likelihood estimate, usually written θ^\hat\theta, is the parameter value with the largest likelihood. This reverses our usual perspective. A probability distribution varies the data while its parameter is fixed; a likelihood varies the parameter while the observed data are fixed. Keeping that distinction clear prevents many later mistakes, especially when we compare likelihoods with posterior distributions or confidence intervals.

Taking a logarithm turns a product of many probabilities into a sum of many terms, which is easier to differentiate and far less prone to numerical underflow. The resulting log-likelihood is the central object in this chapter. It connects naturally to loss functions: under independent Gaussian noise with a common positive variance, maximizing the likelihood over the mean parameters is equivalent to minimizing the sum of squared errors we studied in Sum of Squared Errors (SSE). You will derive the main estimators by hand, inspect the curvature that produces standard errors, and then implement the same calculations with NumPy and SciPy. The ideas here also prepare us for the next chapter on gradient descent and numerical optimization, where we study iterative parameter fitting and numerical checks.

Advantages

Maximum likelihood is a general construction rather than a single formula. Once we can write down a probability model for the data, we can form a likelihood, take its logarithm, and optimize. The same recipe produces the sample proportion for Bernoulli data, the sample mean and variance for Gaussian data, logistic regression coefficients for binary outcomes, and many survival and time-series models. This consistency is valuable because you do not need a new estimation principle for every model family.

The method also gives us more than a point estimate. The first derivative of the log-likelihood, called the score, tells us where the likelihood is flat. The second derivative, or curvature, tells us how sharply the likelihood peaks. That curvature produces approximate standard errors and confidence intervals. In regular models, the maximum likelihood estimator is asymptotically normal and asymptotically efficient. Under the regular asymptotic theory, it attains the inverse-information variance bound within the class of regular estimators. You should read that as a large-sample statement, not a promise that every finite-sample estimate is unbiased or precise.

Finally, maximum likelihood connects statistical modeling to machine learning losses. Gaussian likelihood leads to squared error, Bernoulli likelihood leads to log loss, and Poisson likelihood leads to a deviance loss. This makes likelihood a bridge between probability models, optimization objectives, and predictive evaluation. When we see a loss function in a machine learning model, it often has a likelihood interpretation behind it.

Disadvantages

Maximum likelihood inherits every assumption of the probability model. If we choose a Gaussian model for data with heavy outliers, the resulting mean can be pulled strongly toward those outliers. If correlated Bernoulli observations are treated as independent, the standard errors can be wrong. Positive covariance terms increase the variance of the sample proportion; negative terms can decrease it. With a misspecified model, the estimator may converge to a pseudo-true parameter that is closest to the data-generating process in a Kullback-Leibler sense. That parameter may not answer the scientific or business question you care about.

Maximum likelihood is also not guaranteed to be unbiased in finite samples. The Gaussian variance estimator is a standard example: it divides the sum of squared errors by nn, not n−1n-1, so it is biased downward on average. At boundaries, such as a Bernoulli probability estimated from all successes, the maximum may sit at the edge of the parameter space, and the usual normal approximation can break down. Some models are not identifiable, meaning different parameter values produce exactly the same distribution for the data, so no amount of data can separate them.

Numerical difficulties are common as well. The likelihood can be flat, multimodal, or unbounded in unconstrained parameterizations. Optimization may stop at a local maximum, fail because of scaling, or wander toward infinity when a parameter approaches a boundary. These are not reasons to avoid likelihood, but they are reasons to check convergence, inspect curvature, and report uncertainty rather than treating a single number as certain.

Formula

We can build the likelihood in three steps. First, hold the observed data fixed; they are no longer random quantities to be predicted. Second, choose a probability model that assigns a probability or density to each observation for any candidate parameter value. Third, compare candidate parameter values by asking which one gives the entire observed sample the highest combined plausibility. The formula below is simply the bookkeeping for those three steps.

Suppose we observe independent and identically distributed data y1,…,yny_1,\dots,y_n. Let f(yi;θ)f(y_i;\theta) be the probability mass function for discrete data or the probability density function for continuous data, where θ\theta is a parameter or a vector of parameters. The likelihood is

L(θ;y1,…,yn)=∏i=1nf(yi;θ).L(\theta; y_1,\dots,y_n) = \prod_{i=1}^{n} f(y_i;\theta).

where:

  • L(θ;y1,…,yn)L(\theta; y_1,\dots,y_n): the likelihood of the parameter θ\theta given the full observed sample
  • nn: the number of observations in the sample
  • yiy_i: the ii-th observed data value, held fixed as θ\theta varies
  • f(yi;θ)f(y_i;\theta): the probability mass (discrete case) or probability density (continuous case) assigned to yiy_i by the model with parameter θ\theta
  • ∏i=1n\prod_{i=1}^{n}: the product over all observations from i=1i=1 to i=ni=n

The product symbol ∏i=1n\prod_{i=1}^{n} means that we multiply the terms for i=1i=1 through i=ni=n. That multiplication is not an arbitrary convention. Independence is exactly what makes the joint probability or joint density of the sample factor into one term per observation. If the observations were dependent, the product of marginal terms would not be the joint distribution, and the likelihood would have to be built from the joint model instead. The semicolon in f(yi;θ)f(y_i;\theta) separates the observed data yiy_i from the parameter θ\theta; it reminds us that the data are fixed and θ\theta is the input we are varying. For discrete data, each f(yi;θ)f(y_i;\theta) is a probability, so the product is the probability of the observed sequence under independence. For continuous data, each term is a density, so the product is a likelihood density rather than the probability of observing an exact value.

The log-likelihood is

ℓ(θ)=log⁡L(θ;y1,…,yn)=log⁡∏i=1nf(yi;θ)(substitute the likelihood)=∑i=1nlog⁡f(yi;θ)(log of a product is a sum).\begin{aligned} \ell(\theta) &= \log L(\theta; y_1,\dots,y_n) \\ &= \log \prod_{i=1}^{n} f(y_i;\theta) && \text{(substitute the likelihood)} \\ &= \sum_{i=1}^{n} \log f(y_i;\theta) && \text{(log of a product is a sum)}. \end{aligned}

The symbols in this expression are:

  • ℓ(θ)\ell(\theta): the log-likelihood, the natural logarithm of the likelihood
  • log⁡\log: the natural logarithm
  • ∑i=1n\sum_{i=1}^{n}: the sum over all observations from i=1i=1 to i=ni=n
  • the remaining symbols are defined as above.

The logarithm is monotone increasing. If L(θ1)>L(θ2)L(\theta_1) > L(\theta_2), then ℓ(θ1)>ℓ(θ2)\ell(\theta_1) > \ell(\theta_2). Therefore the parameter that maximizes LL also maximizes ℓ\ell. Logs turn products into sums, which are easier to differentiate and much less likely to underflow when nn is large. It is common to see negative log-likelihood minimized instead, because optimization software usually minimizes rather than maximizes. These three facts, factorization under independence, monotone transformation, and numerical stability, explain nearly every manipulation that follows.

Likelihood and log-likelihood

The likelihood is a function of the parameter, not a probability distribution over the parameter. This point deserves emphasis. If we compute L(0.3)=0.002L(0.3)=0.002 and L(0.6)=0.010L(0.6)=0.010, we can say that the observed data are five times more likely under 0.60.6 than under 0.30.3 in the likelihood ratio sense. We cannot say that there is a 1% probability that the parameter equals 0.60.6. To obtain a probability distribution over θ\theta, we would need a prior distribution and a normalization step, which leads to Bayesian inference. Here we remain in the frequentist likelihood framework.

The independence assumption is what allows us to multiply the individual terms. If observations are correlated, the product of marginal probabilities is not the joint probability, and the likelihood must be built from the joint distribution instead. Identically distributed means that every observation has the same distribution. Independent observations may instead have different densities, all indexed by a shared parameter; their likelihood is still the product of those individual densities. Dependence requires a joint model.

For discrete data, the likelihood is a probability of the observed data. For continuous data, it is a density. A density can be greater than one when the distribution is concentrated over a narrow range, so a likelihood value above one is not an error. For estimation, what matters is the relative size of the likelihood at different parameter values, not whether the number looks like a probability.

To turn this function into an estimate, we need a way to locate its peak. The score is the first derivative of the log-likelihood:

s(θ)=∂ℓ(θ)∂θ.s(\theta) = \frac{\partial \ell(\theta)}{\partial \theta}.

where:

  • s(θ)s(\theta): the score, the first derivative of the log-likelihood with respect to the parameter
  • θ\theta: the parameter (or parameter vector) being estimated
  • ∂ℓ(θ)/∂θ\partial \ell(\theta)/\partial \theta: the partial derivative of the log-likelihood with respect to θ\theta

At a differentiable maximum in the interior of the parameter space, the score is zero:

s(θ^)=0.s(\hat\theta)=0.

This equation is called the score equation or the likelihood equation. In simple models we can solve it algebraically. In more complex models we solve it numerically. The score tells us the local slope of the log-likelihood. A positive score means increasing θ\theta increases the log-likelihood, and a negative score means decreasing θ\theta increases it. A zero score means we are at a flat point, which could be a maximum, a minimum, or a saddle point. A negative second derivative gives a strict local maximum in one dimension; a positive one gives a strict local minimum. A zero second derivative is inconclusive. For a vector parameter, negative definiteness of the Hessian is a sufficient local maximum test.

Bernoulli and Gaussian worked estimators

The general formula becomes concrete only after we choose a probability model. You now derive two estimators that appear constantly in practice. The first is the Bernoulli probability, which gives us the sample proportion. The second is the Gaussian mean and variance, which gives us the sample mean and the maximum likelihood variance. These derivations show how the general likelihood formula becomes a concrete estimate.

For Bernoulli data, each observation is either 11 or 00. Assume n>0n>0, and let p∈[0,1]p\in[0,1] be the probability of a success. For 0<p<10<p<1, the probability mass is

f(yi;p)=pyi(1−p)1−yi.f(y_i;p)=p^{y_i}(1-p)^{1-y_i}.

where:

  • yiy_i: the ii-th observation, taking the value 11 for a success or 00 for a failure
  • pp: the probability of a success, the unknown parameter
  • 1−p1-p: the probability of a failure

When yi=1y_i=1, this becomes p1(1−p)0=pp^1(1-p)^0=p. When yi=0y_i=0, it becomes p0(1−p)1=1−pp^0(1-p)^1=1-p. If we observe kk successes and n−kn-k failures, then the product over all observations is

L(p)=pk(1−p)n−k.L(p)=p^{k}(1-p)^{n-k}.

where:

  • kk: the number of observed successes
  • n−kn-k: the number of observed failures
  • pp: the success probability

The log-likelihood is

ℓ(p)=klog⁡p+(n−k)log⁡(1−p).\ell(p)=k\log p+(n-k)\log(1-p).

where:

  • ℓ(p)\ell(p): the log-likelihood for the Bernoulli success probability pp
  • kk: the number of observed successes
  • n−kn-k: the number of observed failures
  • pp: the success probability

Differentiating with respect to pp gives

dℓdp=kp−n−k1−p.\frac{d\ell}{dp}=\frac{k}{p}-\frac{n-k}{1-p}.

where:

  • dℓdp\frac{d\ell}{dp}: the derivative of the Bernoulli log-likelihood with respect to pp
  • kp\frac{k}{p}: the term contributed by the successes
  • −n−k1−p-\frac{n-k}{1-p}: the derivative term contributed by the failures

Setting this equal to zero, we multiply both sides by p(1−p)p(1-p):

k(1−p)−p(n−k)=0.k(1-p)-p(n-k)=0.

where:

  • kk: the number of observed successes
  • 1−p1-p: the candidate failure probability
  • n−kn-k: the number of observed failures
  • pp: the success probability

Expanding gives k−kp−pn+pk=0k-kp-pn+pk=0, and the −kp+pk-kp+pk terms cancel, leaving k−pn=0k-pn=0. Therefore

p^=kn.\hat p=\frac{k}{n}.

The second derivative is

d2ℓdp2=−kp2−n−k(1−p)2<0,\frac{d^2\ell}{dp^2}=-\frac{k}{p^2}-\frac{n-k}{(1-p)^2}<0,

where:

  • d2ℓdp2\frac{d^2\ell}{dp^2}: the second derivative of the Bernoulli log-likelihood
  • kp2\frac{k}{p^2}: the magnitude of the negative curvature contribution from the successes
  • n−k(1−p)2\frac{n-k}{(1-p)^2}: the magnitude of the negative curvature contribution from the failures

This derivative is negative for 0<p<10<p<1. With 0<k<n0<k<n, the stationary point is the unique global maximum. On the closed parameter space [0,1][0,1], k=0k=0 or k=nk=n puts the maximum at p=0p=0 or p=1p=1, using the limiting convention 0log⁡0=00\log 0=0. The plug-in Wald standard error is zero there, but that does not establish zero uncertainty. The interior information formula below is not valid at those endpoints.

If we only record the count kk rather than the exact sequence of successes and failures, the binomial likelihood is (nk)pk(1−p)n−k\binom{n}{k}p^k(1-p)^{n-k}. The binomial coefficient does not depend on pp, so it does not change the maximizing value. That is why we can work with the simpler Bernoulli form.

For Gaussian data, suppose yi∼N(μ,σ2)y_i\sim N(\mu,\sigma^2). The density is

f(yi;μ,σ2)=12πσ2exp⁡[−(yi−μ)22σ2].f(y_i;\mu,\sigma^2)=\frac{1}{\sqrt{2\pi\sigma^2}} \exp\left[-\frac{(y_i-\mu)^2}{2\sigma^2}\right].

where:

  • μ\mu: the mean of the normal distribution
  • σ2\sigma^2: the variance of the normal distribution
  • σ\sigma: the standard deviation, the positive square root of the variance
  • exp⁡[⋅]\exp[\cdot]: the exponential function

The log-likelihood for all nn observations is

ℓ(μ,σ2)=−n2log⁡(2π)−n2log⁡(σ2)−12σ2∑i=1n(yi−μ)2.\ell(\mu,\sigma^2) = -\frac{n}{2}\log(2\pi) -\frac{n}{2}\log(\sigma^2) -\frac{1}{2\sigma^2}\sum_{i=1}^{n}(y_i-\mu)^2.

where:

  • ℓ(μ,σ2)\ell(\mu,\sigma^2): the Gaussian log-likelihood for all nn observations
  • nn: the number of observations
  • log⁡(2π)\log(2\pi): the constant log term from the normalizing factor
  • log⁡(σ2)\log(\sigma^2): the log of the variance
  • 12σ2∑i=1n(yi−μ)2\frac{1}{2\sigma^2}\sum_{i=1}^{n}(y_i-\mu)^2: the sum of squared deviations divided by twice the variance

To estimate μ\mu, we differentiate with respect to μ\mu. The first two terms do not depend on μ\mu, and the derivative of the squared term brings down a factor of −2(yi−μ)-2(y_i-\mu):

∂ℓ∂μ=1σ2∑i=1n(yi−μ).\frac{\partial \ell}{\partial \mu} = \frac{1}{\sigma^2}\sum_{i=1}^{n}(y_i-\mu).

where:

  • ∂ℓ∂μ\frac{\partial \ell}{\partial \mu}: the score with respect to the Gaussian mean
  • σ2\sigma^2: the variance of the normal distribution
  • yi−μy_i-\mu: the deviation of the ii-th observation from the candidate mean

Setting this to zero gives

∑i=1n(yi−μ)=0⟹∑i=1nyi−nμ=0⟹μ^=1n∑i=1nyi=yˉ.\sum_{i=1}^{n}(y_i-\mu)=0 \quad\Longrightarrow\quad \sum_{i=1}^{n}y_i-n\mu=0 \quad\Longrightarrow\quad \hat\mu=\frac{1}{n}\sum_{i=1}^{n}y_i=\bar y.

where:

  • ∑i=1n(yi−μ)=0\sum_{i=1}^{n}(y_i-\mu)=0: the score set to zero
  • ∑i=1nyi\sum_{i=1}^{n}y_i: the sum of all observations
  • nμn\mu: the sum if every observation were equal to μ\mu
  • μ^\hat\mu: the maximum likelihood estimate of the mean
  • yˉ\bar y: the sample mean

The maximum likelihood estimate of the mean is the sample mean. This result does not depend on the value of σ2\sigma^2.

To estimate the variance, let v=σ2v=\sigma^2 and write the sum of squared deviations as

SSE=∑i=1n(yi−yˉ)2.\mathrm{SSE}=\sum_{i=1}^{n}(y_i-\bar y)^2.

After substituting μ=yˉ\mu=\bar y, the profile log-likelihood for v>0v>0 becomes

ℓ(yˉ,v)=−n2log⁡(2π)−n2log⁡v−SSE2v.\ell(\bar y,v) = -\frac{n}{2}\log(2\pi) -\frac{n}{2}\log v -\frac{\mathrm{SSE}}{2v}.

where:

  • ℓ(yˉ,v)\ell(\bar y,v): the Gaussian log-likelihood with the mean fixed at its fitted value and candidate variance vv
  • nn: the number of observations
  • vv: the candidate variance σ2\sigma^2
  • SSE\mathrm{SSE}: the sum of squared deviations from the sample mean

Differentiating with respect to vv gives

∂ℓ∂v=−n2v+SSE2v2.\frac{\partial \ell}{\partial v} = -\frac{n}{2v}+\frac{\mathrm{SSE}}{2v^2}.

Setting this to zero, we multiply by 2v22v^2:

−nv+SSE=0⟹v^=SSEn.-nv+\mathrm{SSE}=0 \quad\Longrightarrow\quad \hat v=\frac{\mathrm{SSE}}{n}.

where:

  • nn: the number of observations
  • vv: the candidate variance
  • SSE\mathrm{SSE}: the sum of squared deviations from the sample mean
  • v^\hat v: the maximum likelihood variance estimate

If SSE>0\mathrm{SSE}>0, the profile likelihood rises for v<SSE/nv<\mathrm{SSE}/n and falls for v>SSE/nv>\mathrm{SSE}/n, so this is the global maximum over v>0v>0. If all observations are identical, SSE=0\mathrm{SSE}=0 and the Gaussian likelihood is unbounded as vv tends to zero: no positive-variance MLE is attained. For nondegenerate i.i.d. Gaussian samples, the variance estimator is biased downward because

E[SSEn]=n−1nσ2.\mathbb{E}\left[\frac{\mathrm{SSE}}{n}\right] =\frac{n-1}{n}\sigma^2.

where:

  • E[⋅]\mathbb{E}[\cdot]: expectation over repeated samples
  • SSE\mathrm{SSE}: the sum of squared deviations from the sample mean
  • nn: the number of observations
  • σ2\sigma^2: the true variance

The bias shrinks as nn grows, and the estimator is consistent, but it is not unbiased. This is a concrete reminder that maximum likelihood and unbiasedness are different properties.

The Gaussian likelihood also explains why squared error appears so often in regression. If we model y=Xβ+εy=X\beta+\varepsilon with ε∼N(0,σ2I)\varepsilon\sim N(0,\sigma^2 I), the log-likelihood is

ℓ(β,σ2)=−n2log⁡(2πσ2)−12σ2(y−Xβ)⊤(y−Xβ).\ell(\beta,\sigma^2) = -\frac{n}{2}\log(2\pi\sigma^2) -\frac{1}{2\sigma^2}(y-X\beta)^\top(y-X\beta).

Here yy is a column vector of responses, XX is a matrix with one row per observation and one column per predictor, β\beta is a column vector of coefficients, and II is the identity matrix. The expression (y−Xβ)⊤(y−Xβ)(y-X\beta)^\top(y-X\beta) is exactly the sum of squared errors written in matrix notation. For a fixed σ2\sigma^2, maximizing the likelihood over β\beta is the same as minimizing the sum of squared errors. We will see the full regression derivation in the later chapters on ordinary least squares, but the likelihood connection is already visible here.

Four normal densities

The mean controls the center of the distribution, and the standard deviation controls its width. When you evaluate a likelihood, you are not plotting a distribution over μ\mu or σ\sigma. You are comparing candidate distributions over the observed data yy.

PythonIn [3]
CollapseExpand
import matplotlib.pyplot as plt
from book_plot_style import PALETTE, polish_axes, theme_color, use_book_style

use_book_style()
fig, ax = plt.subplots(figsize=(6.0, 4.0))


plot_colors = [
    PALETTE["primary"],
    PALETTE["amber"],
    PALETTE["teal"],
    PALETTE["muted"],
]
for (mu, sigma, label), density, color in zip(
    normal_variants, normal_densities, plot_colors
):
    ax.plot(x_grid, density, color=color, label=label)
ax.set_xlabel("Observation y")
ax.set_ylabel("Density f(y)")
ax.set_title("Candidate normal distributions")
ax.legend()
polish_axes(ax)
plt.show()
VisualizationOut [3]
CollapseExpand
Four bell-shaped curves with different centers and widths on an axis of observation values.
Four candidate normal densities over observation values, each with a different mean and standard deviation. Centers shift with the mean and widths grow with the standard deviation, and all four are distributions over y rather than likelihood curves over the parameters.

Score, curvature, and numerical estimation

The score equation s(θ^)=0s(\hat\theta)=0 is the first-order condition for a maximum. To confirm a maximum and to measure uncertainty, we use the second derivative. Intuitively, the first derivative tells us where the likelihood is flat, while the second derivative tells us how quickly it curves away from that flat point. A sharp peak is informative. A broad, nearly flat peak is not. The observed information is

J(θ^)=−d2ℓ(θ)dθ2∣θ=θ^.J(\hat\theta)=-\left.\frac{d^2\ell(\theta)}{d\theta^2}\right|_{\theta=\hat\theta}.

where:

  • J(θ^)J(\hat\theta): the observed information, evaluated at the estimate θ^\hat\theta
  • θ^\hat\theta: the maximum likelihood estimate of the parameter
  • d2ℓ(θ)/dθ2d^2\ell(\theta)/d\theta^2: the second derivative of the log-likelihood with respect to θ\theta
  • the vertical bar with subscript θ=θ^\theta=\hat\theta: evaluation of the second derivative at the estimate

For a vector parameter, the second derivative becomes a Hessian matrix, and the observed information is the negative Hessian:

J(θ^)=−∇2ℓ(θ^).J(\hat\theta)=-\nabla^2\ell(\hat\theta).

The Fisher information is the expected value of the observed information under the model:

In(θ)=Eθ[J(θ)]=Eθ[−∇2ℓ(θ)],I_n(\theta) = \mathbb{E}_{\theta}\left[J(\theta)\right] = \mathbb{E}_{\theta}\left[-\nabla^2\ell(\theta)\right],

where:

  • In(θ)I_n(\theta): the Fisher information in the full sample for the parameter θ\theta
  • Eθ[⋅]\mathbb{E}_{\theta}[\cdot]: the expectation taken over repeated samples generated with the true parameter equal to θ\theta
  • ∇2ℓ(θ)\nabla^2\ell(\theta): the Hessian of the log-likelihood (the matrix of second partial derivatives)

For a correctly specified regular i.i.d. model, In(θ)=nI1(θ)I_n(\theta)=nI_1(\theta), where I1I_1 is per-observation information. Under the usual consistency and derivative-convergence conditions, J(θ^)/nJ(\hat\theta)/n and In(θ^)/nI_n(\hat\theta)/n converge to the same nonsingular limit. This statement concerns information per observation; their unnormalized difference need not tend to zero.

At a regular interior estimate with positive information, a large-sample standard error for a scalar parameter is

se^(θ^)≈J(θ^)−1=1−ℓ′′(θ^).\widehat{\mathrm{se}}(\hat\theta) \approx \sqrt{J(\hat\theta)^{-1}} = \sqrt{\frac{1}{-\ell''(\hat\theta)}}.

where:

  • se^(θ^)\widehat{\mathrm{se}}(\hat\theta): the approximate standard error of the estimate
  • J(θ^)−1J(\hat\theta)^{-1}: the reciprocal of the observed information (the inverse information matrix in the vector case)
  • ℓ′′(θ^)\ell''(\hat\theta): the second derivative of the log-likelihood evaluated at the estimate

For a regular interior vector estimate with nonsingular positive-definite observed information, its inverse approximates the covariance matrix:

Cov^(θ^)≈[−∇2ℓ(θ^)]−1.\widehat{\mathrm{Cov}}(\hat\theta) \approx \left[-\nabla^2\ell(\hat\theta)\right]^{-1}.

The diagonal entries give approximate variances, and their square roots give approximate standard errors. This is where the shape of the likelihood becomes uncertainty: a sharply curved peak has large information and small standard error, while a flat peak has small information and large standard error.

The quadratic approximation below shows why curvature is used as a local summary of information. Near the peak, the log-likelihood and its second-order approximation almost coincide; farther away, the approximation drifts from the exact curve.

PythonIn [4]
CollapseExpand
bernoulli_p_hat_quad = 12 / 20
bernoulli_info_quad = 20 / (bernoulli_p_hat_quad * (1 - bernoulli_p_hat_quad))
bernoulli_p_grid_quad = np.linspace(0.35, 0.85, 500)
bernoulli_loglik_quad = 12 * np.log(bernoulli_p_grid_quad) + 8 * np.log(
    1 - bernoulli_p_grid_quad
)
bernoulli_loglik_quad_relative = bernoulli_loglik_quad - (
    12 * np.log(bernoulli_p_hat_quad) + 8 * np.log1p(-bernoulli_p_hat_quad)
)
bernoulli_quadratic_approx = (
    -0.5
    * bernoulli_info_quad
    * (bernoulli_p_grid_quad - bernoulli_p_hat_quad) ** 2
)
VisualizationOut [5]
CollapseExpand
Bernoulli log-likelihood and its quadratic approximation around the MLE.
Bernoulli log-likelihood and its quadratic approximation around the maximum likelihood estimate. The approximation matches the curve near the peak and summarizes local curvature through the observed information, while diverging in the tails where the second-order expansion no longer holds.

For the Bernoulli model with 0<k<n0<k<n, the observed information at p^=k/n\hat p=k/n is

J(p^)=np^(1−p^),J(\hat p)=\frac{n}{\hat p(1-\hat p)},

where:

  • J(p^)J(\hat p): the observed information for the Bernoulli probability
  • nn: the number of trials
  • p^\hat p: the estimated success probability
  • 1−p^1-\hat p: the estimated failure probability

so the approximate standard error is

se^(p^)=p^(1−p^)n.\widehat{\mathrm{se}}(\hat p) = \sqrt{\frac{\hat p(1-\hat p)}{n}}.

where:

  • se^(p^)\widehat{\mathrm{se}}(\hat p): the approximate standard error of the Bernoulli estimate
  • p^\hat p: the estimated success probability
  • 1−p^1-\hat p: the estimated failure probability
  • nn: the number of trials

This is the familiar standard error of a sample proportion. For the Gaussian mean with known variance, the observed information is n/σ2n/\sigma^2, so the standard error is σ/n\sigma/\sqrt{n}. For the Gaussian variance, the observed information at v^=SSE/n\hat v=\mathrm{SSE}/n is n/(2v^2)n/(2\hat v^2). The approximate standard error is therefore v^2/n\hat v\sqrt{2/n}, where v^=σ^2\hat v=\hat\sigma^2 is the variance estimate.

When no closed-form solution exists, you can maximize the log-likelihood numerically. A simple one-dimensional approach is a grid search: evaluate the log-likelihood on a fine grid of parameter values and choose the grid point with the largest value. Grid search is easy to reason about but becomes impractical in more than a few dimensions.

A more scalable approach is Newton-Raphson. It comes from a second-order Taylor expansion of the objective around the current iterate, and it approximately solves the score equation ∇ℓ(θ)=0\nabla\ell(\theta)=0 at each step. To maximize ℓ(θ)\ell(\theta), you update

θt+1=θt−[∇2ℓ(θt)]−1∇ℓ(θt).\theta_{t+1} = \theta_t - \left[\nabla^2\ell(\theta_t)\right]^{-1} \nabla\ell(\theta_t).

where:

  • θt\theta_t: the parameter value at iteration tt
  • θt+1\theta_{t+1}: the updated parameter value
  • ∇ℓ(θt)\nabla\ell(\theta_t): the gradient (score) of the log-likelihood at θt\theta_t
  • ∇2ℓ(θt)\nabla^2\ell(\theta_t): the Hessian matrix of second derivatives at θt\theta_t
  • [⋅]−1[\cdot]^{-1}: the matrix inverse

The gradient points in the direction of increase, and the inverse Hessian rescales that direction. The update is equivalent to solving ∇2ℓ(θt)(θt+1−θt)=−∇ℓ(θt)\nabla^2\ell(\theta_t)(\theta_{t+1}-\theta_t) = -\nabla\ell(\theta_t), which makes the score approximately zero after the step. When the Hessian is negative definite and the score is nonzero, the Newton direction is an ascent direction, but the full step can overshoot and decrease the likelihood. A line search can shorten the step. If the starting value is poor or the Hessian is not negative definite, Newton-Raphson can diverge. Practical implementations often minimize the negative log-likelihood with quasi-Newton methods, add bounds, or reparameterize positive quantities using logarithms. For example, instead of optimizing σ2\sigma^2 directly, you can optimize log⁡σ\log\sigma and exponentiate the result. This keeps the standard deviation positive.

Identifiability, sampling uncertainty, and limitations

A model is identifiable if different parameter values produce different distributions for the data. Formally, if

Pθ1(A)=Pθ2(A)for every measurable event AP_{\theta_1}(A)=P_{\theta_2}(A) \quad\text{for every measurable event }A

implies θ1=θ2\theta_1=\theta_2, then the parameter is identifiable. Here Pθ(A)P_\theta(A) is the model probability of an event AA. If distinct parameters give the same distribution, no amount of data from that model can distinguish those equivalent values. A continuous equivalence can create a flat ridge, while a discrete label symmetry can create separate equivalent peaks. A mixture model with unlabeled components is a classic example: swapping the labels of two components gives the same likelihood. In linear regression, perfectly collinear predictor columns make X⊤XX^\top X singular, so different coefficient vectors can produce the same fitted values. We discussed the practical consequences of that in Multicollinearity.

Identifiability is a property of the model and the data design, not a property of the optimizer. A numerical optimizer may return a point on a flat ridge, but the data do not distinguish that point from the other equivalent points. Before trusting an estimate, ask whether the data contain enough variation to distinguish the parameters. If not, we need to simplify the model, collect more informative data, or impose a constraint.

Sampling uncertainty is different from identifiability. Even in an identifiable model, the maximum likelihood estimate is a random variable because it depends on a random sample. For a correctly specified identifiable model with an interior true parameter, sufficient smoothness, nonsingular Fisher information, a consistent maximizing solution, and the derivative-convergence conditions used in the asymptotic argument, we obtain:

n(θ^−θ0)→dN(0,I1(θ0)−1),\sqrt{n}\left(\hat\theta-\theta_0\right) \xrightarrow{d} N\left(0,I_1(\theta_0)^{-1}\right),

where:

  • n\sqrt{n}: the square root of sample size, which scales the centered estimation error to a nondegenerate limit under the stated regularity conditions
  • θ^\hat\theta: the maximum likelihood estimate
  • θ0\theta_0: the true parameter value
  • →d\xrightarrow{d}: convergence in distribution as n→∞n\to\infty
  • N(0,I1(θ0)−1)N(0,I_1(\theta_0)^{-1}): the limiting normal distribution with mean zero and covariance I1(θ0)−1I_1(\theta_0)^{-1}
  • I1(θ0)I_1(\theta_0): the per-observation Fisher information evaluated at the true parameter θ0\theta_0

This is the basis for the curvature-based standard errors above. The approximation can be poor in small samples, near boundaries, or when the model is misspecified. Alternatives include profile likelihood, a bootstrap appropriate to the sampling design, and Bayesian inference with an explicit prior. Each requires its own assumptions and coverage or sensitivity checks; none automatically repairs a boundary or a misspecified model.

Maximum likelihood also has failure modes that are worth recognizing. The likelihood can be unbounded, as in a Gaussian mixture when a component variance collapses to zero around a single point. In logistic regression, complete separation can push coefficients toward infinity because the likelihood keeps increasing as the separating boundary becomes sharper. Non-concave likelihoods can have multiple local maxima, so different starting values may produce different answers. And if the model is wrong, the estimate may be precise but precisely wrong.

Mathematical Properties

Maximum likelihood has several properties that make it useful beyond the basic examples. The first is invariance under reparameterization. If θ^\hat\theta is the maximum likelihood estimate of θ\theta, and gg is a one-to-one function, then g(θ^)g(\hat\theta) is the maximum likelihood estimate of g(θ)g(\theta). For example, if 0<p^<10<\hat p<1, then p^/(1−p^)\hat p/(1-\hat p) is the finite maximum likelihood estimate of the odds. This property is convenient, but it does not mean that standard errors transform by simply plugging in the transformed estimate. Uncertainty usually requires the delta method or a profile-likelihood calculation.

The second property is additivity for independent observations. The log-likelihood is a sum of per-observation log-density or log-mass contributions, so each new independent observation adds one term. This makes the likelihood scalable and explains why the curvature typically grows with sample size. In regular models, information adds across independent observations. For a correctly specified regular i.i.d. model with fixed, finite, positive definite per-observation information, total information is proportional to nn, and the usual large-sample standard errors shrink at rate 1/n1/\sqrt{n}.

Under regularity conditions, maximum likelihood estimators are consistent and asymptotically efficient. Consistency means the estimate converges to the true parameter as the sample size grows. Asymptotic efficiency means attaining the inverse-Fisher-information bound within the regular estimator class. It does not compare every possible consistent estimator at every parameter value. These are large-sample guarantees. They do not imply that the estimate is unbiased in a small sample, that the model is correct, or that the likelihood is well behaved in every finite dataset.

Finally, maximum likelihood is not the same as least squares in general. For independent Gaussian errors and any fixed common positive variance, maximizing over the mean parameters is equivalent to minimizing squared error. Bernoulli, Poisson, and other non-Gaussian likelihoods generally give different objectives, although their maximizing estimates can sometimes coincide with least-squares estimates. This is why the likelihood framework is more general than squared error, and why the choice of likelihood encodes assumptions about the data-generating process.

Visualizing Maximum Likelihood

A likelihood curve shows how the plausibility of the observed data changes as we move the parameter. The peak is the maximum likelihood estimate. The width of the curve tells you how much information the data provide about the parameter. To compare curves with different sample sizes, we often shift each log-likelihood so that its maximum is zero. This removes an arbitrary additive constant and makes the shapes easier to compare.

For Bernoulli samples with the same interior observed proportion, the log-likelihood is concave and becomes narrower as sample size grows. The peak stays at the sample proportion, but the data become more informative, so small departures from the peak cost more log-likelihood. That is the visual counterpart of the standard error formula p^(1−p^)/n\sqrt{\hat p(1-\hat p)/n}.

ConsoleOut [7]
CollapseExpand
n = 5, k = 3, MLE p = 0.600
n = 20, k = 12, MLE p = 0.600
n = 100, k = 60, MLE p = 0.600
PythonIn [8]
CollapseExpand
from book_plot_style import PALETTE, polish_axes, use_book_style

use_book_style()
fig, ax = plt.subplots(figsize=(6.0, 4.0))
plot_colors = [PALETTE["primary"], PALETTE["amber"], PALETTE["teal"]]
for (k, n, label), ll, color in zip(
    bernoulli_scenarios, bernoulli_curve_values, plot_colors
):
    ax.plot(p_grid_viz, ll, color=color, label=label)
ax.axvline(0.6, color=PALETTE["muted"], linestyle="--", linewidth=1.0)
ax.set_xlabel("Probability p")
ax.set_ylabel("Log-likelihood relative to maximum")
ax.set_title("More data sharpens the Bernoulli likelihood")
ax.legend()
polish_axes(ax)
plt.show()
VisualizationOut [8]
CollapseExpand
Three concave curves over the probability axis, all peaking at 0.6 and becoming narrower as the sample size increases from 5 to 20 to 100.
Bernoulli log-likelihoods for three sample sizes, shifted so each maximum is zero. The curves peak at the same observed proportion of 0.6 but become narrower as the sample size grows from 5 to 20 to 100, reflecting more information about the parameter.

The three curves use the same observed proportion, k/n=0.6k/n=0.6, but different sample sizes. The n=5n=5 curve is broad, and many values of pp are nearly as plausible as the peak. The n=100n=100 curve is much narrower, and the data are far more discriminating. This does not mean the estimate is necessarily correct. A narrow likelihood can still be centered on a biased value if the model is wrong. It does mean that, under the assumed model, the parameter is more precisely determined.

For the Gaussian mean, the log-likelihood as a function of μ\mu is also concave when the variance is fixed. The peak is the sample mean, and the curvature is controlled by the variance and sample size. A larger variance or a smaller sample produces a flatter curve and a larger standard error.

The figure below shows the Gaussian log-likelihood for the mean with the variance held fixed at its maximum likelihood estimate. The concave curve peaks at the sample mean, and its width reflects the information the data provide about μ\mu.

The readings from the sensor example, the fixed data used throughout this section, are stored once here so that the likelihood curves below can reuse them.

PythonIn [9]
CollapseExpand
import numpy as np

y = np.array([9.8, 10.3, 9.9, 10.2, 9.8])
gaussian_sigma2_viz = np.mean((y - y.mean()) ** 2)
mu_grid_viz = np.linspace(9.6, 10.4, 400)
gaussian_ll_mu = -len(y) / 2 * np.log(2 * np.pi * gaussian_sigma2_viz) - np.sum(
    (y[None, :] - mu_grid_viz[:, None]) ** 2, axis=1
) / (2 * gaussian_sigma2_viz)
gaussian_mu_hat_viz = y.mean()
gaussian_peak_loglik = -len(y) / 2 * np.log(
    2 * np.pi * gaussian_sigma2_viz
) - np.sum((y - gaussian_mu_hat_viz) ** 2) / (2 * gaussian_sigma2_viz)
gaussian_ll_mu_relative = gaussian_ll_mu - gaussian_peak_loglik
PythonIn [10]
CollapseExpand
from book_plot_style import PALETTE, polish_axes, use_book_style

use_book_style()
fig, ax = plt.subplots(figsize=(6.0, 4.0))
ax.plot(
    mu_grid_viz,
    gaussian_ll_mu_relative,
    color=PALETTE["primary"],
)
ax.axvline(
    gaussian_mu_hat_viz, color=PALETTE["amber"], linestyle="--", linewidth=1.0
)
ax.set_xlabel("Mean mu")
ax.set_ylabel("Log-likelihood relative to maximum")
ax.set_title("The Gaussian mean likelihood peaks at the sample mean")
polish_axes(ax)
plt.show()
VisualizationOut [10]
CollapseExpand
A concave curve over possible mean values, peaking at the sample mean of 10.0.
Gaussian log-likelihood for the mean, with the variance fixed at its maximum likelihood estimate. The concave curve peaks at the sample mean of 10.0, and its width reflects how much information the five readings provide about the mean.

The plotted Gaussian log-likelihood is a downward parabola in μ\mu, because the variance is held fixed. Its horizontal peak is the estimate and its curvature controls the local precision. Exponentiating the unshifted log-likelihood would give a bell-shaped likelihood, but neither plot by itself assigns posterior probabilities to μ\mu. Bayesian parameter probabilities also require a prior and normalization.

Example

We now work through the likelihood calculations for two small examples. The first example is a Bernoulli problem with a count. The second is a Gaussian problem with five observations. In both cases, the same pattern appears. Build the likelihood, take its logarithm, differentiate, solve the score equation, then inspect curvature.

Bernoulli: twelve clicks in twenty visits

Suppose twenty visitors arrive, and twelve click. We model each visit as an independent Bernoulli trial with unknown click probability pp. The observed count is k=12k=12 and the number of trials is n=20n=20. The likelihood is

L(p)=p12(1−p)8.L(p)=p^{12}(1-p)^{8}.

where:

  • L(p)L(p): the likelihood of the click probability pp given the observed counts
  • pp: the unknown click probability
  • the exponents 1212 and 88: the numbers of clicks and non-clicks, so the terms carry the success and failure counts

The log-likelihood is

ℓ(p)=12log⁡p+8log⁡(1−p).\ell(p)=12\log p+8\log(1-p).

The score is

ℓ′(p)=12p−81−p.\ell'(p)=\frac{12}{p}-\frac{8}{1-p}.

Setting the score to zero gives

12p=81−p.\frac{12}{p}=\frac{8}{1-p}.

Cross-multiplying gives 12(1−p)=8p12(1-p)=8p, so 12−12p=8p12-12p=8p, and therefore 12=20p12=20p. Hence

p^=1220=0.6.\hat p=\frac{12}{20}=0.6.

The second derivative is

ℓ′′(p)=−12p2−8(1−p)2.\ell''(p)=-\frac{12}{p^2}-\frac{8}{(1-p)^2}.

At p^=0.6\hat p=0.6, this is

ℓ′′(0.6)=−120.62−8(1−0.6)2(substitute p^=0.6)=−120.36−80.16(square the denominators)=−33.3‾−50(divide each term)=−83.3‾(add).\begin{aligned} \ell''(0.6) &= -\frac{12}{0.6^2} - \frac{8}{(1-0.6)^2} && \text{(substitute } \hat p = 0.6 \text{)} \\ &= -\frac{12}{0.36} - \frac{8}{0.16} && \text{(square the denominators)} \\ &= -33.\overline{3} - 50 && \text{(divide each term)} \\ &= -83.\overline{3} && \text{(add)}. \end{aligned}

where:

  • ℓ′′(0.6)\ell''(0.6): the second derivative of the Bernoulli log-likelihood evaluated at p^=0.6\hat p = 0.6
  • 120.62\frac{12}{0.6^2}: the magnitude of the negative second-derivative contribution from the 12 successes
  • 8(1−0.6)2\frac{8}{(1-0.6)^2}: the magnitude of the negative second-derivative contribution from the 8 failures

The observed information is therefore J(0.6)=83.3‾J(0.6) = 83.\overline{3}, so the approximate standard error is

se^(p^)=183.333≈0.1095.\widehat{\mathrm{se}}(\hat p) =\sqrt{\frac{1}{83.333}} \approx 0.1095.

where:

  • se^(p^)\widehat{\mathrm{se}}(\hat p): the approximate standard error of the Bernoulli estimate
  • 83.33383.333: the observed information J(0.6)J(0.6) rounded

This matches the formula p^(1−p^)/n=0.6⋅0.4/20=0.012≈0.1095\sqrt{\hat p(1-\hat p)/n}=\sqrt{0.6\cdot0.4/20}=\sqrt{0.012}\approx0.1095.

We can compare the log-likelihood at a few candidate values. At p=0.5p=0.5,

ℓ(0.5)=12log⁡(0.5)+8log⁡(0.5)(substitute p=0.5)=20log⁡(0.5)(combine like terms)≈−13.863(evaluate).\begin{aligned} \ell(0.5) &= 12\log(0.5) + 8\log(0.5) && \text{(substitute } p = 0.5 \text{)} \\ &= 20\log(0.5) && \text{(combine like terms)} \\ &\approx -13.863 && \text{(evaluate)}. \end{aligned}

At p=0.6p=0.6,

ℓ(0.6)=12log⁡(0.6)+8log⁡(0.4)(substitute p=0.6)≈−13.460(evaluate).\begin{aligned} \ell(0.6) &= 12\log(0.6) + 8\log(0.4) && \text{(substitute } p = 0.6 \text{)} \\ &\approx -13.460 && \text{(evaluate)}. \end{aligned}

At p=0.7p=0.7,

ℓ(0.7)=12log⁡(0.7)+8log⁡(0.3)(substitute p=0.7)≈−13.912(evaluate).\begin{aligned} \ell(0.7) &= 12\log(0.7) + 8\log(0.3) && \text{(substitute } p = 0.7 \text{)} \\ &\approx -13.912 && \text{(evaluate)}. \end{aligned}

The largest value is at p=0.6p=0.6, as expected. The differences in log-likelihood are modest, which is another way of seeing that p=0.5p=0.5 is not absurdly implausible with only twenty observations. A rough 95% Wald interval is 0.6±1.96(0.1095)0.6\pm1.96(0.1095), or approximately (0.385,0.815)(0.385,0.815). The interval is symmetric around 0.60.6 and can be unreliable near the boundaries, but it gives a useful first summary of uncertainty.

Gaussian: five sensor readings

Suppose five readings from a sensor are

y=(9.8, 10.3, 9.9, 10.2, 9.8).y=(9.8,\ 10.3,\ 9.9,\ 10.2,\ 9.8).

We model them as independent draws from N(μ,σ2)N(\mu,\sigma^2). The sample mean is

μ^=yˉ=9.8+10.3+9.9+10.2+9.85=10.0.\hat\mu=\bar y=\frac{9.8+10.3+9.9+10.2+9.8}{5}=10.0.

where:

  • μ^\hat\mu: the maximum likelihood estimate of the mean
  • yˉ\bar y: the sample mean
  • the numerator: the sum of the five observed readings
  • the denominator 55: the number of observations nn

The deviations from the mean are −0.2,0.3,−0.1,0.2,−0.2-0.2,0.3,-0.1,0.2,-0.2. Squaring and summing gives

SSE=(y1−yˉ)2+(y2−yˉ)2+(y3−yˉ)2+(y4−yˉ)2+(y5−yˉ)2(definition)=(−0.2)2+(0.3)2+(−0.1)2+(0.2)2+(−0.2)2(substitute deviations)=0.04+0.09+0.01+0.04+0.04(square each term)=0.22.(sum)\begin{aligned} \mathrm{SSE} &= (y_1-\bar y)^2 + (y_2-\bar y)^2 + (y_3-\bar y)^2 + (y_4-\bar y)^2 + (y_5-\bar y)^2 && \text{(definition)} \\ &= (-0.2)^2 + (0.3)^2 + (-0.1)^2 + (0.2)^2 + (-0.2)^2 && \text{(substitute deviations)} \\ &= 0.04 + 0.09 + 0.01 + 0.04 + 0.04 && \text{(square each term)} \\ &= 0.22. && \text{(sum)} \end{aligned}

where:

  • SSE\mathrm{SSE}: the sum of squared deviations of the readings from the sample mean
  • each squared term: one observation's deviation from the mean, squared

The maximum likelihood variance is therefore

σ^2=SSEn=0.225=0.044.\hat\sigma^2=\frac{\mathrm{SSE}}{n}=\frac{0.22}{5}=0.044.

The maximum likelihood standard deviation is

σ^=0.044≈0.2098.\hat\sigma=\sqrt{0.044}\approx0.2098.

where:

  • σ^\hat\sigma: the maximum likelihood standard deviation
  • 0.0440.044: the maximum likelihood variance estimate

For comparison, the unbiased sample variance divides by n−1=4n-1=4:

s2=SSEn−1=0.224=0.055,s=s2=0.055≈0.2345.\begin{aligned} s^2 &= \frac{\mathrm{SSE}}{n-1} = \frac{0.22}{4} = 0.055, \\ s &= \sqrt{s^2} = \sqrt{0.055} \approx 0.2345. \end{aligned}

where:

  • s2s^2: the unbiased sample variance, which divides by n−1n-1 rather than nn
  • ss: the square root of the unbiased sample variance; ss itself is generally biased for σ\sigma
  • n−1=4n-1 = 4: the degrees of freedom, one less than the number of observations

The maximum likelihood variance is smaller because it divides by nn. On average, it underestimates the true variance by a factor of (n−1)/n=4/5(n-1)/n=4/5. With only five observations, the bias is not negligible.

The bias is easiest to see as a ratio. The maximum likelihood variance has expected value (n−1)σ2/n(n-1)\sigma^2/n, while the unbiased sample variance has expected value σ2\sigma^2. The gap closes as nn increases.

PythonIn [11]
CollapseExpand
variance_bias_n = np.arange(2, 51)
variance_bias_mle_ratio = (variance_bias_n - 1) / variance_bias_n
variance_bias_unbiased_ratio = np.ones_like(variance_bias_n)
VisualizationOut [12]
CollapseExpand
Expected MLE variance divided by true variance rises toward one as sample size grows.
Expected maximum likelihood variance divided by the true variance for sample sizes from 2 to 50, compared with the unbiased sample variance ratio. The maximum likelihood ratio (n-1)/n approaches one as n grows, but the downward bias is substantial in small samples.

The score for μ\mu at the estimate is

∂ℓ∂μ∣μ=10=1σ^2∑i=1n(yi−10)(score formula at μ=10)=10.044(−0.2+0.3−0.1+0.2−0.2)(substitute deviations)=10.044(0)(sum the deviations)=0(simplify).\begin{aligned} \left.\frac{\partial\ell}{\partial\mu}\right|_{\mu=10} &= \frac{1}{\hat\sigma^2}\sum_{i=1}^{n}(y_i-10) && \text{(score formula at } \mu=10\text{)} \\ &= \frac{1}{0.044}\left(-0.2+0.3-0.1+0.2-0.2\right) && \text{(substitute deviations)} \\ &= \frac{1}{0.044}(0) && \text{(sum the deviations)} \\ &= 0 && \text{(simplify)}. \end{aligned}

where:

  • ∂ℓ∂μ∣μ=10\left.\frac{\partial\ell}{\partial\mu}\right|_{\mu=10}: the score evaluated at μ=10\mu = 10
  • σ^2\hat\sigma^2: the maximum likelihood variance estimate, 0.0440.044
  • yi−10y_i-10: each observation's deviation from the candidate mean

The score is zero at μ^=yˉ=10\hat\mu = \bar y = 10, which is exactly the first-order condition for the maximum.

The approximate standard error of the mean, using σ^2\hat\sigma^2 as the variance, is

se^(μ^)=σ^2n(information n/σ^2)=0.0445(substitute values)≈0.0088(divide)≈0.0938.(square root)\begin{aligned} \widehat{\mathrm{se}}(\hat\mu) &= \sqrt{\frac{\hat\sigma^2}{n}} && \text{(information } n/\hat\sigma^2 \text{)} \\ &= \sqrt{\frac{0.044}{5}} && \text{(substitute values)} \\ &\approx \sqrt{0.0088} && \text{(divide)} \\ &\approx 0.0938. && \text{(square root)} \end{aligned}

where:

  • se^(μ^)\widehat{\mathrm{se}}(\hat\mu): the approximate standard error of the estimated mean
  • σ^2\hat\sigma^2: the maximum likelihood variance estimate
  • nn: the number of observations

A rough 95% interval using the normal approximation is 10.0±1.96(0.0938)10.0\pm1.96(0.0938), or approximately (9.816,10.184)(9.816,10.184). With only five observations, a tt interval based on four degrees of freedom would be wider, which is a reminder that the curvature approximation is asymptotic. The likelihood still gives us the point estimate and a sense of precision, but the finite-sample interval should be chosen with care.

Implementation in NumPy and SciPy

You will now implement the same calculations from primitives. First you compute the closed-form estimates directly. Then you compute a likelihood grid and run numerical optimization with SciPy. Finally, we compute curvature-based standard errors. The data are small and deterministic so that every printed value can be checked by hand.

The next cell imports SciPy's optimizer. The earlier hidden setup already imported NumPy, Matplotlib and the normal distribution and seeded the shared plot environment.

PythonIn [13]
CollapseExpand
from scipy.optimize import minimize

You start with the closed-form estimates for the Bernoulli probability and the Gaussian mean and variance. These are the same formulas derived in the previous sections, now written as direct computations.

PythonIn [14]
CollapseExpand
clicks = 12
visitors = 20
p_hat_closed = clicks / visitors

mu_hat_closed = y.mean()
sigma2_hat_closed = np.mean((y - mu_hat_closed) ** 2)
sigma_hat_closed = np.sqrt(sigma2_hat_closed)
sigma2_unbiased = np.var(y, ddof=1)
ConsoleOut [15]
CollapseExpand
Bernoulli closed-form MLE: p_hat = 0.6000
Gaussian closed-form MLE: mu_hat = 10.0000
Gaussian closed-form MLE: sigma2_hat = 0.0440 (sigma_hat = 0.2098)
Unbiased sample variance for comparison: 0.0550

Next we evaluate the Bernoulli log-likelihood on a grid and run a bounded numerical optimizer. For the Gaussian model, we optimize μ\mu and log⁡σ\log\sigma so that the standard deviation remains positive. Using log⁡σ\log\sigma is a common practical trick. It turns a constrained optimization problem into an unconstrained one.

In the Gaussian optimizer below, the starting value for μ\mu is set to the analytic sample mean mu_hat_closed.

PythonIn [16]
CollapseExpand
p_grid = np.linspace(0.001, 0.999, 999)
bernoulli_ll_grid = clicks * np.log(p_grid) + (visitors - clicks) * np.log(
    1 - p_grid
)
p_hat_grid = p_grid[np.argmax(bernoulli_ll_grid)]


def bernoulli_neg_loglik(theta):
    p = theta[0]
    return -(clicks * np.log(p) + (visitors - clicks) * np.log(1 - p))


bernoulli_fit = minimize(
    bernoulli_neg_loglik,
    x0=np.array([0.5]),
    method="L-BFGS-B",
    bounds=[(1e-9, 1 - 1e-9)],
)
p_hat_numeric = bernoulli_fit.x[0]


def gaussian_neg_loglik(theta):
    mu, log_sigma = theta
    sigma = np.exp(log_sigma)
    return len(y) * (0.5 * np.log(2 * np.pi) + log_sigma) + np.sum(
        (y - mu) ** 2
    ) / (2 * sigma**2)


gaussian_fit = minimize(
    gaussian_neg_loglik,
    x0=np.array([mu_hat_closed, 0.0]),
    method="L-BFGS-B",
)
mu_hat_numeric, log_sigma_hat = gaussian_fit.x
sigma_hat_numeric = np.exp(log_sigma_hat)
sigma2_hat_numeric = sigma_hat_numeric**2

# Independent distribution fit and density implementation.
mu_reference, sigma_reference = norm.fit(y)
assert bernoulli_fit.success and gaussian_fit.success
assert np.isclose(p_hat_numeric, p_hat_closed, atol=1e-6, rtol=0)
assert np.allclose(
    [mu_hat_numeric, sigma_hat_numeric],
    [mu_reference, sigma_reference],
    atol=1e-5,
    rtol=0,
)
assert np.isclose(
    gaussian_neg_loglik(gaussian_fit.x),
    -norm.logpdf(y, loc=mu_hat_numeric, scale=sigma_hat_numeric).sum(),
)
ConsoleOut [17]
CollapseExpand
Bernoulli grid best p: 0.6000
Bernoulli numerical MLE: 0.6000
Gaussian numerical MLE: mu_hat = 10.0000, sigma2_hat = 0.0440
Optimizer success flags: Bernoulli=True, Gaussian=True
SciPy normal fit: mean=10.0000, variance=0.0440

The grid has spacing 0.001 and includes 0.6, so its answer matches p_hat_closed to four decimal places. The numerical optimizer should match the closed-form answer to several decimal places. If the optimizer reports failure, the estimate is not necessarily wrong, but it is a signal to inspect the starting value, scaling, and bounds.

Both routes recover the sample proportion and, for the Gaussian model, the optimizer recovers the sample mean and the maximum likelihood variance reported in the closed-form output above. Agreement among the grid search, the closed-form calculation, and the optimizer suggests the estimate is not an artifact of one particular numerical approach. When the routines disagree, the discrepancy usually points to grid resolution, an optimizer that stopped early, or a likelihood that is flat near its peak.

Finally, you compute approximate standard errors from the curvature formulas.

PythonIn [18]
CollapseExpand
# Curvature-based standard errors from observed information
p_information = visitors / (p_hat_closed * (1 - p_hat_closed))
mu_information = len(y) / sigma2_hat_closed
sigma2_information = len(y) / (2 * sigma2_hat_closed**2)

Each information value summarizes how sharply the log-likelihood peaks at the estimate. Larger information implies a narrower peak and a smaller approximate standard error. The standard errors below are the square roots of the reciprocals of these information values. For the Bernoulli probability, the information is n/[p^(1−p^)]n/[\hat p(1-\hat p)]. For the Gaussian mean, the information is n/σ^2n/\hat\sigma^2. For the Gaussian variance, the asymptotic standard error is σ^22/n\hat\sigma^2\sqrt{2/n}, which follows from the observed information n/(2σ^4)n/(2\hat\sigma^4) and the square root of its reciprocal. The two are related by se(σ^2)≈σ^22/n=2σ^4/n\mathrm{se}(\hat\sigma^2) \approx \hat\sigma^2\sqrt{2/n} = \sqrt{2\hat\sigma^4/n}, and that approximate value is computed from the observed information in the code below rather than hardcoded. Explicitly,

2σ^4n=σ^42n=σ^22n.\sqrt{\frac{2\hat\sigma^4}{n}} = \sqrt{\hat\sigma^4}\sqrt{\frac{2}{n}} = \hat\sigma^2\sqrt{\frac{2}{n}}.

where:

  • σ^2\hat\sigma^2: the maximum likelihood variance estimate
  • nn: the number of observations
  • n2σ^4\frac{n}{2\hat\sigma^4}: the observed information for the Gaussian variance
PythonIn [19]
CollapseExpand
p_se_closed = np.sqrt(1 / p_information)
mu_se_closed = np.sqrt(1 / mu_information)
sigma2_se_closed = np.sqrt(1 / sigma2_information)
ConsoleOut [20]
CollapseExpand
Approximate standard error for p_hat: 0.1095
Approximate standard error for mu_hat: 0.0938
Approximate standard error for sigma2_hat: 0.0278
Root of observed information for p_hat: 9.1287

The Bernoulli standard error is the same value we derived by hand from clicks and visitors, and it reflects the moderate amount of information in twenty visits. The Gaussian mean standard error is small in absolute terms, but with only five observations it relies on the asymptotic approximation. Here the variance standard error is large relative to the variance estimate. Comparing this with the mean estimate is not a general ranking of how difficult means and variances are to estimate: their scales and units differ. Variance intervals also need care in small samples.

Key Parameters

The key parameters that govern the implementation are:

  • clicks and visitors: the number of successes and trials for the Bernoulli example. The closed-form estimate is clicks / visitors; the ratio is only meaningful when visitors is positive.
  • p_grid: the sequence of candidate probabilities between 0.0010.001 and 0.9990.999 used by the grid search. A finer grid can reduce discretization error but increases cost, and the bounds keep pp away from the exact boundary where the logarithm is undefined.
  • Optimizer starting value for p: 0.5 for the Bernoulli fit; a plausible interior value helps the quasi-Newton method converge.
  • y: the observed Gaussian vector. The closed-form mean is y.mean(), and the maximum likelihood variance is the average squared deviation from that mean, np.mean((y - mu_hat_closed)**2).
  • Optimizer starting value x0 = [mu_hat_closed, 0.0]: the first entry is an initial guess for μ\mu (the sample mean) and the second is an initial guess for log⁡σ\log\sigma. The log parameterization keeps the standard deviation positive.
  • method="L-BFGS-B": a bounded quasi-Newton optimizer that works well for smooth lower-dimensional problems.
  • Observed information: visitors / (p_hat * (1 - p_hat)) for the Bernoulli probability, len(y) / sigma2_hat for the Gaussian mean, and len(y) / (2 * sigma2_hat**2) for the Gaussian variance. The information formulas are exact for the stated interior fits; using inverse information to estimate sampling uncertainty is the large-sample approximation.

Key Methods

np.mean computes the sample mean by summing the observations and dividing by nn. np.var(y, ddof=0) would compute the maximum likelihood variance, while np.var(y, ddof=1) computes the unbiased sample variance. The difference is the denominator nn versus n−1n-1. np.argmax returns the index of the largest value in an array, which is how you select the best grid point.

scipy.optimize.minimize minimizes a scalar function of one or more variables. We pass the negative log-likelihood because the optimizer minimizes. The method="L-BFGS-B" option supports bounds. In these calls, no jac is supplied, so SciPy estimates gradients numerically; callers can also supply an analytic gradient. norm.logpdf evaluates normal log-densities, whose sum supplies a reference for our primitive objective. norm.fit(y) estimates the normal location and scale, which here are the sample mean and maximum likelihood standard deviation.

The optimizer returns an object with x, the estimated parameters, and success, a Boolean flag indicating whether the algorithm believes it converged. Convergence flags are useful but not sufficient. For an unconstrained interior fit, check that the gradient is near zero and inspect the Hessian of the negative log-likelihood. Positive definiteness is a sufficient local minimum check, not proof of global optimality; bounded solutions instead require the corresponding constrained conditions. Compare reasonable starting values as well.

Practical Implications

Maximum likelihood is a natural choice when a credible probability model can be written down and when the goal includes both estimation and uncertainty. Applications include Bernoulli or binomial outcomes, Gaussian measurements, count data, survival times, and generalized linear models. The same likelihood construction also underlies many machine learning losses, including log loss for binary outcomes and squared error under Gaussian assumptions. The derivation therefore clarifies both the objective being optimized and the assumptions that objective encodes. Closed-form estimators are preferable when available; numerical optimization is appropriate when the score equation has no convenient solution.

The central practical requirement is that the model reflect the data-generating process closely enough for the estimand to be meaningful. Independence, the distributional family, and the mean-variance relationship all matter. Clustered, repeated, or spatially correlated observations call for a model that represents that dependence or for standard errors that account for it. Outliers under a Gaussian likelihood can pull the mean substantially. A heavier-tailed likelihood or robust loss changes the estimating equation and can change the population target under misspecification, so choose it to match the question.

Best Practices

Begin by deriving the score and the curvature for the chosen model, even when a numerical optimizer will be used. The derivation identifies the estimating equation, shows whether a closed form exists, and indicates where the likelihood may be flat or boundary-sensitive. For Bernoulli data, the estimate is p^=k/n\hat p=k/n with approximate standard error p^(1−p^)/n\sqrt{\hat p(1-\hat p)/n}. For Gaussian data, the mean estimate is the sample mean and the variance estimate is SSE/n\mathrm{SSE}/n, which is biased downward relative to the unbiased sample variance. Reporting the bias or using a bias-corrected variance should be a conscious choice tied to the inferential goal.

When numerical optimization is needed, minimize the negative log-likelihood, keep positive parameters on a log scale or within bounds, and start from a plausible value or a closed-form approximation. Try several starting values for non-concave problems, then verify the appropriate stationarity conditions (a near-zero gradient for an unconstrained interior fit), positive curvature where the regular local test applies, and that the estimate is stable across reasonable starts. A convergence flag is useful but not sufficient evidence that the optimum has been found.

Report uncertainty with every point estimate. Curvature-based standard errors from the inverse observed information are fast and often adequate in large samples, but they can be misleading near boundaries, in small samples, or under misspecification. Profile likelihood intervals, bootstrap intervals, and simulation-based checks are useful alternatives when the normal approximation is suspect. For predictive modeling, fit on training data and evaluate on disjoint validation data; an in-sample likelihood is not evidence of out-of-sample performance.

Data Requirements and Preprocessing

The data must support the likelihood that will be optimized. For Bernoulli data, the sufficient inputs are the number of successes kk and trials nn under a constant-probability model. For the i.i.d. Gaussian mean and variance model, nn, ∑iyi\sum_i y_i, and ∑iyi2\sum_i y_i^2 suffice to evaluate the likelihood; retaining the full vector also permits distributional checks. Regression models additionally use the predictor matrix. The model family, the independence structure, and the parameterization should be specified before fitting. Missing data need an explicit sampling and missingness model. Complete-case estimates can be biased under selective missingness, and treating imputed values as observed can understate uncertainty. The appropriate likelihood depends on what is observed and how missingness is handled.

Outliers and distributional shape deserve inspection rather than automatic deletion. A Gaussian location likelihood is sensitive to extreme observations. A heavier-tailed model changes the objective and may target a different aspect of the distribution under misspecification. Predictor standardization can improve conditioning; with a one-to-one coefficient transformation and corresponding intercept, it preserves the unpenalized regression model. Fit that transformation on training data only when evaluating predictions. Positive quantities such as variances, rates, and scale parameters should be represented on a log scale or constrained during optimization.

Sample size affects sampling precision and the reliability of asymptotic approximations. Structural identifiability concerns the model; an uninformative design or a small realized sample can still leave parameters poorly determined. Curvature-based standard errors may be poor near boundaries. Before fitting a complex model, check whether the data contain enough variation to distinguish the parameters; if not, simplify the model, collect more informative data, or impose a defensible constraint.

Common Pitfalls

A frequent mistake is to interpret the likelihood as a probability distribution over the parameter. The likelihood is a function of the parameter with the data held fixed; without a prior and normalization, it does not assign posterior probabilities. A related mistake is to report only the point estimate and omit uncertainty. The maximum is a summary of the best-fitting value, but the curvature, sample size, and model assumptions determine how much confidence that value warrants.

Another common problem is trusting an optimizer without checking the optimization problem. A successful convergence flag does not rule out a local maximum, a flat likelihood, or a boundary solution. Non-concave likelihoods can produce different answers from different starting values, and non-identifiable models can return arbitrary values along a flat direction. Checking the gradient, the Hessian, several starting values, and the stability of the estimate is more informative than relying on a single fit.

Model misspecification and boundary estimates are also frequent sources of error. Ignoring dependence can make standard errors too small, and using a Gaussian likelihood for heavy-tailed data can produce an estimate dominated by outliers. When the estimate lies near a boundary, such as a Bernoulli probability of zero or one, the usual Wald interval can be unreliable. In these settings, profile likelihood, bootstrap, or Bayesian intervals may be more appropriate, and the model assumptions should be reported alongside the estimate.

Computational Considerations

A direct likelihood evaluation costs O(n)O(n) when each of nn independent observations has constant evaluation cost, as in the Bernoulli and univariate Gaussian examples. A dense linear predictor with pp coefficients typically costs O(np)O(np) per pass. Accumulating the sufficient statistics for these examples takes O(n)O(n); subsequent closed-form estimates and likelihood evaluations from those statistics take O(1)O(1). Numerical optimization adds iterations, and forming or approximating a Hessian can become expensive as the parameter dimension grows. Grid search is easy to interpret in one or two dimensions but becomes impractical in higher dimensions.

The bounded L-BFGS-B optimizer used here is one option for smooth likelihoods; its success depends on the objective, constraints and starting values. For high-dimensional problems, gradient-based methods, analytic gradients, and careful scaling become important. When observations are very numerous, subsampling or stochastic gradients can reduce cost, while sufficient statistics can make repeated likelihood evaluations much cheaper for exponential-family models. Memory requirements depend on whether the full data matrix, pairwise distances, or a Hessian approximation must be stored.

Numerical conditioning should be treated as part of the modeling workflow. Standardizing predictors, centering variables, avoiding extreme starting values, and using log parameterizations can make the difference between convergence and failure. Bounds can keep a parameter away from a region where the log-likelihood is undefined, but bounds should not be used to hide a poorly specified model. After fitting, inspect the gradient and curvature rather than assuming that the optimizer's stopping rule implies a well-behaved optimum.

Performance and Deployment Considerations

Performance should be evaluated with both in-sample and out-of-sample criteria. The maximized log-likelihood is useful for comparing nested models and for computing information criteria such as AIC or BIC, but it can favor more complex models and does not by itself measure predictive accuracy. For Bernoulli outcomes, out-of-sample log loss and calibration are natural checks; for Gaussian outcomes, out-of-sample squared error or predictive log score is appropriate. Standard errors and interval coverage should also be checked when the estimate will support decisions rather than mere prediction.

In deployment, record the model family, preprocessing steps, parameterization, optimizer settings, and the data version used for fitting. These details matter because a likelihood fit is reproducible only when the same transformations and constraints are applied. Monitor predictive log loss, calibration, and the distribution of incoming features; a likelihood model can remain computationally stable while its predictions deteriorate under data drift. Refit when the data-generating process changes, and retain uncertainty estimates where decisions depend on more than a point prediction.

For simple models, sufficient statistics can make updating inexpensive and can support online or batch refitting. For larger models, retraining cost and numerical diagnostics should be planned explicitly. A deployed likelihood model is not validated by its optimizer's success flag. It is validated by out-of-sample performance, calibrated uncertainty, and continued agreement between the model's assumptions and the data it receives.

Summary

Maximum likelihood estimation chooses the parameter values that make the observed data most plausible under a probability model. Under independence, the likelihood is a product of per-observation masses or densities, and the log-likelihood is the sum of their logarithms. We maximize the log-likelihood, or equivalently minimize the negative log-likelihood. Logs are monotone, numerically stable, and easy to differentiate. The likelihood is not a probability distribution over parameters; it is a function of the parameter with the data held fixed.

For Bernoulli data, the maximum likelihood estimate is p^=k/n\hat p=k/n on [0,1][0,1]; the Wald standard error p^(1−p^)/n\sqrt{\hat p(1-\hat p)/n} is an interior large-sample approximation. For a nondegenerate i.i.d. Gaussian sample, the maximum likelihood mean is the sample mean and the variance is SSE/n\mathrm{SSE}/n, with downward finite-sample bias. If SSE=0\mathrm{SSE}=0, no positive-variance Gaussian MLE is attained. Independent Gaussian errors with common variance make likelihood maximization over regression coefficients equivalent to minimizing squared error.

The score and curvature provide both optimization equations and uncertainty estimates. The score is zero at an interior maximum, and the negative second derivative measures information. Identifiability determines whether the parameters can be distinguished at all, while sampling uncertainty describes how much the estimate would vary across repeated samples. Maximum likelihood is general, but it is only as trustworthy as the model, the data, and the numerical checks behind it.

Quiz

Ready to test your understanding? Take this quick quiz to reinforce what you've learned about maximum likelihood estimation.

Maximum Likelihood Estimation Quiz

Question 1 of 70 of 7 completed
Which statement best describes the likelihood L(θ;y)?L(θ;y)?
Join the discussionAsk a question or share what you learned.

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!

A different angle
All writing
Machine Learning

Gradient Descent and Numerical Optimization

Learn how gradient descent updates parameters on quadratic objectives, how curvature and learning rates control convergence, and how to verify least-squares fits in NumPy.

43 min read
Machine Learning · Vol. 2

Gauss-Markov Assumptions for OLS Regression

Covers the Gauss-Markov assumptions that underpin linear regression. Topics include the five key assumptions, how to test them, consequences of violations.

17 min read
Machine Learning · Vol. 2

Normalization: Feature Scaling with Min-Max Implementation

Covers normalization in machine learning, covering min-max scaling, proper train-test split implementation, when to use normalization vs standardization.

14 min read

About the author

Reference

Citation details

Cite or share this article.

BIBTEXAcademic
@misc{brenndoerfer2026maximumlikelihood, author = {Michael Brenndoerfer}, title = {Maximum Likelihood Estimation}, year = {2026}, url = {https://mbrenndoerfer.com/writing/maximum-likelihood-estimation-from-scratch}, organization = {mbrenndoerfer.com}, note = {Accessed: 2026-10-28} }
APAAcademic
Michael Brenndoerfer (2026). Maximum Likelihood Estimation. Retrieved from https://mbrenndoerfer.com/writing/maximum-likelihood-estimation-from-scratch
MLAAcademic
Michael Brenndoerfer. "Maximum Likelihood Estimation." 2026. Web. October 28, 2026. <https://mbrenndoerfer.com/writing/maximum-likelihood-estimation-from-scratch>.
CHICAGOAcademic
Michael Brenndoerfer. "Maximum Likelihood Estimation." Accessed October 28, 2026. https://mbrenndoerfer.com/writing/maximum-likelihood-estimation-from-scratch.
HARVARDAcademic
Michael Brenndoerfer (2026) 'Maximum Likelihood Estimation'. Available at: https://mbrenndoerfer.com/writing/maximum-likelihood-estimation-from-scratch (Accessed: October 28, 2026).
SimpleBasic
Michael Brenndoerfer (2026). Maximum Likelihood Estimation. https://mbrenndoerfer.com/writing/maximum-likelihood-estimation-from-scratch
Newsletter

Stay up to date

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

Unsubscribe at any time. Privacy policy