Vol. 08 · ML & Decision Systems

Statistics for Evaluating LLM Systems

Basic concepts of statistics as applied to LLM experiments: quality metrics, variance and confidence intervals, hypothesis testing, A/B tests, LLM-as-judge, evaluation pitfalls and a practical checklist for a valid experiment.

Retrieval answer

Basic concepts of statistics as applied to LLM experiments: quality metrics, variance and confidence intervals, hypothesis testing, A/B tests, LLM-as-judge, evaluation pitfalls and a practical checklist for a valid experiment. Log-loss (cross-entropy) measures how confidently the model predicts the correct token. This New Runtime record is an evidence-linked retrieval unit.

01

LLM Quality Metrics

4 cards
01MetricsLog-Loss and Perplexity: one essence, two names1 visual1 source note

Log-loss (cross-entropy) measures how confidently the model predicts the correct token. Perplexity is simply an exponent of log-loss: “how many variants the model loses on average.” PPL=10 means the model “oscillates between 10 equally probable tokens” at each step.

Source-complete noteswhen to use

when to use

  • comparison of pretrain quality of models
  • assessment of quality degradation during quantization
  • PPL on the domain ≠ PPL on your task
  • does not reflect Useful framing for downstream tasks
02MetricsAccuracy, Precision, Recall, F11 source note

For classification tasks (IntentRouter, sentiment, RAG relevance), accuracy often deceives when classes are imbalanced. F1 - harmonic mean Precision and Recall - fairer for rare classes.

Source-complete notesformulas and error matrix
formulas and error matrixtex
Predicted + Predicted −
Actual + TP FN
Actual − FP TN

Accuracy = (TP+TN) / (TP+TN+FP+FN)
→ cheats: 99% TN → accuracy=99% effortless

Precision = TP / (TP+FP) ← of all the “+”, how many “+” are true?
Recall = TP / (TP+FN) ← of all the real “+”s, how many did you find?

F1 = 2 · (P R) / (P+R) ← harmonic mean

Macro F1: average F1 for all classes (imbalance not taken into account)
Weighted F1: class frequency weighted
03MetricsBLEU, ROUGE and their limitations2 source notes

BLEU and ROUGE measure the n-gram intersection between a generation and a reference. Historically the standard for translation and summarization, but poorly correlated with human assessment of the quality of free text.

Source-complete notesmechanics · modern practice
mechanicstext
BLEU (precision-oriented):
  BLEU-N = intersection of N-grams(gen, ref) / len(gen)
  ↑ penalizes for output that is too short (BP)
  ↑ usually average BLEU-1..4

ROUGE-N (recall-oriented):
  ROUGE-N = intersection of N-grams(gen, ref) / len(ref)

ROUGE-L: longest common subsequence

Example:
  ref: "the cat was sitting on the rug"
  gen: "the rug is occupied by a cat"
  BLEU-1 = 0.5 (2 words out of 3 are in ref)
  but the meaning is correct → BLEU does not see this

BERTScore: cosine proximity of embeddings
  ↑ better for semantic quality

modern practice

  • BLEU/ROUGE - only as baseline
  • BERTScore - if you need automation
  • LLM-as-judge - for free generation
04MetricsMetrics for RAGs and agents1 source note

The RAG pipeline consists of two stages - retrieval and generation - and both need to be measured separately. The final quality of the answer depends on both, but different types of errors require different corrections.

Source-complete notesRAGAS and components
RAGAS and componentssql
Retrieval:
  Hit Rate@k - relevant doc in the top-k?
  MRR@k - position of the first relevant
  Precision@k - share of relevant ones in the top k

Generation (RAGAS):
  Faithfulness - Is the answer based on context?
  Answer Relevancy - does the answer answer the question?
  Context Precision - does the context contain the answer?
  Context Recall - has all the required context been found?

