Skip to main content
In this lesson we demonstrate two common document retrieval approaches using a small automotive troubleshooting corpus:
  • Keyword search (TF-IDF) with Whoosh
  • Semantic retrieval using SentenceTransformers + cosine similarity
We’ll build a tiny corpus, run both methods on the same query, and compare the ranked results side-by-side so you can see how exact-match ranking (TF-IDF) and meaning-based retrieval (embeddings) differ. Keywords: TF-IDF, semantic search, embeddings, Whoosh, SentenceTransformers, cosine similarity Prerequisites (run once):
Corpus and titles used in this lesson:
SentenceTransformers will download model weights on first use. If you’re running this in a restricted environment, pre-download models or set SENTENCE_TRANSFORMERS_HOME to a writable cache folder. For larger corpora consider batching embeddings to avoid memory spikes.

1) Keyword search with Whoosh (TF-IDF)

Whoosh is a pure-Python search library that indexes documents and computes TF-IDF style relevance under the hood. The example below creates a temporary Whoosh index, adds our documents, and runs a simple keyword query. Whoosh matches query terms and ranks results by term frequency / inverse document frequency.
Example Whoosh outputs (your scores may vary slightly):
Notes on Whoosh behavior:
  • Whoosh returns documents where the query terms appear and ranks by TF-IDF-like importance.
  • If a conceptually relevant document doesn’t contain the exact query terms (e.g., “Motor Diagnostics Checklist” for the query “engine troubleshooting”), Whoosh will not return it unless the text contains matching tokens.
This example stores the index in a temporary directory. In production or repeated runs, persist the index directory or rebuild as needed. Remember to clean up temporary files to avoid disk bloat (shutil.rmtree(index_dir)).

2) Semantic search with SentenceTransformers (cosine similarity)

Semantic search embeds documents and queries into a vector space and ranks by vector similarity (cosine). This approach captures conceptual relationships beyond exact token overlap. We use the paraphrase-MiniLM-L6-v2 model for compact, fast embeddings.
Example semantic ranking (scores will vary by model version and environment):
Why semantic search differs:
  • The embedding model captures conceptual similarity, so queries like “engine troubleshooting” will surface “motor diagnostics” and “valve timing” even without exact word overlap.
  • Semantic retrieval improves recall for related documents; TF-IDF provides more precision for literal matches.

3) Compare TF-IDF and Semantic rankings side-by-side

We can combine Whoosh (TF-IDF) hits and SentenceTransformers (cosine similarity) hits into a pandas DataFrame to compare ranks and scores. This lets you directly inspect differences in ordering and the presence/absence of documents in each result set.
Sample comparison table output:
Performance and practical considerations: Interpretation:
  • Whoosh (TF-IDF) excels at precision for literal queries and is simple to run locally.
  • Semantic search returns documents ranked by conceptual relevance and can surface related material that lacks exact tokens from the query.
  • A hybrid approach often works best: use TF-IDF for exact matches and embeddings to expand recall, or rerank TF-IDF candidates with embeddings for a balance of speed and semantic quality.
Conclusion
  • This lesson illustrated the differences between keyword (TF-IDF) search and semantic retrieval using a small corpus.
  • You can run the provided notebook-style code to experiment with queries, model choice, and ranking strategies.
Links and References

Watch Video