GenAI Course · Module 2 · Session 8

Word Embeddings

⏱ 14 min read🎯 Intermediate🖼 4 diagrams🧪 1 live demo🐍 Python code

Counting words (Session 7) cannot see that “UPI” and “card” are both payment methods. Word embeddings fix this: each word becomes a short list of numbers, learned so that words used in similar contexts get similar numbers. This one idea is the foundation of everything from search to LLMs.

In this session

  • The idea: “you shall know a word by the company it keeps”
  • Word2Vec: CBOW vs skip-gram
  • Training a real Word2Vec model and checking similarities
  • GloVe: learning from global co-occurrence counts
  • Cosine similarity and the famous king − man + woman ≈ queen

01Meaning from context

Linguist J. R. Firth wrote in 1957: “You shall know a word by the company it keeps.” If “UPI” and “card” keep appearing in the same kinds of sentences (“paid via ___”, “the ___ payment failed”), they probably mean similar things.

2-D picture of an embedding space (illustration)upicardnetbankingwalletmumbaipunedelhichennaibiryanidosasamosaidlipayment methodscitiesfoods
Words used in similar contexts end up close together. Real embeddings have 50–3,000 dimensions; this is a 2-D sketch.
One-hot / BoW• 50,000+ numbers, mostly 0• every word equally distant• no meaningEmbeddings• 50–300 dense numbers• similar words are close• meaning learned from data
Dense embeddings pack meaning into a few hundred numbers.

02Word2Vec: CBOW and skip-gram

Word2Vec (Google, 2013) trains a very small neural network on a fake task. The word vectors it learns along the way are what we actually want. It comes in two flavours:

CBOW• context → middle word• “customer paid via ___ today”• faster to train• good for frequent wordsSkip-gram• middle word → its context• “upi” → paid, via, today• slower• better for rare words
CBOW guesses a word from its neighbours; skip-gram guesses the neighbours from a word.

We train both on 3,000 short sentences about payments, cities and food. Watch which words the model puts next to “upi”:

word2vec_toy.py
# pip install gensim
import random
from gensim.models import Word2Vec

random.seed(0)
methods = ["upi", "card", "netbanking", "wallet"]
cities = ["mumbai", "pune", "delhi", "chennai"]
foods = ["biryani", "dosa", "samosa", "idli"]
templates = ["customer paid via {m} today", "the {m} payment was successful", "refund sent to the {m} account",
             "she lives in {c} city", "flights to {c} are cheap", "the office in {c} is open",
             "he ordered {f} for lunch", "the {f} was hot and tasty", "we ate {f} at the stall"]
sentences = []
for _ in range(3000):
    t = random.choice(templates)
    sentences.append(t.format(m=random.choice(methods), c=random.choice(cities), f=random.choice(foods)).split())

for name, sg in [("CBOW", 0), ("Skip-gram", 1)]:
    model = Word2Vec(sentences, vector_size=30, window=3, min_count=1, sg=sg, epochs=20, seed=1, workers=1)
    print(f"{name}: most similar to 'upi' ->", [w for w, _ in model.wv.most_similar("upi", topn=3)])
    print(f"{name}: similarity(upi, card) = {model.wv.similarity('upi', 'card'):.2f}, "
          f"(upi, dosa) = {model.wv.similarity('upi', 'dosa'):.2f}")
print("vector size:", model.wv["upi"].shape)
CBOW: most similar to 'upi' -> ['netbanking', 'wallet', 'card'] CBOW: similarity(upi, card) = 0.99, (upi, dosa) = 0.18 Skip-gram: most similar to 'upi' -> ['netbanking', 'card', 'wallet'] Skip-gram: similarity(upi, card) = 1.00, (upi, dosa) = 0.26 vector size: (30,)

Nobody told the model that UPI, card, netbanking and wallet are payment methods. It learned it purely from the sentences around them. “upi” and “dosa” never share a context, so their similarity is low.

This toy corpus is tiny and very regular, so similarities look extreme. Real Word2Vec models train on billions of words; the classic Google News model has 3 million words with 300 numbers each.

03GloVe

GloVe (Stanford, 2014) reaches similar vectors a different way. It first counts, over the whole corpus, how often each pair of words appears near each other (a big co-occurrence table), then learns vectors whose dot products match those counts (in log form).

paymentpaidfailedtastylunchupi120954001card110883500dosa0206075
Co-occurrence counts (illustrative): rows with similar patterns get similar vectors.
Word2VecGloVe
Learns fromlocal windows, one sentence at a timeglobal co-occurrence counts
Trainingpredict words (neural network)factorise the count table
Pre-trained setsGoogle News (300-d)glove.6B (50–300-d, 400K words)
Resultsimilar quality in practicesimilar quality in practice

04Cosine similarity and semantic distance

To compare two embeddings we use cosine similarity: the cosine of the angle between the vectors. 1 = same direction (same meaning), 0 = unrelated, −1 = opposite.

cosine(a, b) = (a · b) / (|a| × |b|)
cosine.py
import numpy as np

def cosine(a, b):
    return a @ b / (np.linalg.norm(a) * np.linalg.norm(b))

# toy 4-number "embeddings": [royalty, male, female, fruit]  (made up for illustration)
v = {"king":  np.array([0.9, 0.8, 0.1, 0.0]), "queen": np.array([0.9, 0.1, 0.8, 0.0]),
     "man":   np.array([0.1, 0.9, 0.1, 0.0]), "woman": np.array([0.1, 0.1, 0.9, 0.0]),
     "apple": np.array([0.0, 0.1, 0.1, 0.9])}

print(f"king vs queen: {cosine(v['king'], v['queen']):.2f}")
print(f"king vs apple: {cosine(v['king'], v['apple']):.2f}")

target = v["king"] - v["man"] + v["woman"]
best = max((w for w in v if w not in ("king", "man", "woman")), key=lambda w: cosine(target, v[w]))
print("king - man + woman ≈", best, f"(cosine {cosine(target, v[best]):.2f})")
king vs queen: 0.66 king vs apple: 0.08 king - man + woman ≈ queen (cosine 0.99)

Embeddings can even do “maths with meaning”: king − man + woman lands closest to queen. In real Word2Vec models this works for many relations, such as Paris − France + Italy ≈ Rome, though not perfectly.

Demo · How similar are these?
The big limitation: each word gets one vector, whatever the sentence. “bank” in “river bank” and “bank account” share the same numbers. Transformers (Modules 5–7) fix this with contextual embeddings.

05Summary

06Quick quiz

1. Word embeddings put which words close together?

2. Skip-gram predicts…

3. GloVe learns from…

4. A cosine similarity of about 0 means…

5. What problem do static embeddings like Word2Vec have?

07References

Created by Ajeetkumar