# Precision, recall and F1, explained with moderation examples

> Accuracy hides the problem. What precision, recall and F1 measure, how to compute them in 30 seconds and which one matters for your community.

Source: https://www.vigimod.com/en/learn/precision-recall-f1 · VigiMod (https://www.vigimod.com) · updated 2026-11-11 · 7 min

## In short

- Accuracy is misleading when harmful messages are rare: “flag nothing” can be 98% accurate.
- Precision: of the messages flagged, how many were really harmful.
- Recall: of the harmful messages, how many were caught.
- F1 combines the two: it is high only when both are high.

## Why accuracy is not enough

Imagine 1,000 chat messages, 20 of which are insults. A model that **never flags anything** is right 980 times out of 1,000: **98% accuracy**, and completely useless. When the thing you look for is rare, accuracy hides the problem. That is why moderation is measured with **precision** and **recall**.

## The four boxes

Every decision falls in one of four boxes:

| | Really harmful | Really harmless |
|---|---|---|
| **Flagged** | true positive (TP) | false positive (FP) |
| **Not flagged** | false negative (FN) | true negative (TN) |

A **false positive** is an innocent message flagged by mistake; a **false negative** is a harmful message that slipped through. They have different costs, explained in [false positives and false negatives](https://www.vigimod.com/en/learn/false-positives-and-false-negatives).

## Precision

> Precision = TP / (TP + FP)

Of everything the model flagged, how much was really harmful? Low precision means **many false alarms**: your moderators waste time and your users get annoyed.

## Recall

> Recall = TP / (TP + FN)

Of all the harmful messages, how many did the model catch? Low recall means **many misses**: harmful content stays in the chat.

## A worked example

Out of 1,000 messages, 20 are insults. The model flags 25 messages: 18 are real insults, 7 are innocent.

- TP = 18, FP = 7, FN = 20 − 18 = 2
- Precision = 18 / 25 = **0.72**
- Recall = 18 / 20 = **0.90**

The model catches almost every insult, but about one flag in four is a false alarm.

## F1: one number for both

> F1 = 2 × precision × recall / (precision + recall)

F1 is the *harmonic mean* of the two: it is high only when **both** are high. In the example, F1 = 2 × 0.72 × 0.90 / 1.62 ≈ **0.80**. A model with precision 1.0 and recall 0.1 has an F1 of only 0.18, even if the average of the two is 0.55.

## Which one matters for you?

- A **children's game** may want very high recall: missing a grooming attempt is far worse than a few false alarms reviewed by a person.
- A **gaming community full of banter** may want high precision: flagging every friendly “you're trash at this game” would drive people away.

You move between the two with the [threshold](https://www.vigimod.com/en/learn/choosing-a-threshold): lower it and recall goes up, precision goes down; raise it and the opposite happens.

## Average precision (AP)

F1 depends on the threshold you chose. **Average precision** summarises the model at every threshold at once: it tells you how well the scores separate harmful from harmless messages, independently of where you put the line. It is useful to compare two models fairly.

## A note on the “truth”

All these numbers compare the model with labels written by people, and people disagree, especially on hate speech and irony. If the test labels are wrong, even a perfect model gets a lower score. That is why serious evaluations re-check their test sets (see [training data and labels](https://www.vigimod.com/en/learn/training-data-and-labels)).

## Quiz

1. 1,000 messages, 10 harmful. A model that never flags anything has accuracy…
   Answer: 99%. It is right on the 990 harmless ones: high accuracy, zero usefulness.
2. Precision answers the question…
   Answer: Of the flagged messages, how many were really harmful?. Precision = TP / (TP + FP).
3. The model catches 30 of 40 harmful messages. Recall is…
   Answer: 0.75. 30 / 40 = 0.75.
4. Precision 1.0 and recall 0.1. F1 is about…
   Answer: 0.18. F1 = 2 × 1.0 × 0.1 / 1.1 ≈ 0.18: it is high only when both are high.
