Graph connections

Draft

Recall

Measure how many real positives were found by the model.

concept beginner machine-learningmetricsclassification

Hook problem: did we catch enough real spam?

Your model evaluated 12 emails. You care about one question:

Of the real positives, how many were caught?

From 12 messages to 6 actual spamRecall only asks about what was really positive, so the denominator is fixed to actual spam rows.
e1

Prize claim now

Obvious prize bait caught by the filter.

actual: spam, predicted: spam (TP: True Positive)

e2

Project notes

A normal work message left in the inbox.

actual: not-spam, predicted: not-spam (TN: True Negative)

e3

Receipt attached

A real receipt incorrectly flagged as spam.

actual: not-spam, predicted: spam (FP: False Positive)

e4

Account alert

A fake alert slipped into the inbox.

actual: spam, predicted: not-spam (FN: False Negative)

e5

Limited offer

Promotional spam correctly blocked.

actual: spam, predicted: spam (TP: True Positive)

e6

Team lunch

A casual team email correctly kept.

actual: not-spam, predicted: not-spam (TN: True Negative)

e7

Password reset

A requested reset email reached the user.

actual: not-spam, predicted: not-spam (TN: True Negative)

e8

Urgent transfer

A scam message was missed by the filter.

actual: spam, predicted: not-spam (FN: False Negative)

e9

Flight update

A useful travel update became a false alarm.

actual: not-spam, predicted: spam (FP: False Positive)

e10

Crypto bonus

Suspicious bonus spam correctly caught.

actual: spam, predicted: spam (TP: True Positive)

e11

Invoice approved

A business invoice correctly accepted.

actual: not-spam, predicted: not-spam (TN: True Negative)

e12

Verify wallet

A phishing-style wallet email was missed.

actual: spam, predicted: not-spam (FN: False Negative)

Recall denominator summary

actual positives = TP + FN = 6

TP ids: e1, e5, e10

FN ids: e4, e8, e12

First naive idea: reuse accuracy

If you still use global correctness:

TP+TNTP+FP+TN+FN=3+412=712\frac{TP + TN}{TP + FP + TN + FN} = \frac{3 + 4}{12} = \frac{7}{12}

This measures overall correctness. It says nothing about coverage of real spam.

Why it hurts: FN examples are invisible to that denominator

e4, e8, and e12 are all real spam but missed by the model (FN):

  • e1: caught spam (TP)
  • e4: missed spam (FN)
  • e5: caught spam (TP)
  • e8: missed spam (FN)
  • e10: caught spam (TP)
  • e12: missed spam (FN)

So for recall, denominator is TP + FN = 6, not all 12.

Accuracy vs recall contrastAccuracy uses all 12 predictions; recall uses only actual spam examples.
Accuracy question

All 12 predictions are in scope.

Numerator = TP + TN = 7

Accuracy = 7 / 12 = 58.3%

Recall question

Only actual-positive examples are in scope.

Denominator = TP + FN = 6

Numerator = TP = 3

Recall = 3/6 = 0.5

Outside recall denominator

Actual negatives (6): e3, e9, e2, e6, e7, e11

Core invention: read the actual-positive row

The matrix orientation is fixed:

actual rows, predicted columns\text{actual rows},\ \text{predicted columns}

Recall reads only one row:

recall=TPTP+FN\text{recall} = \frac{TP}{TP + FN}

For this fixture:

TPTP+FN=33+3=36=0.5\frac{TP}{TP + FN} = \frac{3}{3 + 3} = \frac{3}{6} = 0.5
Actual-positive matrix rowRows are actual labels, columns are predictions. Recall reads the actual-positive row: TP + FN.

Positive-label orientation: rows are actual, columns are predicted.

Actual-positive row (row-level view)
actual \ predictedpredicted spampredicted not-spam
actual spamTP (3): e1, e5, e10FN (3): e4, e8, e12

Recall reads TP + FN = 6.

Numerator / denominator splitFor this fixture, caught spam is `TP`, and all real spam is `TP + FN`.
Numerator (caught real spam)

TP from the actual-positive row.

3 (e1, e5, e10)

Denominator (all actual spam)

TP + FN from the actual-positive row.

6 (e1, e5, e10, e4, e8, e12)

Result

Recall = 3/6 = 0.500

Meaning: 3 out of 6 real spam were caught.

Interactive trace: actual-positive step-by-step

The interactive demo now shows only e1, e4, e5, e8, e10, e12 in fixture order, and one row of the running recall after each row.

Recall over actual spam

e1: Prize claim now. Actual spam, Predicted spam. Cell: TP (True Positive). Caught positives 1/1, Running recall: 1.0.

Step

1/6

Subject

Prize claim now

Current id

