A spam filter labels n e-mails: 1 = spam (positive), 0 = not spam. Given the true labels and the predicted labels, print the confusion matrix counts and four metrics with 4 decimals:
- accuracy = (TP + TN) / n
- precision = TP / (TP + FP)
- recall = TP / (TP + FN)
- F1 = 2·TP / (2·TP + FP + FN)
If a denominator is 0, print 0.0000 for that metric.
Constraints
- 1 ≤ n ≤ 5000
Input and output
- Input
- First line: n. Second line: n true labels (0/1). Third line: n predicted labels (0/1).
- Output
- Line 1: `TP FP FN TN` as four integers. Then `accuracy X`, `precision X`, `recall X`, `f1 X`.
Examples
Input 1
8
1 1 1 0 0 0 0 1
1 0 1 0 1 0 0 1Output
3 1 1 3
accuracy 0.7500
precision 0.7500
recall 0.7500
f1 0.7500TP = 3, FP = 1, FN = 1, TN = 3. Precision = 3/4, recall = 3/4, F1 = 0.75.
Input 2
5
1 0 0 0 0
0 0 0 0 0Output
0 0 1 4
accuracy 0.8000
precision 0.0000
recall 0.0000
f1 0.0000The model never predicts spam: accuracy is 0.8, but precision, recall and F1 are all 0.
Show hints
- Count the four (actual, predicted) combinations in one loop.
- F1 is the harmonic mean of precision and recall. 2TP / (2TP + FP + FN) is the same value and needs no special case when P = R = 0.
Show the explanation
Confusion matrix (rows are the actual class, columns the predicted class):
| predicted 1 | predicted 0 | |
|---|---|---|
| actual 1 | TP | FN |
| actual 0 | FP | TN |
One loop fills it: TP += a == 1 and p == 1, and so on.
Metrics
- Precision: of the e-mails we flagged, how many were really spam? Low precision means good mail lands in the spam folder.
- Recall (sensitivity): of the actual spam, how much did we catch?
- F1 = 2PR / (P + R), the harmonic mean. It is high only when both are high. The form 2TP / (2TP + FP + FN) is algebraically the same and avoids a 0/0.
- Accuracy misleads on imbalanced data. If 1% of transactions are fraud, a model that always says "not fraud" is 99% accurate and has 0 recall.
Zero denominators. A model that never predicts positive has TP + FP = 0, so precision is undefined. scikit-learn's precision_score then returns 0 and warns, unless you set zero_division. Printing 0.0000 here copies that convention.
Threshold trade-off. Raising the decision threshold usually increases precision and lowers recall. The precision–recall curve (or ROC/AUC) summarises every threshold at once.
Original UniCircle question. Last reviewed 22 Oct 2026.
