NLTK
Named Entity Recognition
NLP
Python
Natural Language Processing

NLTK for Named Entity Recognition

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Named Entity Recognition, or NER, identifies spans such as people, organizations, and locations in text. NLTK provides a classical pipeline that is useful for education, prototyping, and rule-augmented NLP workflows. To get reliable results, you need clear tokenization, part-of-speech tagging, and post-processing rules.

Build the Standard NLTK NER Pipeline

The default NLTK flow is tokenization, POS tagging, then chunking with ne_chunk. This produces a tree where named entities are grouped as labeled subtrees.

python
1import nltk
2
3# Run once in a new environment.
4# nltk.download("punkt")
5# nltk.download("averaged_perceptron_tagger")
6# nltk.download("maxent_ne_chunker")
7# nltk.download("words")
8
9text = "Sundar Pichai visited Toronto to meet teams at Google Canada."
10tokens = nltk.word_tokenize(text)
11pos_tags = nltk.pos_tag(tokens)
12chunk_tree = nltk.ne_chunk(pos_tags)
13
14print(chunk_tree)

For exploratory work, this baseline gives quick visibility into extracted entities. For production workflows, you usually convert tree output into a structured list.

Convert Chunk Trees into Structured Entity Records

Tree output is not ideal for downstream systems. Convert chunks into dictionaries with label, text span, and token offsets where possible.

python
1import nltk
2
3
4def extract_entities(text):
5    tokens = nltk.word_tokenize(text)
6    tags = nltk.pos_tag(tokens)
7    tree = nltk.ne_chunk(tags)
8
9    entities = []
10    for node in tree:
11        if hasattr(node, "label"):
12            label = node.label()
13            phrase = " ".join(token for token, _ in node.leaves())
14            entities.append({"label": label, "text": phrase})
15    return entities
16
17sample = "Barack Obama gave a speech in Berlin for the United Nations."
18print(extract_entities(sample))

This representation is much easier to store, evaluate, and compare across model versions.

Improve Precision with Domain-Specific Post Rules

Classical NLTK models may misclassify domain terms. Add deterministic post-processing rules for your domain vocabulary. For example, if your corpus includes many company suffixes or product names, normalize these patterns after NER extraction.

python
1
2def normalize_entities(entities):
3    normalized = []
4    for ent in entities:
5        text = ent["text"].strip()
6        label = ent["label"]
7
8        if text.endswith("Inc") or text.endswith("Ltd"):
9            label = "ORGANIZATION"
10
11        normalized.append({"label": label, "text": text})
12    return normalized
13
14entities = [
15    {"label": "PERSON", "text": "Acme Ltd"},
16    {"label": "GPE", "text": "Toronto"},
17]
18print(normalize_entities(entities))

This hybrid approach often beats pure model output in specialized datasets with predictable terminology.

Evaluate Before Shipping

Entity extraction quality must be measured. Keep a labeled validation set with expected entities and compute precision and recall periodically. Lightweight evaluation scripts prevent silent regression when tokenization rules or model versions change.

Also monitor failure cases such as nested entities and punctuation-heavy names. Many NER errors are boundary errors rather than wrong labels, so exact-span evaluation matters.

Evaluation and Error Analysis Workflow

For practical NER projects, evaluation discipline matters more than model complexity. Build a small labeled dataset with expected entity spans and labels. After each pipeline change, compute precision and recall by entity type. This reveals whether changes helped organization extraction while harming person extraction, or vice versa. Keep false-positive and false-negative examples in a review notebook and categorize root causes such as tokenization error, label confusion, or boundary mismatch. Then introduce targeted rules or preprocessing fixes for the dominant failure category. Also monitor model behavior on noisy text with punctuation, abbreviations, and mixed casing because real-world inputs often differ from clean training examples. A consistent evaluation loop makes NLTK-based NER far more reliable than ad hoc manual spot checks.

python
1def evaluate(predicted, expected):
2    p = set((e["label"], e["text"]) for e in predicted)
3    t = set((e["label"], e["text"]) for e in expected)
4    tp = len(p & t)
5    precision = tp / len(p) if p else 0.0
6    recall = tp / len(t) if t else 0.0
7    return precision, recall

Common Pitfalls

  • Treating default ne_chunk output as production-ready without evaluation.
  • Ignoring tokenization quality, which directly affects entity boundaries.
  • Storing chunk trees directly instead of normalized records.
  • Skipping domain-specific post rules when corpus terminology is specialized.

Summary

  • Start with the standard NLTK tokenize-tag-chunk pipeline.
  • Convert tree output to structured records for downstream use.
  • Add deterministic post-processing for domain precision.
  • Evaluate with labeled data to track quality over time.
  • Keep NER pipelines testable and versioned.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.