e1

Actual

spam

Predicted

spam

Cell

TP (True Positive)

Caught positives

1/1

Running recall

1.0

percent: 100.0%

Final fixture value

3/6 = 0.5

Recall trace over actual-positive emails (no-JS fallback)
StepEmailSubjectCellCaughtActual positives seenRunning recallActualPredicted
1e1Prize claim nowTP (True Positive)111/1 = 1.0spamspam
2e4Account alertFN (False Negative)121/2 = 0.5spamnot-spam
3e5Limited offerTP (True Positive)232/3 = 0.667spamspam
4e8Urgent transferFN (False Negative)242/4 = 0.5spamnot-spam
5e10Crypto bonusTP (True Positive)353/5 = 0.6spamspam
6e12Verify walletFN (False Negative)363/6 = 0.5spamnot-spam

If JavaScript is unavailable, use this ledger:

Recall trace over actual spam emails (no-JS fallback)
StepEmailSubjectActualPredictedCellCaught positivesActual positives seenRunning recall
1e1Prize claim nowspamspamTP111/1 = 1
2e4Account alertspamnot-spamFN121/2 = 0.5
3e5Limited offerspamspamTP232/3 = 0.667
4e8Urgent transferspamnot-spamFN242/4 = 0.5
5e10Crypto bonusspamspamTP353/5 = 0.6
6e12Verify walletspamnot-spamFN363/6 = 0.5

Missed-spam pain (what recall protects)

Recall stays honest because it measures missed real positives directly.

Missed spam painFalse negatives are outside the actual-positive numerator but inside the denominator because they were real positives.
e4

Account alert

A fake alert slipped into the inbox.

actual: spam, predicted: not-spam (FN: False Negative)

e8

Urgent transfer

A scam message was missed by the filter.

actual: spam, predicted: not-spam (FN: False Negative)

e12

Verify wallet

A phishing-style wallet email was missed.

actual: spam, predicted: not-spam (FN: False Negative)

Why it hurts

These are real spam emails that were not caught.

Missed count: 3

Recall denominator check

Each missed sample still contributes to the denominator.

Formula: TP + FN.

Zero-denominator convention

If there are no real positives in the evaluated set:

  • TP = 0
  • FN = 0
  • TP + FN = 0
  • internal value: null
  • rendered value: not available
Zero-denominator edge caseWhen there is no actual-positive example, recall is undefined and rendered as not available.
Zero-denominator convention table
CaseTPFNDenominator (TP + FN)Internal valueRendered
No actual positives000nullnot available

Implementation sketch

interface RecallCounts {
  tp: number;
  fn: number;
}

function recallFromCounts(counts: RecallCounts) {
  const denominator = counts.tp + counts.fn;
  if (denominator === 0) {
    return { numerator: counts.tp, denominator, value: null };
  }
  return { numerator: counts.tp, denominator, value: counts.tp / denominator };
}
Implementation branch tableKeep the same scan or counts, then branch on denominator zero before formatting.
Recall implementation branch
StepNumerator (tp)Denominator (tp + fn)BranchResult
1tptp + fnif denominator==0null
2tptp + fnelsetp / (tp + fn)

Correctness intuition

Each actual-positive example is exactly one of:

  • TP: actual spam and predicted spam (caught)
  • FN: actual spam and predicted not-spam (missed)

So TP + FN is exactly the set of real spam. It must equal 6 here.

InvariantValue
TP + FN from final counts6
Final TP3
Final FN3
Final recall3 / (3 + 3)

Complexity

  • If counts already exist: O(1) to compute recall from {tp, fn}.
  • If scanning examples directly: O(n) time and O(1) extra space.
Common confusionsRecall is a coverage metric over real positives, not a trust metric over alarms.
Not accuracy

Accuracy counts true negatives too; recall ignores TN/FP.

Not a raw count

3 caught is not enough; denominator must be all real spam.

Precision contrast

Precision asks: of predicted positives, how many were correct?

Recall asks: of real positives, how many were caught?

Graph connection

Recall is built from the confusion-matrix actual-positive row and can be contrasted with precision.

Graph stripRecall is implemented from confusion-matrix and can optionally be contrasted with precision.
confusion-matrix

implemented

recall

implemented

precision (contrast)

contrast

Exercises

  1. Why is 7 / 12 not a recall score?
  2. What is the recall denominator in this fixture and why?
  3. Compute the running recall after e8.
  4. Explain what should render when denominator is 0.
  5. Which examples are FN, and why do they affect recall?
Final reference
TP + FN = 3 + 3 = 6, final recall is 3 / 6 = 0.5, which is 50%.
Actual-spam set
e1, e4, e5, e8, e10, e12

Graph connections : Recall