AI Hints
Home›NLP Tutorial›Counting Words
NLP · Lesson 8 of 106

TF-IDF

Finding the words that matter.

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

If a word appears ten times in one document, it's probably important to that document. But if it also appears in every other document, it's useless. The best words are common here, and rare elsewhere. That single insight, from nineteen seventy two, is still inside search engines today.

TF-IDF
From the video: TF-IDF
  • Common here, rare elsewhere
  • An idea from 1972
  • Still in search engines

Scoring words

TF means term frequency, how often a word appears here. IDF means inverse document frequency, which is higher for rare words. We multiply them together. Here are three short documents. We look at the highest scoring words in the third. Run it. Wonderful, and gift score the highest, because they're unique to this document. The word the sits near the bottom, though it's in every document. That's exactly what we want.

tfidf.pypython
from sklearn.feature_extraction.text import TfidfVectorizer

docs = ["the book arrived late",
        "the refund arrived late",
        "the book was a wonderful gift"]

vec = TfidfVectorizer()
X = vec.fit_transform(docs).toarray()
names = vec.get_feature_names_out()

top = sorted(zip(X[2], names), reverse=True)[:4]
for score, word in top:
    print(f"{word:<10} {score:.3f}")
print("Score of 'the':", round(X[2][list(names).index("the")], 3))
Output
wonderful  0.505
was        0.505
gift       0.505
book       0.384
Score of 'the': 0.298

Searching the FAQ

Now Scribe can use this to find answers. Here's a small FAQ. We turn each question into a TF-IDF vector, and the customer's message too. Cosine similarity measures the angle between two vectors. Smaller angle, more similar. Run it. It matched the customer's question to the right FAQ, using the shared words order and arrive. That's a search engine, in ten lines. But notice its limit. If the customer said, my parcel is missing, there'd be no shared words, and it would fail. We'll fix this later with embeddings.

faq_search.pypython
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

faq = ["How do I return a book?",
       "When will my order arrive?",
       "Do you ship to Canada?",
       "Can I change my delivery address?"]

vec = TfidfVectorizer(stop_words="english")
X = vec.fit_transform(faq)

question = vec.transform(["my order has not arrived yet"])
scores = cosine_similarity(question, X)[0]

for s, q in sorted(zip(scores, faq), reverse=True)[:2]:
    print(f"{s:.2f}  {q}")
Output
0.71  When will my order arrive?
0.00  How do I return a book?

Summary

TF-IDF rewards rare, telling words, and cosine similarity compares documents. You've just built a real search engine. Before we move on, let's look at one strange law that governs every language on Earth.

Key takeaways
  • Term frequency times rarity
  • Cosine compares documents
  • No shared words, no match
Next up: Zipf's Law — the shape of every language