Estimation, data quality, and unsupervised patterns
Vadim Sokolov
George Mason University
Fall 2026
The secretary problem: also called the matching or marriage problem.
Say I have a budget to consider \(T=10\) candidates, and they have the following scores (which I do not know)
1 7 4 5 3 8 10 3 0 11
I decide to screen 3 candidates before making a decision.
What’s your best strategy?
The peak is near \(T/e\) and height \(1/e\) (Monte Carlo, so the top wiggles).
Decision Tree
You live in a house that is somewhat prone to mud slides.
Should you build the wall? Should you use the Geologist’s Test and Bayes Rule?
Let’s formally solve this as follows:
There’s also the possibility of a further test to see if the wall will hold.
Mudslide Decision Tree
Let’s include the testing option
If you choose the test, then should you build the wall?
Bayes Rule is as follows:
We’ll use this to find our optimal course of action.
The Bayes probability given a positive test is \[\begin{align*} P(\text{Slide} \mid T) &= \frac{P(T \mid \text{Slide}) P(\text{Slide})}{P(T)} \\ &= \frac{0.90 \times 0.01}{0.1575} = 0.0571 \end{align*}\]
The Bayes probability given a negative test is \[\begin{align*} P(\text{Slide} \mid \bar{T}) &= \frac{P(\bar{T} \mid \text{Slide}) P(\text{Slide})}{P(\bar{T})} \\ &= \frac{0.1 \times 0.01}{0.8425} \\ &=0.001187 \end{align*}\]
Compare this to the initial base rate of a \(1\)% chance of having a mud slide.
You build the wall without testing, what’s the probability that you lose everything?
With the given situation, there is one path (or sequence of events and decisions) that leads to losing everything:
\[P(\text{losing everything} \mid \text{build w/o testing}) = 0.01 \times 0.05 = 0.0005\]
You choose the test, what’s the probability that you’ll lose everything?
There are two paths that lead to losing everything:
For the first path \[P(\text{first path}) = 0.1575 \times 0.0571 \times 0.05 = 0.00045\]
For the second path \[P(\text{second path}) = 0.8425 \times 0.001187 = 0.00101\]
Hence putting it all together \[P(\text{losing everything} \mid \text{testing}) = 0.00045 + 0.00101 = 0.00146\]
Risk-Return Trade-off
| Choice | Expected Cost | Risk | P |
|---|---|---|---|
| Don’t Build | $10,000 | 0.01 | 1 in 100 |
| Build w/o testing | $40,500 | 0.0005 | 1 in 2000 |
| Test | $10,760 | 0.00146 | 1 in 700 |
Expected Cost: Fee + Build + Loss
Expected cost: \(3 + 40\times 0.1575+ 1000\times 0.00146\) or $10,760
What do you choose?
Probability is a property of what you know.
Litowitz, Fortune, 15 September 2026. Opening of The Adaptability Quotient.
Coherence forces the same rules Kolmogorov wrote down.
The complement rule \(P(A)+P(\bar A)=1\) is 2 and 3 together. Violate any of them and someone can lock in a loss.
As \(N\) grows, \(n/N\) settles near \(1/2\).
S&P 500 returns vs Normal
Albert Solomon (1913)
Challenges
Pattern recognition
Impact
Chess Analogy
“Let’s say a chess game. And you don’t know the rules… you try to figure out what the rules are… You might discover that when there’s only one bishop around on the board, that the bishop maintains its color. Later on you might discover the law for the bishop is that it moves on a diagonal…”
Feynman on AI
“When we make a bird, the airplanes don’t fly like a bird… It’s different, right? So, there’s no question that the later machines are not going to think like people think… they’re not going to do arithmetic the same way as we do arithmetic, but they’ll do it better.”
Evolution in Chess:
Correlation coefficient: measures strength of linear relationship
\[r = \frac{\text{cov}(X,Y)}{\sqrt{\text{var}(X)} \sqrt{\text{var}(Y)}}\]
Range: \(-1 \leq r \leq 1\)
Applications:
2012 Obama Election Prediction
library(plyr)
# Source: "http://www.electoral-vote.com/evp2012/Pres/pres_polls.csv"
election.2012 = read.csv("data/pres_polls.csv")
# Remove a pollster: elect2012 <- election.2012[!grepl('Rasmussen', election.2012$Pollster),]
elect2012 <- election.2012
# Aggregrate the data
elect2012 <- ddply(elect2012, .(state), subset, Day == max(Day))
elect2012 <- ddply(elect2012, .(state), summarise, R.pct = mean(GOP), O.pct = mean(Dem), EV = mean(EV))| state | R.pct | O.pct | EV |
|---|---|---|---|
| Alabama | 61 | 38 | 9 |
| Alaska | 55 | 42 | 3 |
| Arizona | 54 | 44 | 11 |
| Arkansas | 61 | 37 | 6 |
| California | 38 | 59 | 55 |
| Colorado | 47 | 51 | 9 |
| Connecticut | 40 | 58 | 7 |
| D.C. | 7 | 91 | 3 |
| Delaware | 40 | 59 | 3 |
| Florida | 49 | 50 | 29 |
| Georgia | 53 | 45 | 16 |
| Hawaii | 28 | 71 | 4 |
| Idaho | 65 | 33 | 4 |
| Illinois | 41 | 57 | 20 |
| Indiana | 54 | 44 | 11 |
| Iowa | 47 | 52 | 6 |
| Kansas | 60 | 38 | 6 |
| Kentucky | 61 | 38 | 8 |
| Louisiana | 58 | 41 | 8 |
| Maine | 41 | 56 | 4 |
| Maryland | 37 | 62 | 10 |
| Massachusetts | 38 | 61 | 11 |
| Michigan | 45 | 54 | 16 |
| Minnesota | 45 | 53 | 10 |
| Mississippi | 56 | 44 | 6 |
| state | R.pct | O.pct | EV | |
|---|---|---|---|---|
| 26 | Missouri | 54 | 44 | 10 |
| 27 | Montana | 55 | 41 | 3 |
| 28 | Nebraska | 61 | 38 | 5 |
| 29 | Nevada | 46 | 52 | 6 |
| 30 | New Hampshire | 46 | 52 | 4 |
| 31 | New Jersey | 41 | 58 | 14 |
| 32 | New Mexico | 43 | 53 | 5 |
| 33 | New York | 36 | 63 | 29 |
| 34 | North Carolina | 51 | 48 | 15 |
| 35 | North Dakota | 59 | 39 | 3 |
| 36 | Ohio | 48 | 50 | 18 |
| 37 | Oklahoma | 67 | 33 | 7 |
| 38 | Oregon | 43 | 54 | 7 |
| 39 | Pennsylvania | 47 | 52 | 20 |
| 40 | Rhode Island | 36 | 63 | 4 |
| 41 | South Carolina | 55 | 44 | 9 |
| 42 | South Dakota | 58 | 40 | 3 |
| 43 | Tennessee | 60 | 39 | 11 |
| 44 | Texas | 57 | 41 | 38 |
| 45 | Utah | 73 | 25 | 6 |
| 46 | Vermont | 31 | 67 | 3 |
| 47 | Virginia | 48 | 51 | 13 |
| 48 | Washington | 42 | 56 | 12 |
| 49 | West Virginia | 62 | 36 | 5 |
| 50 | Wisconsin | 46 | 53 | 10 |
| 51 | Wyoming | 69 | 28 | 3 |
suppressMessages(library(MCMCpack))
prob.Obama <- function(mydata) {
p <- rdirichlet(1000, 500 * c(mydata$R.pct, mydata$O.pct, 100 - mydata$R.pct -
mydata$O.pct)/100 + 1)
mean(p[, 2] > p[, 1])
}
win.probs <- ddply(elect2012, .(state), prob.Obama)
win.probs$Romney <- 1 - win.probs$V1
names(win.probs)[2] <- "Obama"
win.probs$EV <- elect2012$EV
win.probs <- win.probs[order(win.probs$EV), ]
rownames(win.probs) <- win.probs$stateProbabilities of Obama winning by state
Calculate the probability of Obama having 270 EV or more
library(lattice)
# Lattice Graph
densityplot(sim.EV, plot.points = "rug", xlab = "Electoral Votes for Obama",
panel = function(x, ...) {
panel.densityplot(x, ...)
panel.abline(v = 270)
panel.text(x = 285, y = 0.01, "270 EV to Win")
panel.abline(v = 332)
panel.text(x = 347, y = 0.01, "Actual Obama")
}, main = "Electoral College Results Probability")Application in Election Forecasting:
Why Use Dirichlet for Polling?
Results of recent state polls in the 2008 United States Presidential Election between Barack Obama and John McCain.
# Source: LearnBayes library
#| fig-height: 6
election.2008 = read.csv("data/election2008.csv")
attach(election.2008)
## Dirichlet simulation
prob.Obama = function(j)
{
p=rdirichlet(5000,500*c(M.pct[j],O.pct[j],100-M.pct[j]-O.pct[j])/100+1)
mean(p[,2]>p[,1])
}
## sapply function to compute Obama win prob for all states
Obama.win.probs=sapply(1:51,prob.Obama)
## sim.EV function
sim.election = function()
{
winner = rbinom(51,1,Obama.win.probs)
sum(EV*winner)
}
sim.EV = replicate(1000,sim.election())
## histogram of simulated election
hist(sim.EV,min(sim.EV):max(sim.EV),col="blue",prob=T)
abline(v=365,lwd=3) # Obama received 365 votes
text(375,30,"Actual \n Obama \n total")To fit a Poisson distribution, we need to estimate its single parameter, λ.
\[ P(X=k) = \frac{\lambda^k e^{-\lambda}}{k!} \]
A natural choice for the estimate, \(\hat{\lambda}\), is the sample mean of the observed counts.
We will explore the rationale for this choice and how to assess its reliability.
Let’s plot the observed and expected frequencies.
#| fig-width: 8
#| fig-height: 5
#| code-fold: true
expected_counts = dpois(0:17, lmb*10)*1207 # expected count
expected_counts = c(sum(expected_counts[1:3]), expected_counts[4:18])
# Create a data frame for plotting
results <- data.frame(
Particles = d$n,
Observed = d$Observed,
Expected = expected_counts
)
# Plotting
library(ggplot2)
ggplot() +
geom_bar(data = results, aes(x = Particles, y = Observed), stat = "identity", fill = "skyblue", alpha = 0.7, width=0.8) +
geom_line(data = results, aes(x = Particles, y = Expected), color = "red", linewidth=1) +
geom_point(data = results, aes(x = Particles, y = Expected), color = "red", size=3) +
scale_x_continuous(breaks = 0:17) +
labs(title = "Alpha Particle Emissions: Observed vs. Expected Frequencies",
subtitle = paste("Poisson Fit with lambda =", round(lmb, 3)),
x = "Number of Alpha Particles per Interval",
y = "Frequency") +
theme_minimal()The density of normal is \[ f(x) = \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{(x-\mu)^2}{2\sigma^2}} \]
The mean and variance of the normal distribution are: \[ E(X) = \mu \]
Now Plot the histogram and the fitted normal curve.
We will look at two general methods for creating estimates: 1. The Method of Moments 2. The Method of Maximum Likelihood
This method equates sample moments with the theoretical moments of the distribution, which are functions of the parameters.
Procedure:
For a Poisson distribution, the first theoretical moment is the mean: \[ E(X) = \lambda \]
The first sample moment is the sample mean: \[ \hat{\mu}_1 = \bar{X} \]
Equating them gives the method of moments estimate for λ: \[ \hat{\lambda} = \bar{X} \]
This is precisely what was done in the alpha particle example.
For a Normal distribution, the first two theoretical moments are: \[E(X) = \mu\] \[E(X^2) = \mu^2 + \sigma^2\] Solving for the parameters gives: \[\mu = E(X)\] \[\sigma^2 = E(X^2) - [E(X)]^2\] The method of moments estimates are found by replacing theoretical moments with sample moments: \[\hat{\mu} = \bar{X}\] \[\hat{\sigma}^2 = \frac{1}{n}\sum_{i=1}^n X_i^2 - \bar{X}^2 = \frac{1}{n}\sum_{i=1}^n (X_i - \bar{X})^2\]
Let’s fit a normal distribution to human body temperature data. We’ll use the method of moments to estimate μ and σ and visualize the fit.
# Load the body temperature data
bodytemp <- read.csv("data/bodytemp.txt")
temperatures <- bodytemp$temperature
# Method of Moments estimates
mu_hat <- mean(temperatures)
# Note: R's var() function uses the n-1 denominator for an unbiased estimate.
# The strict method of moments uses n. The difference is negligible for large n.
sigma2_hat <- var(temperatures) * (length(temperatures)-1) / length(temperatures)
sigma_hat <- sqrt(sigma2_hat)
print(paste("Estimated mu:", round(mu_hat, 2)))[1] "Estimated mu: 98.25"
[1] "Estimated sigma: 0.73"
# Plotting the histogram and the fitted normal curve
library(ggplot2)
ggplot(data.frame(x = temperatures), aes(x = x)) +
geom_histogram(aes(y = after_stat(density)), binwidth = 0.2, fill = "skyblue", color = "white", alpha = 0.7) +
stat_function(fun = dnorm, args = list(mean = mu_hat, sd = sigma_hat), color = "red", size = 1) +
labs(title = "Fit of Normal Distribution to Body Temperatures",
subtitle = paste("mu_hat =", round(mu_hat, 2), ", sigma_hat =", round(sigma_hat, 2)),
x = "Body Temperature (F)",
y = "Density") +
theme_minimal()An estimate is wrong for two reasons.
Internet-scale \(n\) makes the blue line vanish.
The CDF of a random variable \(X\), denoted as \(F(x)\), is defined as: \[F(x) = P(X \leq x)\]
Key Properties:
For a discrete random variable, the CDF is a step function: \[F(x) = \sum_{k: x_k \leq x} P(X = x_k)\]
Example: Rolling a six-sided die
For a continuous random variable with PDF \(f(x)\): \[F(x) = \int_{-\infty}^x f(t) \, dt\]
Relationship between PDF and CDF: \[f(x) = \frac{dF(x)}{dx}\]
Probability calculations: \[P(a < X \leq b) = F(b) - F(a)\]
For uniform distribution on \([0,1]\) with PDF: \[ f(x) = \begin{cases} 1 & \text{if } 0 \leq x \leq 1 \\ 0 & \text{otherwise} \end{cases} \]
The CDF is: \[ F(x) = \begin{cases} 0 & \text{if } x < 0 \\ x & \text{if } 0 \leq x \leq 1 \\ 1 & \text{if } x > 1 \end{cases} \]
1. Probability Calculations:
2. Percentiles and Quantiles:
3. Random Number Generation:
Algorithm for generating random samples:
Where \(F^{-1}(u) = \inf\{x : F(x) = u\}\) is the inverse CDF (quantile function).
Why it works: If \(U\) is uniform on \([0,1]\), then \(F^{-1}(U)\) has the desired distribution \(F\).
This method is particularly useful when:
For a normal random variable \(X \sim N(\mu, \sigma^2)\), the CDF is: \[F(x) = P(X \leq x) = \int_{-\infty}^x \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(t-\mu)^2}{2\sigma^2}} dt\]
No closed-form solution exists - must use numerical methods or tables.
Standard Normal CDF: When \(\mu = 0, \sigma = 1\): \[\Phi(z) = \int_{-\infty}^z \frac{1}{\sqrt{2\pi}} e^{-\frac{t^2}{2}} dt\]
Standardization: \(F(x) = \Phi\left(\frac{x-\mu}{\sigma}\right)\)
Key Properties of \(\Phi(z)\):
z <- seq(-4, 4, length.out = 1000)
phi_z <- pnorm(z)
plot(z, phi_z, type = "l", lwd = 3, col = "blue",
xlab = "z", ylab = "Φ(z)",
main = "Standard Normal CDF")
# Add horizontal lines for key probabilities
abline(h = c(0.025, 0.5, 0.975), col = "red", lty = 2)
abline(v = c(-1.96, 0, 1.96), col = "red", lty = 2)
# Add labels
text(-1.96, 0.1, "-1.96", col = "red", cex = 1.2)
text(1.96, 0.1, "1.96", col = "red", cex = 1.2)
text(-3, 0.975, "0.975", col = "red", cex = 1.2)
text(-3, 0.025, "0.025", col = "red", cex = 1.2)
grid()Standard Normal CDF with key values highlighted
1. Probability Calculations: \[P(a < X < b) = \Phi\left(\frac{b-\mu}{\sigma}\right) - \Phi\left(\frac{a-\mu}{\sigma}\right)\]
2. Confidence Intervals:
3. Quality Control:
SAT scores are approximately \(N(1000, 200^2)\). Let’s calculate some probabilities:
P(SAT > 1200) = 0.159
P(800 < SAT < 1200) = 0.683
# Visualization
x <- seq(400, 1600, length.out = 1000)
y <- dnorm(x, mu_sat, sigma_sat)
plot(x, y, type = "l", lwd = 2, col = "blue",
xlab = "SAT Score", ylab = "Density",
main = "SAT Scores Distribution with Probabilities")
# Shade areas
x_above <- seq(1200, 1600, length.out = 100)
y_above <- dnorm(x_above, mu_sat, sigma_sat)
polygon(c(1200, x_above, 1600), c(0, y_above, 0),
col = rgb(1, 0, 0, alpha = 0.3))
x_between <- seq(800, 1200, length.out = 100)
y_between <- dnorm(x_between, mu_sat, sigma_sat)
polygon(c(800, x_between, 1200), c(0, y_between, 0),
col = rgb(0, 1, 0, alpha = 0.3))
# Add vertical lines
abline(v = c(800, 1000, 1200), col = "red", lty = 2, lwd = 2)
# Add labels
text(1300, 0.0005, paste("P(>1200) =", round(prob_above_1200, 3)), col = "red")
text(1000, 0.001, paste("P(800-1200) =", round(prob_between_800_1200, 3)), col = "darkgreen")
grid()Key R functions for Normal CDF:
[1] 0.9750021
[1] 0.8413447
[1] 1.959964
[1] 1328.971
[1] 0.9500042
The quantile function (also called the inverse CDF) gives the value \(x\) such that the probability of the random variable being less than or equal to \(x\) is a specified probability \(p\).
Why is it useful? - Summarizes distributions (e.g., percentiles, medians) - Used in constructing confidence intervals and tolerance intervals - Important in risk analysis (e.g., Value-at-Risk in finance)
R function: qnorm() for the normal distribution (and q* for other distributions)
[1] 1.959964
[1] 1328.971
CDF
Quantile
Assume we observe \(y_1, \ldots, y_n\) which are independent draws from a random variable \(Y\) with probability density function \(p(y | \theta)\) (normal, binomial, etc.).
Likelihood Function: \[L(\theta) = \prod_{i=1}^n p(y_i | \theta)\]
Log-likelihood Function: \[l(\theta) = \sum_{i=1}^n \log p(y_i | \theta)\]
Likelihood is a function of \(\theta\) that measures how likely the observed data is given the parameter \(\theta\).
The maximum likelihood estimate of \(\theta\) is the value of \(\theta^*\) that maximizes the likelihood function.
\[\theta^* = \arg\max_{\theta} L(\theta)\] Sometimes we use notations \(\theta_{\text{MLE}}\) or simply \(\hat \theta\) to denote the maximum likelihood estimate of \(\theta\).
Or the log-likelihood function. \[\theta^* = \arg\max_{\theta} l(\theta)\]
Logarithm is a monotonically increasing function, so the maximum likelihood estimate of \(\theta\) is the same as the maximum log-likelihood estimate of \(\theta\).
\[\theta^* = \arg\max_{\theta} L(\theta) = \arg\max_{\theta} l(\theta)\]
For exponential family RVs, it is easier to maximize the log-likelihood function.
Why?
For the normal distribution, maximum likelihood leads to least squares!
Given \(y_i \sim N(\mu, \sigma^2)\), here we have two parameters \(\mu\) and \(\sigma^2\).
\[l(\mu, \sigma^2) = \sum_{i=1}^n \log p(y_i | x_i, \mu, \sigma^2) = \sum_{i=1}^n \log \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left(-\frac{(y_i - \mu)^2}{2\sigma^2}\right)\]
Expanding the normal log-likelihood: \[l(\mu, \sigma^2) = \sum_{i=1}^n \left[-\frac{1}{2}\log(2\pi\sigma^2) - \frac{(y_i - \mu)^2}{2\sigma^2}\right]\]
Removing \(\sigma^2\) and simplifying: \[l(\mu) = - \frac{1}{2\sigma^2}\sum_{i=1}^n (y_i - \mu)^2 + \text{constant}\]
\[\mu^* = \arg\min_{\mu} \sum_{i=1}^n (y_i - \mu)^2\]
Take the derivative of \(l(\mu)\) with respect to \(\mu\) and set it to 0: \[\frac{\partial l(\mu)}{\partial \mu} = 2\sum_{i=1}^n (y_i - \mu) = 0\] \[\sum_{i=1}^n (y_i - \mu) = 0\] \[\sum_{i=1}^n y_i = n\mu\] \[\hat \mu = \frac{1}{n}\sum_{i=1}^n y_i\]
Dataset: SAT score for 1000 students
mu_mle <- mean(sat$sat_sum)
sigma2_mle <- mean((sat$sat_sum - mu_mle)^2)
sigma_mle <- sqrt(sigma2_mle)
n <- nrow(sat)
# Print table
library(knitr)
results_table <- data.frame(
Parameter = c("μ (mean)", "σ² (variance)", "σ (std dev)", "n (sample size)"),
Value = c(round(mu_mle, 2), round(sigma2_mle, 2), round(sigma_mle, 2), n)
)
kable(results_table, caption = "Maximum Likelihood Estimates for Normal Distribution")| Parameter | Value |
|---|---|
| μ (mean) | 103.33 |
| σ² (variance) | 203.92 |
| σ (std dev) | 14.28 |
| n (sample size) | 1000.00 |
# Define negative log-likelihood function
neg_log_likelihood <- function(params, data) {
mu <- params[1]
sigma <- params[2]
# Ensure sigma is positive
if (sigma <= 0) return(Inf)
# Calculate negative log-likelihood
n <- length(data)
-sum(dnorm(data, mean = mu, sd = sigma, log = TRUE))
}
# Optimize using built-in optimizer
result <- optim(c(50, 10), neg_log_likelihood, data = sat$sat_sum)
mu_optim <- result$par[1]
sigma_optim <- result$par[2]
# Create results table for optimization
optim_table <- data.frame(
Parameter = c("μ", "σ"),
Analytical = c(round(mu_mle, 2), round(sigma_mle, 2)),
Optimized = c(round(mu_optim, 2), round(sigma_optim, 2)),
Difference = c(round(abs(mu_mle - mu_optim), 6), round(abs(sigma_mle - sigma_optim), 6))
)
kable(optim_table, caption = "Comparison of Analytical vs Numerical Optimization Results")| Parameter | Analytical | Optimized | Difference |
|---|---|---|---|
| μ | 103.33 | 103.33 | 0.000542 |
| σ | 14.28 | 14.28 | 0.002433 |
# Create grid of mu values around the MLE
library(ggplot2)
mu_range <- seq(mu_mle - 10, mu_mle + 10, length.out = 100)
log_likelihood_values <- sapply(mu_range, function(mu) {
-neg_log_likelihood(c(mu, sigma_mle), sat$sat_sum)
})
# Plot log-likelihood
likelihood_df <- data.frame(mu = mu_range, log_likelihood = log_likelihood_values)
ggplot(likelihood_df, aes(x = mu, y = log_likelihood)) +
geom_line(color = "darkblue", linewidth = 1) +
geom_vline(xintercept = mu_mle, color = "red", linetype = "dashed", linewidth = 1) +
annotate("point", x = mu_mle, y = max(log_likelihood_values),
color = "red", size = 3) +
labs(title = "Log-Likelihood Function for μ",
subtitle = paste("Maximum at μ =", round(mu_mle, 2)),
x = "Mean Score (μ)",
y = "Log-Likelihood") +
theme_minimal()Log-likelihood surface for different values of μ
The Royal Mint Tradition (12th Century)
Sir Isaac Newton’s Role (1696):
The Process:
Example: 1 million coins minted, \(n=100\) sample
# Simulate 2000 surveys
prep = replicate(2000, mean(sample(allcoins, size = 100, replace = FALSE)))
hist(prep, breaks = 30, freq = FALSE,
main = "Distribution of Sample Means",
xlab = "Sample Mean (grams)",
col = "lightblue", border = "white")
# Overlay normal distribution
p = seq(4.9, 5.1, length.out = 500)
lines(p, dnorm(p, mean(prep), sd(prep)), col = "red", lwd = 3)
# Add statistics
abline(v = mean(prep), col = "red", lwd = 2, lty = 2)
text(mean(prep), max(dnorm(p, mean(prep), sd(prep))),
paste("Mean:", round(mean(prep), 4)), pos = 3)Key Observation: The red bell-curve (normal density) models the distribution well!
The Fundamental Relationship
Standard Error decreases with \(\sqrt{n}\): \[s_{\bar x} = \frac{s}{\sqrt{n}}\]
This means: To halve uncertainty, you need to quadruple sample size!
The Math:
Practical Implications:
# Simulate different sample sizes
set.seed(42)
true_mean = 5.0
true_sd = 0.1
sample_sizes = c(10, 25, 50, 100, 200, 400, 800, 1600)
n_sims = 1000
# Calculate standard errors for each sample size
se_values = true_sd / sqrt(sample_sizes)
# Simulate confidence interval widths
ci_widths = 2 * 1.96 * se_values
# Create visualization
par(mfrow = c(1, 2))
# Plot 1: Standard Error vs Sample Size
plot(sample_sizes, se_values,
type = "b", lwd = 2, pch = 19, col = "blue",
xlab = "Sample Size (n)", ylab = "Standard Error",
main = "Standard Error vs Sample Size",
log = "xy")
grid()
# Add theoretical curve
curve(true_sd / sqrt(x), from = 10, to = 1600,
add = TRUE, col = "red", lwd = 2, lty = 2)
legend("topright", c("Observed", "Theoretical"),
col = c("blue", "red"), lty = c(1, 2), lwd = 2)
# Plot 2: Confidence Interval Width
plot(sample_sizes, ci_widths,
type = "b", lwd = 2, pch = 19, col = "green",
xlab = "Sample Size (n)", ylab = "95% CI Width",
main = "Confidence Interval Width vs Sample Size",
log = "xy")
grid()
# Add theoretical curve
curve(2 * 1.96 * true_sd / sqrt(x), from = 10, to = 1600,
add = TRUE, col = "red", lwd = 2, lty = 2)
legend("topright", c("Observed", "Theoretical"),
col = c("green", "red"), lty = c(1, 2), lwd = 2)Key Insight: The relationship is logarithmic - each doubling of sample size reduces uncertainty by \(\sqrt{2} \approx 1.41\)
Scenario: Quality control for coin weights
Required sample sizes:
Required sample size: 385
This gives CI width: 0.02 grams
CI widths for different sample sizes:
n = 100 → CI width = 0.0392 grams
n = 400 → CI width = 0.0196 grams
n = 1600 → CI width = 0.0098 grams
n = 6400 → CI width = 0.0049 grams
The Cost of Precision: - To get 4x more precise (0.08 → 0.02 grams), need 16× more data! - This is why large-scale experiments are expensive but necessary
The Most Powerful Theorem in Statistics
CLT states: Given sufficiently large sample size, sample means are approximately normally distributed, regardless of population distribution shape.
De Moivre-Laplace Theorem (1738): For independent Rademacher variables \(x_i\) with \(P(x_i = \pm 1) = 1/2\):
\[\lim_{n\to\infty} P\left(a \le \frac{x_1+\cdots+x_n}{\sqrt{n}} \le b\right) = \int_a^b \frac{1}{\sqrt{2\pi}} e^{-x^2/2} dx\]
Galton Board: (Physical demonstration of CLT)[https://youtu.be/zeJD6dqJ5lo?si=Pm_QVnXr4H403yYu]
Figure 1: Galton Board
The Challenge:
The Solution:
The Math: \(s_{\bar x} = s/\sqrt{n}\) where \(n\) = number of phones With massive \(n\), standard error becomes incredibly small!
95% Confidence Interval for μ:
Lower bound: 102.44
Upper bound: 104.21
Margin of error: 0.89
For an i.i.d. sample \(X_1, \dots, X_n\) from a Bernoulli(p) distribution, the likelihood is: \[ l(p) = \prod_{i=1}^n p^{x_i} (1-p)^{1-x_i} \]
The log-likelihood is: \[ l(p) = \sum_{i=1}^n \ln\left(p^{x_i} (1-p)^{1-x_i}\right) \] \[ = \sum_{i=1}^n \left( x_i \ln(p) + (1-x_i) \ln(1-p) \right) \]
To find the maximum, we take the derivative with respect to p and set it to zero: \[ \frac{\partial l}{\partial p} = \frac{1}{p}\sum_{i=1}^n x_i - \frac{1}{1-p}\sum_{i=1}^n (1-x_i) = 0 \] \[ \implies \hat{p}_{MLE} = \frac{1}{n}\sum_{i=1}^n x_i = \bar{X} \]
For an i.i.d. sample \(X_1, \dots, X_n\) from a Poisson(λ) distribution, the log-likelihood is: \[ l(\lambda) = \sum_{i=1}^n \ln\left(\frac{\lambda^{X_i} e^{-\lambda}}{X_i!}\right) = (\ln \lambda) \sum X_i - n\lambda - \sum \ln(X_i!) \]
To find the maximum, we take the derivative with respect to λ and set it to zero: \[ \frac{dl}{d\lambda} = \frac{1}{\lambda}\sum X_i - n = 0 \] \[ \implies \hat{\lambda}_{MLE} = \frac{\sum X_i}{n} = \bar{X} \]
For the Poisson distribution, the Method of Moments and the Maximum Likelihood estimates are the same.
The density of the Gamma distribution is: \[ f(x) = \frac{1}{\Gamma(\alpha)\lambda^\alpha} x^{\alpha-1} e^{-\frac{x}{\lambda}} \]
The mean and variance of the Gamma distribution are: \[ E(X) = \alpha\lambda \] \[ Var(X) = \alpha\lambda^2 \]
The Gamma distribution is extremely versatile and appears in many real-world applications:
Examples:
Let’s examine a real dataset: inter-arrival times of cosmic ray detections.
For the Gamma distribution, the log-likelihood is: \[l(\alpha, \lambda) = n\alpha\ln(\lambda) - n\ln(\Gamma(\alpha)) + (\alpha-1)\sum\ln(X_i) - \lambda\sum X_i\] The MLEs for α and λ don’t have a simple closed-form solution and must be found numerically by maximizing this function.
Let’s fit a Gamma distribution to the inter-arrival times of gamma-rays.
#| fig-width: 8
#| fig-height: 5
# Load the data
gamma_arrivals <- read.csv("data/gamma-arrivals.txt", header = FALSE)$V1
# Log-likelihood function for the Gamma distribution
log_likelihood_gamma <- function(params, data) {
alpha <- params[1]
lambda <- params[2]
if (alpha <= 0 || lambda <= 0) return(NA) # Parameters must be positive
n <- length(data)
loglik <- n * alpha * log(lambda) - n * lgamma(alpha) +
(alpha - 1) * sum(log(data)) - lambda * sum(data)
return(-loglik) # optim minimizes by default, so we return negative log-likelihood
}
# Use Method of Moments for starting values
mean_g <- mean(gamma_arrivals)
var_g <- var(gamma_arrivals)
alpha_start <- mean_g^2 / var_g
lambda_start <- mean_g / var_g
# Find MLEs using numerical optimization
mle_fit <- optim(par = c(alpha_start, lambda_start),
fn = log_likelihood_gamma,
data = gamma_arrivals)
alpha_mle <- mle_fit$par[1]
lambda_mle <- mle_fit$par[2]
print(paste("MLE for alpha:", round(alpha_mle, 4)))[1] "MLE for alpha: 1.0263"
[1] "MLE for lambda: 0.0128"
# Plotting
ggplot(data.frame(x = gamma_arrivals), aes(x = x)) +
geom_histogram(aes(y = after_stat(density)), bins = 50, fill = "skyblue", color = "white", alpha = 0.7) +
stat_function(fun = dgamma, args = list(shape = alpha_mle, rate = lambda_mle), color = "red", linewidth = 1) +
labs(title = "Fit of Gamma Distribution to Gamma-Ray Inter-Arrival Times",
subtitle = paste("alpha_mle =", round(alpha_mle, 3), ", lambda_mle =", round(lambda_mle, 3)),
x = "Inter-Arrival Time (seconds)",
y = "Density") +
xlim(0, 1000) +
theme_minimal()Under general “smoothness” conditions, MLEs have desirable large-sample properties:
This provides a strong theoretical justification for using MLEs.
The asymptotic normality of MLEs allows us to construct approximate confidence intervals. The variance of the limiting normal distribution is given by \(1/I(\theta_0)\), where \(I(\theta)\) is the Fisher Information.
\[ I(\theta) = E\left[\left(\frac{\partial}{\partial\theta} \ln f(X|\theta)\right)^2\right] = -E\left[\frac{\partial^2}{\partial\theta^2} \ln f(X|\theta)\right] \]
An approximate \(100(1-\alpha)\%\) confidence interval for \(\theta\) is: \[ \hat{\theta} \pm z_{\alpha/2} \frac{1}{\sqrt{nI(\hat{\theta})}} \] The term \(\frac{1}{\sqrt{nI(\hat{\theta})}}\) is the estimated standard error of the MLE.
The Negative Binomial distribution is often used for count data that is “overdispersed” (variance is greater than the mean), making it a good alternative to the Poisson. Let’s fit it to data on potato beetle counts.
#| message: false
#| warning: false
#| fig-width: 8
#| fig-height: 5
library(MASS) # For fitdistr
# Load data and expand from frequency table
evans <- read.csv("data/evans1953.txt")
beetle_data <- rep(evans$Count, evans$PotatoBeetles)
# Use fitdistr to find MLEs for the negative binomial distribution
# 'size' is r (number of successes), 'mu' is the mean
neg_bin_fit <- fitdistr(beetle_data, "negative binomial")
r_hat <- neg_bin_fit$estimate["size"]
mu_hat <- neg_bin_fit$estimate["mu"]
print(paste("MLE for r (size):", round(r_hat, 2)))[1] "MLE for r (size): 2.24"
[1] "MLE for mean (mu): 4.7"
# Calculate expected frequencies
max_count <- max(evans$Count)
counts_range <- 0:max_count
expected_freq <- length(beetle_data) * dnbinom(counts_range, size = r_hat, mu = mu_hat)
# Create a data frame for plotting
plot_data <- data.frame(
Count = counts_range,
Observed = sapply(counts_range, function(c) sum(beetle_data == c)),
Expected = expected_freq
)
# Plotting observed vs. expected
ggplot(plot_data, aes(x = Count)) +
geom_bar(aes(y = Observed), stat = "identity", fill = "skyblue", alpha = 0.7, width = 0.8) +
geom_line(aes(y = Expected), color = "red", size = 1) +
geom_point(aes(y = Expected), color = "red", size = 3) +
scale_x_continuous(breaks = seq(0, max_count, by = 2)) +
labs(title = "Potato Beetle Counts: Observed vs. Expected Frequencies",
subtitle = paste("Negative Binomial Fit with r_hat =", round(r_hat, 2), ", mu_hat =", round(mu_hat, 2)),
x = "Number of Beetles per Plant",
y = "Frequency") +
theme_minimal()Large Language Models (LLMs) like GPT, BERT, and others are trained using Maximum Likelihood Estimation as a core principle.
The Setup: - Given a sequence of tokens \(w_1, w_2, \ldots, w_n\) (words, subwords, or characters) - Model parameterized by \(\theta\) (neural network weights) - Goal: Find \(\theta\) that maximizes the likelihood of observing the training text
The Likelihood: For autoregressive models (like GPT), we factorize the joint probability: \[P(w_1, w_2, \ldots, w_n | \theta) = \prod_{i=1}^n P(w_i | w_1, \ldots, w_{i-1}, \theta)\]
The MLE objective is to maximize this likelihood over the training corpus.
Log-Likelihood Objective: \[\mathcal{L}(\theta) = \sum_{i=1}^n \log P(w_i | w_1, \ldots, w_{i-1}, \theta)\]
Cross-Entropy Loss: In practice, this becomes minimizing the cross-entropy loss: \[\text{Loss} = -\frac{1}{n} \sum_{i=1}^n \log P(w_i | \text{context}, \theta)\]
Key Components:
Training Data: Massive text corpora (books, web pages, articles) containing billions of tokens
Computational Challenges:
Statistical Considerations:
Modern Adaptations:
The success of LLMs demonstrates MLE’s power when combined with sufficient data and computational resources.
Supervised learning is the next notes: \(y = f(x)\).