Seven metrics across four families; here we cover how each one works — the pseudocode, and interactive demos.
precision = TP / (TP + FP) # of what I flagged, how much was right recall = TP / (TP + FN) # of what existed, how much I found F1 = 2 · P · R / (P + R) # harmonic mean — punishes imbalance accuracy = (TP + TN) / total # can mislead on skewed classes
# Suppose the sentence is: # "I love NLP" H = 0 for each word wi in the sentence: # Model predicts the next word from previous words # Example: # P(I) = 0.50 # P(love | I) = 0.20 # P(NLP | I love) = 0.10 H += -log2( P(wi | previous words) ) H = H / N # Average surprisal (cross-entropy) PP = 2^H # Convert average surprisal into perplexity
Type a sentence. A small toy model assigns each word a probability given the words before it, and those combine into a perplexity.
for n in 1..4: pₙ = clipped_matches(cand, ref, n) / total_ngrams(cand, n) BP = 1 if c > r else exp(1 − r/c) # brevity penalty (c,r = cand/ref lengths) BLEU = BP · exp( (1/4) · Σ log pₙ ) # geometric mean of precisions function clipped_matches(cand, ref, n): # Count all n-grams in the candidate and reference. # Example (n = 1): # cand = "the the the" # ref = "the cat the" # cand_counts = {"the": 3} # ref_counts = {"the": 2, "cat": 1} cand_counts = count_ngrams(cand, n) ref_counts = count_ngrams(ref, n) matches = 0 for each ngram in cand_counts: matches += min(cand_counts[ngram], ref_counts[ngram]) # "the": min(3, 2) = 2 return matches function total_ngrams(cand, n): # Count all candidate n-grams. return count_ngrams(cand, n).total_count()
ROUGE-N recall = overlap_ngrams(cand, ref, n) / total_ngrams(ref, n) ROUGE-N prec. = overlap_ngrams(cand, ref, n) / total_ngrams(cand, n) LCS = longest_common_subsequence(cand, ref) ROUGE-L recall = LCS / len(ref), prec = LCS / len(cand)
prompt = rubric + criteria + the_output_to_grade scores = LLM(prompt) # e.g. {relevance:4, accuracy:5, ...} on 1–5 overall = Σ wᵢ · scoreᵢ # weighted aggregate # pairwise variant: ask "is A or B better?" — average over both orderings to cancel position bias.
A candidate answer graded against a reference. The prompt below is the real text an LLM would receive and updates as you type; the response is a frozen example for the default pair (we do not call a model).
# each annotator scores every criterion from 1-5 overall = Σ wᵢ · scoreᵢ # weighted mean, per annotator final = mean(overall over annotators) # average across people # also report inter-annotator agreement (e.g. Cohen's κ)
Play the annotator: rate the candidate against the reference on each criterion. Weights reflect a typical rubric. (Compare your verdict with the LLM judge's above — humans and models often differ.)