Faithfulness Formula (LLM-judge):
  score = (#statements from context) / (#all statements)
  → catches hallucinations
02

Scatter, Variance and Confidence Intervals

4 cards
05ScatterMean, Variance, Standard Deviation2 source notes

One assessment of the LLM system does not mean anything. What matters is the spread—how unstable the results are. The variance σ² and standard deviation σ measure this spread around the mean.

Source-complete notesformulas · interpretation
formulastex
# n runs of the experiment, xᵢ is the result of the i-th

Sample mean:
  x̄ = (1/n) · Σᵢ xᵢ

Sample variance (unbiased):
  s² = 1/(n−1) Σᵢ (xᵢ − x̄)²
  ↑ divide by n-1, not n (Bessel correction)

Standard Deviation:
  s = √s² ← same units as xᵢ

Example: accuracy on 10 test sets:
  [0.82, 0.79, 0.84, 0.81, 0.83,
   0.80, 0.85, 0.78, 0.82, 0.81]
  x = 0.815
  s = 0.021 ← spread ≈ 2%

interpretation

  • s small → results are stable
  • s large → more runs needed
  • one point instead of distribution = error
06ScatterStandard Error and Confidence Interval1 source note

The average is also a random variable. Standard error (SE) measures how closely the estimated mean reflects the “true.” A confidence interval (CI) gives a range within which there is a 95% probability that the true value of a metric lies.

Source-complete notesformulas
formulastex
Standard error of the mean:
  SE = s/√n
  ↑ decreases with increasing sample
  ↑ for n=100: SE is 10 times less than n=1

95% Confidence Interval (normal):
  CI = x̄ ± 1.96 SE = x̄ ± 1.96 s/√n

Example:
  accuracy x̄ = 0.815, s = 0.021, n = 100
  SE = 0.021 / √100 = 0.0021
  95% CI = [0.811, 0.819]

  n = 10 → SE = 0.021/√10 = 0.0066
  95% CI = [0.802, 0.828] ← wide interval!

Conclusion: n=10 is a bad score. Need ≥ 50-100.
07ScatterBootstrap: CI without distribution assumptions2 source notes

The formula 1.96·SE works under normal distribution. LLM metrics (F1, BLEU, win-rate) are often not normal. Bootstrap is a universal method: we sample with return and build an empirical distribution.

Source-complete notesbootstrap CI algorithm · when to use
bootstrap CI algorithmsql
results = [0.82, 0.79, 0.84, 0.81, …] # n=100

bootstrap_means = []
for _ in range(10_000):
  sample = resample(results, n=100) # return
  bootstrap_means.append(mean(sample))

#95% CI = 2.5% and 97.5% percentiles
ci_low = percentile(bootstrap_means, 2.5)
ci_high = percentile(bootstrap_means, 97.5)

print(f"95% CI: [{ci_low:.3f}, {ci_high:.3f}]")

from scipy.stats import bootstrap
res = bootstrap((data,), np.mean, n_resamples=10000)

when to use

  • the metric is not normally distributed
  • small sample (n < 30)
  • complex metrics (BLEU, F1, win-rate)
  • gold standard for LLM experiments
08ScatterSources of variance in the LLM experiment1 visual

LLM adds its own layer of randomness on top of the normal sample variance. Before calculating the metric, you need to know what noise sources there are and which one dominates.

Visual model · Process flowFollow the sequence behind Sources of variance in the LLM experiment and locate where work or state changes.
Complete view · 6 layers
03

Testing Statistical Hypotheses

4 cards
09HypothesesNull hypothesis, p-value and how not to read them1 visual1 source note

Hypothesis testing is a formal procedure for deciding whether the improvement is real or random. The p-value is the most commonly misinterpreted value in science. Let's figure out exactly what it means and what it doesn't.

Visual model · Process flowFollow the sequence behind Null hypothesis, p-value and how not to read them and locate where work or state changes.
Complete view · 5 layers
Source-complete notestypical thresholds α

typical thresholds α

  • p < 0.05 - standard (5% probability of false alarm)
  • p < 0.01 - strict
  • p < 0.1 - soft (research)
  • p by itself without effect size is an incomplete picture
10Hypothesest-test: comparison of two systems1 source note

The t-test tests whether the observed difference in means could have occurred by chance? Paired t-test - for the same sets of questions (A and B were assessed on the same data). Independent - for different sets.

Source-complete notespaired t-test (recommended for LLM)
paired t-test (recommended for LLM)sql
# Both prompts were run on the same 100 questions
scores_A = [0.8, 0.6, 1.0, …] # 100 values
scores_B = [0.9, 0.7, 1.0, …] # 100 values

diff = scores_B - scores_A # pairwise differences
# H₀: mean(diff) = 0

t = mean(diff) / (std(diff) / √n)
# compare with t-distribution (n-1 degrees of freedom)

from scipy.stats import ttest_rel
t_stat, p_value = ttest_rel(scores_B, scores_A)

Why paired is better than independent:
  removes variance from question difficulty
  → one complex issue affects both systems
  → difference is cleaner
11HypothesesWilcoxon: nonparametrics for scores 1–51 source note

When an LLM-judge or person gives marks 1–5, the data is ordinal, not interval. The t-test assumes normality - this is violated for scores. The Wilcoxon test is a nonparametric analogue of the paired t-test and makes no assumptions about distribution.

Source-complete notesalgorithm and application
algorithm and applicationsql
# Ratings of two systems (15) using 50 examples:
grades_A = [3, 4, 3, 5, 2, …]
grades_B = [4, 4, 4, 5, 3, …]

from scipy.stats import wilcoxon
stat, p_value = wilcoxon(grades_B, grades_A,
                          alternative='greater')

Works through difference ranks:
  diff_i = B_i - A_i
  → rank |diff_i|
  → compare the sums of ranks “+and “−”

When to use:
  ✓ ratings 1-5, 1-10 (LLM-judge, human eval)
  ✓ ordinal metrics (pass@k ranks)
  ✓ small samples (n < 30)
12HypothesesMultiple comparisons and Bonferroni correction2 source notes

If you compare 10 prompts in pairs, that’s 45 tests. With α=0.05 and 45 tests, ~2 false significant results are expected simply by chance. The Bonferroni correction adjusts the significance threshold.

Source-complete notesproblem and solution · rule
problem and solutionsql
Family-wise error rate (FWER):
  P(at least 1 false alarm from m tests)
  = 1 − (1−α)^m

  m=45, α=0.051−(0.95)^45 = 0.90 = 90%!

Bonferroni correction:
  α* = α / m = 0.05 / 45 = 0.0011
use this threshold for each test

Benjamini-Hochberg correction (FDR):
  less strict, controls the rate of false discoveries
  → recommended for large numbers of comparisons

from statsmodels.stats.multitest import multipletests
reject, p_adj, _, _ = multipletests(
  p_values, method='bonferroni' # or 'fdr_bh'
)

rule

  • compared 10 prompts, took the best one without correction → error
  • Bonferroni - strictly, few comparisons (<20)
  • BH / FDR - flexible, many comparisons
04

A/B Test of LLM systems

3 cards
13A/B testEffect Size: the difference is significant - but is it big?1 visual1 source note

p-value says “whether the difference is due to chance”, but nothing about its magnitude. With large n, even a difference of 0.1% will be statistically significant. Effect size is a separate value that answers the question “how big is the effect?”

Visual model · Formula mapConnect the quantities and operations that determine Effect Size: the difference is significant - but is it big?.
Source-complete notespractice

practice

  • d > 0.5 → worth implementing
  • d = 0.2–0.5 → depends on the cost of change
  • d < 0.2 → most likely not worth it
  • for win-rate: OR / relative lift as effect size
14A/B testPower Analysis: how many examples do you need?1 source note

Power (test power) - the probability of detecting a real effect if there is one. Power = 1 − β, where β is the probability of missing an improvement (type II error). Standard: power ≥ 0.80. Power analysis answers the question “how many examples are needed” before the experiment?

Source-complete notesformula and example
formula and examplesql
Four related parameters (know 3 → find 4th):
  α (significance level, usually 0.05)
  power (1−β, typically 0.80)
  d (expected effect size)
  n (← what we are looking for)

Minimum n for paired t-test:
from statsmodels.stats.power import TTestPower
analysis = TTestPower()
n = analysis.solve_power(
  effect_size=0.3, # expected Cohen's d
  alpha=0.05,
  power=0.80
)
# → n ≈ 90 examples per group

Empirical guidelines for LLM:
  d=0.5 → n ≥ 34 (large expected effect)
  d=0.3 → n ≥ 90
  d=0.2 → n ≥ 200 (small effect - you need a lot)
15A/B testCorrect setup of an A/B experiment1 source note

Most errors in LLM experiments are not mathematical, but design ones: the test set is chosen incorrectly, systems are compared on different data, or the metric does not correspond to the task.

Source-complete notesdesign checklist
design checklistsql
① Formulate a hypothesis BEFORE the experiment
  "Prompt B gives higher F1 on task X"
not “let’s see what’s best”

② Fix the metric BEFORE the run
  → you cannot select a metric after, based on the best result

Use the SAME test set for A and B
  → paired test, removes variance from the difficulty of questions

④ The test set should not overlap with the dev set
  → otherwise you optimize for a test without knowledge

⑤ Run each system k≥3 times (at T>0)
  → average across runs, estimate σ as a function of temperature

⑥ Calculate n using power analysis IN ADVANCE
  → don't stop when p < 0.05 “for the first time”
05

LLM-specific assessment

4 cards
16LLM EvalLLM-as-Judge: Model Evaluator Statistics1 visual1 source note

LLM-as-judge is itself a stochastic process with variance. Before trusting his assessments, you need to measure the consistency of the judge with yourself and with people. Only then can the results be interpreted as a metric.

Visual model · Formula mapConnect the quantities and operations that determine LLM-as-Judge: Model Evaluator Statistics.
Source-complete notespractice

practice

  • validate judge on ~100 human-labeled examples
  • average 3+ runs of judge at T>0
  • set judge T=0 for reproducibility
  • one run judge = not a metric, but a random point
17LLM EvalWin-Rate and its statistics1 source note

Win-rate (the percentage of victories of A over B in pairwise comparisons) is an intuitive metric. But how do you know if the difference 55% vs 45% is significant? This is a problem for a fraction test - the binomial test or chi-square.

Source-complete noteswin-rate significance test
win-rate significance testsql
# 100 comparisons A vs B
wins_B = 58 # B won 58 times
n = 100 # total comparisons
# H₀: p(B wins) = 0.5 (equal systems)

from scipy.stats import binomtest
result = binomtest(wins_B, n, p=0.5,
                  alternative='greater')
print(result.pvalue) # → 0.044 → significant!

# CI for win-rate (Wilson interval):
from statsmodels.stats.proportion import proportion_confint
ci = proportion_confint(wins_B, n, method='wilson')
# → (0.483, 0.671)

Minimum significant difference=0.05):
  n=50 → win-rate > 64% significant
  n=100 → win-rate > 59% significant
  n=200 → win-rate > 56% significant
