AI Hints
Home›NLP Tutorial›Evaluation and Extraction
NLP · Lesson 13 of 106

Evaluating Text Models

The traps of measuring language.

⏱ 2 min read▶ Video at 23:55🎓 Free
Watch this lesson in the NLP courseWatch on YouTube ↗Full NLP course

Scribe scores ninety percent. Is that good? It depends. What if the rare legal threats, the most important messages of all, are the ones it misses? And here's a stranger question. Do even humans agree on the right answer?

Evaluating Text Models
From the video: Evaluating Text Models
  • Ninety percent. Is that good?
  • What about rare legal threats?
  • Do humans even agree?

Reading a report

Here's a typical result. Ten messages, and most are delivery problems. Accuracy looks fine at eighty percent. But now read the report, class by class. Legal has a recall of zero. Scribe missed the only legal threat. Macro average treats all classes equally, so it reveals this kind of failure. Weighted average hides it. For rare but important classes, always read each row.

report.pypython
from sklearn.metrics import classification_report, confusion_matrix

truth = ["delivery"] * 6 + ["refund"] * 3 + ["legal"] * 1
pred  = ["delivery"] * 6 + ["refund"] * 2 + ["delivery"] + ["delivery"]

print(classification_report(truth, pred, zero_division=0, digits=2))
Output
              precision    recall  f1-score   support

    delivery       0.75      1.00      0.86         6
       legal       0.00      0.00      0.00         1
      refund       1.00      0.67      0.80         3

    accuracy                           0.80        10
   macro avg       0.58      0.56      0.55        10
weighted avg       0.75      0.80      0.75        10

Do humans agree?

Text labels come from people, and people disagree. Is this message angry, or just firm? Two labellers annotate the same eight messages. Plain agreement is seventy five percent. But two people flipping coins would also agree half of the time. Cohen's kappa corrects for chance. Run it. Kappa is well below the plain number. A good rule of thumb. If your humans only agree seventy five percent of the time, then no model can honestly be expected to reach ninety five. Always measure this first.

agreement.pypython
from sklearn.metrics import cohen_kappa_score

alice = ["angry", "fine", "angry", "fine", "angry", "fine", "fine", "angry"]
bilal = ["angry", "fine", "fine",  "fine", "angry", "angry", "fine", "angry"]

same = sum(a == b for a, b in zip(alice, bilal)) / len(alice)
print(f"Plain agreement: {same:.2f}")
print(f"Kappa:           {cohen_kappa_score(alice, bilal):.2f}")
Output
Plain agreement: 0.75
Kappa:           0.50

Summary

Read each class, and measure how far your humans agree. Those two habits will save you from fooling yourself. Scribe can sort and feel. Next, it learns to pull out the facts. Who, what, where, and when.

Key takeaways
  • Read per-class results
  • Macro average shows rare classes
  • Measure human agreement
Next up: Named Entity Recognition — finding people, places, and things