18LLM EvalElo Rating for models1 source note

When comparing more than two systems, pairwise win-rates are not transitive. Elo-rating (from chess) solves this problem: each win/loss updates the rating taking into account the expected result. Used in Chatbot Arena (LMSYS).

Source-complete notesElo mechanics
Elo mechanicstext
# Expected probability of A winning over B:
E_A = 1 / (1 + 10^((R_B − R_A) / 400))

# Rating update after A vs B match:
# S_A = 1 (win), 0.5 (draw), 0 (loss)
R_A_new = R_A + K (S_A − E_A)
#K = learning factor (usually 32)

Initial rating: 1000 for everyone
Difference 400 → expected ~10% wins for the weakest

Bootstrap CI for Elo (Chatbot Arena approach):
→ resample paired matches 1000 times
→ recalculate Elo for each bootstrap
→ 95% CI by percentiles
19LLM EvalAggregate Score: when the average deceives1 visual

An average score across multiple tasks/benchmarks masks uneven quality. A model can perform well on 9 out of 10 problems and fail on the 10th - the average score still looks good.

Visual model · Formula mapConnect the quantities and operations that determine Aggregate Score: when the average deceives.
06

Pitfalls in Evaluating LLM Systems

3 cards
20TrapsData Contamination, Benchmark Overfitting and Goodhart's Law1 visual

The three most dangerous pitfalls when evaluating LLM: test data leaked into training, the metric no longer reflects real quality, or the model is “tailored” for a benchmark. All three make the comparison meaningless.

Visual model · Process flowFollow the sequence behind Data Contamination, Benchmark Overfitting and Goodhart's Law and locate where work or state changes.
Complete view · 3 layers
21TrapsJudge's biases: attitude and verbosity1 source note

LLM-judge systematically distorts scores in favor of the first or second answer (positional bias) and in favor of longer answers (verbosity bias) - regardless of the quality of the content.

Source-complete notestypes of displacements and protection
types of displacements and protectionsql
Positional bias:
  judge([A, B]) → A wins 65% of the time
  judge([B, A]) → B wins 62% of the time
  → the first one wins both times!
  Defense: Always run in both orders
  Result: win only if you win in BOTH runs
  or take the average if there is a draw

Verbosity bias:
  judge prefers a longer answer
  even if it's less accurate
  Defense: explicitly in the judge prompt: “length is not a criterion”
  Defense: normalize the score by the length of the answer

Self-enhancement bias:
  Claude judge overestimates Claude answers
  GPT-4 judge overestimates GPT-4 responses
  Protection: use judge from another provider
22TrapsPrompt Sensitivity: assessment instability1 source note

A difference in the formulation of a prompt by ±10% of the metric is a common phenomenon. This means that “comparing systems” without prompt control is actually “comparing prompts.” The result depends on who wrote the better prompt for their system.

Source-complete noteshow to control
how to controltext
Antipattern:
  System A: Prompt v7 (carefully written)
  System B: prompt v1 (draft)
  → you compare the quality of prompting, not systems

That's right - fix the prompt template:
  one template for both systems
  vary ONLY the parameter being studied

Or - multi-prompt evaluation:
  k=5 prompt options for each system
  estimate = mean ± std for all options
  → you evaluate robustness, not a point result

Sensitivity measurement:
  CV = std/mean (coefficient of variation)
  CV > 0.1 → system is unstable to formulation
07

Practice: Checklist and Rules

2 cards
23PracticeChecklist for a statistically valid LLM experiment1 visual

Go through this list before and after launch. If at least one point is missed, the conclusions are questionable.

Visual model · ComparisonContrast the alternatives in Checklist for a statistically valid LLM experiment under the same frame.
Complete view · 4 layers
24PracticeQuick Reference: Method Selection2 source notes

Quick cheat sheet: which statistical method to use in typical LLM scenarios.

Source-complete notestable · minimum stack
TaskMethodPython
Compare 2 promptspaired t-testttest_rel(a, b)
Ratings 1–5 from judgeWilcoxonwilcoxon(a, b)
Win-rate significanceBinomial testbinomtest(w, n)
CI for any metricBootstrapbootstrap((x,), np.mean)
Compare N systemsElo + bootstrap CIelo_mle() + resample
N prompts → choosing the best+ Bonferronimultipletests(p_vals)
Judge vs human agreementSpearman ρ / Cohen κspearmanr / cohen_kappa
How many examples do you need?Power analysisTTestPower().solve_power

minimum stack

  • scipy.stats
  • statsmodels
  • numpy (bootstrap)
  • ragas (for RAG metrics)

No dead end

Keep moving through the map.

Continue in sequence, switch to a related guide, or return to the seven-track learning map.

Discovery graph / next reads

Continue through New Runtime

Open the graph
  1. 01learning trackMl And Decision SystemsOpen the complete learning track.
  2. 02related materialBERT, Encoders & Non-Generative ModelsContinue with another guide in this learning track.
  3. 03related materialClassical Machine Learning in Plain EnglishContinue with another guide in this learning track.
  4. 04related materialForecasting, Causal Inference & BanditsContinue with another guide in this learning track.
  5. 05related materialAdvanced RAG: Context & EnrichmentContinue with a related New Runtime material.

These links are also published in this page’s JSON twin and as typed edges in DiscoveryGraph v1.

Who read this page?Machine requests, hidden until opened

Loading the privacy-safe route aggregate…

Open the JSON contract