Charan | AI Journey › 01 · Vectors › One-Hot Encoding
⚡ 3D Simulator
AI Journey · Understand Vectors

One-Hot Encoding

The cleanest way to give a model unambiguous categorical identity — a vector of length V with exactly one active position. No fake numeric order, no learned geometry, just a precise pointer into vocabulary space.

🔴 MUST 15 Study Phases Vectors Prerequisite: Why Text Becomes Numbers → Token IDs
🧙‍♂️ The Wise Scholar's Metaphor The Switchboard Selector
⏮️ 00 · Math & Foundations Hub →

One-Hot Encoding: The Single Glowing Lightbulb

Imagine a massive board with 128,000 lightbulbs in the library. When the scholar wants to select token #42, exactly lightbulb #42 switches ON (1) while all 127,999 others stay OFF (0). Dot-multiplying this one-hot vector with the embedding matrix acts as an instantaneous physical selector pulling out row #42. However, because all lightbulb axes are perpendicular, one-hot vectors cannot tell the scholar if "cat" is closer to "dog" than to "airplane".

01

IntroductionWhat is one-hot encoding?

One-hot encoding is the most direct answer to the question: how do you give a model an unambiguous identity for each category in a set? Given a vocabulary of size V, each token or category is represented as a vector of length V where every position is 0 except for exactly one position — the one corresponding to this token — which is 1.

The name comes from digital electronics: a "one-hot" signal is a bus where exactly one wire is high (1) at any given time. In NLP, the "bus" is the vocabulary, and the "high wire" is the token's unique index.

Vocabulary: [cat, dog, fish, bird]   (V = 4)

cat  → [1, 0, 0, 0]
dog  → [0, 1, 0, 0]
fish → [0, 0, 1, 0]
bird → [0, 0, 0, 1]
Key ideas:
  • Exactly one active position per vector — no exceptions.
  • Every vector has the same length V (vocabulary size).
  • There is no semantic relationship encoded — cat and dog are just as "far" from each other as cat and fish.
Token→ Look up ID→ zeros(V)→ x[ID] = 1→ One-hot vector
02

WhyWhy one-hot at all?

The naive alternative — assigning integer IDs (cat=0, dog=1, fish=2, bird=3) and feeding those integers directly into a model — creates an implicit ordering that does not exist. If dog gets ID 1 and fish gets ID 2, the model may infer that fish is "greater than" or "closer to 3" than dog, which is nonsensical. One-hot eliminates this fake numeric order entirely.

🚫 Problem with raw IDs

Integer IDs imply a numeric scale: ID 3 − ID 1 = 2, suggesting "distance". Models using IDs directly will learn spurious relationships from ordinal proximity. The assignment was arbitrary — it should carry zero information.

✅ One-hot advantage

Every token occupies a completely orthogonal axis. The encoding is unambiguous identity, not a position on a scale. The model receives no misleading numeric signal from the encoding itself.

Conceptual role: Even when production systems skip materializing the full one-hot vector (an embedding lookup is equivalent to W @ one_hot), the conceptual model of one-hot is exactly what embedding lookups implement. Understanding one-hot is the prerequisite for understanding embeddings.
Note: Modern LLM pipelines do not construct explicit one-hot vectors at runtime — the embedding layer performs the equivalent matrix multiply as a direct index lookup for efficiency. But the mathematical foundation is identical.
03

IntuitionA row of switches

Imagine a control panel with V switches, one for each word in your vocabulary. Exactly one switch is ON at any time — the switch labelled with the current token. Every other switch is OFF. The entire state of the panel is your one-hot vector.

cat
[1,0,0,0]
switch 0 ON
dog
[0,1,0,0]
switch 1 ON
fish
[0,0,1,0]
switch 2 ON

The key insight: the position of the 1 carries all the information. The value of the 1 is always just 1 — it signals presence, not magnitude. There is no "more cat-ness" or "less dog-ness" in this encoding.

This is fundamentally different from, say, word frequency counts, where values vary in magnitude and carry information. In one-hot, every active token has exactly the same activation value: 1.

Intuition shortcut: One-hot says which category. Embeddings learn to say where in semantic space. One-hot is step zero — the categorical ground truth before any learning happens.
04

TheoryOne-hot geometry: orthogonality and equidistance

One-hot vectors form the standard basis of an V-dimensional space. Each vector $\mathbf{e}_i$ has a 1 at index $i$ and 0s everywhere else. This has precise geometric consequences.

dot product $\mathbf{e}_i \cdot \mathbf{e}_j = 0$ for $i \neq j$ — distinct one-hot vectors are perfectly orthogonal. The dot product measures shared activation; since they never share an active position, the result is always zero.
Euclidean dist $\|\mathbf{e}_i - \mathbf{e}_j\|_2 = \sqrt{(1-0)^2 + (0-1)^2} = \sqrt{2}$ for any $i \neq j$ — all distinct tokens are equidistant from one another. Distance is always $\sqrt{2}$, regardless of which two tokens are compared.
cosine sim $\cos(\mathbf{e}_i, \mathbf{e}_j) = \frac{\mathbf{e}_i \cdot \mathbf{e}_j}{\|\mathbf{e}_i\|\|\mathbf{e}_j\|} = \frac{0}{1 \times 1} = 0$ for $i \neq j$ — cosine similarity is zero for all distinct tokens. They are perfectly "perpendicular" in category space.
self-similarity $\mathbf{e}_i \cdot \mathbf{e}_i = 1$ and $\cos(\mathbf{e}_i, \mathbf{e}_i) = 1$ — a token is perfectly similar to itself and to nothing else. This makes one-hot a perfect discrete identity encoding.

The geometric consequence of equidistance is that one-hot vectors encode no semantic topology. "cat" and "dog" are no closer together than "cat" and "spaceship". The encoding is maximally agnostic about semantic relationships — it delegates all relationship learning to the embedding layer on top.

Why this matters: Embeddings are learned precisely to break this equidistance — to place semantically related tokens near each other in a lower-dimensional space. One-hot is the uniform prior; embeddings are the learned posterior.
05

How It WorksThe four-step construction

Constructing a one-hot vector for a token is entirely mechanical — no learning, no parameters, no ambiguity:

  1. Fix the vocabulary: Enumerate all possible tokens and assign each a unique integer ID. The order is arbitrary but must remain fixed. Vocabulary size is V.
  2. Find the token's ID: Look up the token in the vocabulary dictionary to retrieve its integer index i.
  3. Create a zero vector: Allocate a vector of length V filled with zeros: [0, 0, …, 0].
  4. Set position i to 1: Flip exactly one position to 1: vector[i] = 1. The result is the one-hot encoding.
Token "fish"→ ID lookup → 2→ zeros(V=4)→ x[2] = 1→ [0, 0, 1, 0]

The embedding layer in a neural network performs the equivalent of: take the one-hot vector $\mathbf{e}_i$, multiply by the embedding matrix $W \in \mathbb{R}^{V \times d}$, and get the $d$-dimensional embedding: $W^\top \mathbf{e}_i = W[i, :]$ — the $i$-th row of $W$. In practice, this is implemented as a direct row index rather than a full matrix multiply, but the math is identical.

Efficiency insight: You never need to materialize the full one-hot vector in production code. The embedding lookup embedding_matrix[token_id] is mathematically equivalent but uses O(d) memory instead of O(V).
06

CalculateManual worked example

Walk through a complete manual construction. Vocabulary: [red, green, blue, yellow, black] — V = 5. Token to encode: "blue".

step 1 Assign IDs: red=0, green=1, blue=2, yellow=3, black=4. Blue's ID is 2.
step 2 Create zero vector of length 5: [0, 0, 0, 0, 0]
step 3 Set position 2 (zero-indexed) to 1: [0, 0, 1, 0, 0]
Vocab [red, green, blue, yellow, black]  →  IDs [0, 1, 2, 3, 4]

red    → [1, 0, 0, 0, 0]
green  → [0, 1, 0, 0, 0]
blue   → [0, 0, 1, 0, 0]   ← token "blue" → ID 2 → position 2 is hot
yellow → [0, 0, 0, 1, 0]
black  → [0, 0, 0, 0, 1]

Dot product check: blue · green = [0,0,1,0,0] · [0,1,0,0,0] = 0+0+0+0+0 = 0. Orthogonal, as expected.

Distance check: ‖blue − green‖₂ = ‖[0,−1,1,0,0]‖₂ = √(0+1+1+0+0) = √2 ≈ 1.414. Equidistant, as expected.

07

Visualize + Hands-onInteractive one-hot encoder

Select any token from the demo vocabulary below and click Encode to see its one-hot vector rendered as a grid of cells. The blue cell marks the active dimension — every other position is zero.

Observation: Notice that no matter which token you select, exactly one cell is blue (value = 1) and all others are grey (value = 0). The dimension count is always 5 — the full vocabulary size V.

Now try to observe these properties as you switch tokens:

  • The position of the hot cell changes but its value is always 1.
  • All other cells are always 0 — the vector is maximally sparse.
  • Two different tokens can never share the same hot position.
  • Adding a new token to the vocabulary would grow every vector by one dimension.
08

CodePython one-hot encoding implementation

A fully annotated implementation showing one-hot construction from scratch, with numpy for efficiency, and a demonstration of the key properties (orthogonality, equidistance, and the embedding-lookup equivalence).

Python
import numpy as np

# ── Step 1: Build vocabulary ────────────────────────────────────────────────
vocab = ["cat", "dog", "fish", "bird", "rabbit"]
token_to_id = {tok: i for i, tok in enumerate(vocab)}
V = len(vocab)

# ── Step 2: Core one-hot function ───────────────────────────────────────────
def one_hot(token_id: int, vocab_size: int) -> np.ndarray:
    """
    Create a one-hot vector of length vocab_size.

    Args:
        token_id:   Integer index of the token (0-based).
        vocab_size: Total vocabulary size V.

    Returns:
        numpy array of shape (V,) with a single 1.0 at position token_id.
    """
    vec = np.zeros(vocab_size, dtype=np.float32)
    vec[token_id] = 1.0
    return vec

# ── Step 3: Encode tokens ───────────────────────────────────────────────────
cat_vec  = one_hot(token_to_id["cat"],  V)   # [1, 0, 0, 0, 0]
dog_vec  = one_hot(token_to_id["dog"],  V)   # [0, 1, 0, 0, 0]
fish_vec = one_hot(token_to_id["fish"], V)   # [0, 0, 1, 0, 0]

# ── Step 4: Verify geometric properties ────────────────────────────────────
print(f"cat · dog  = {np.dot(cat_vec, dog_vec):.1f}")          # 0.0 (orthogonal)
print(f"cat · cat  = {np.dot(cat_vec, cat_vec):.1f}")          # 1.0 (self-dot)
print(f"‖cat−dog‖  = {np.linalg.norm(cat_vec - dog_vec):.4f}") # 1.4142 (√2)
print(f"‖cat−fish‖ = {np.linalg.norm(cat_vec-fish_vec):.4f}")  # 1.4142 (√2, always)
print(f"Non-zero entries: {int(cat_vec.sum())}")                 # 1

# ── Step 5: The embedding lookup equivalence ────────────────────────────────
d = 4   # small embedding dimension
np.random.seed(0)
embedding_matrix = np.random.randn(V, d).astype(np.float32)

# Method A: matrix multiply with one-hot (expensive — O(V*d))
embed_A = embedding_matrix.T @ cat_vec           # shape: (d,)

# Method B: direct index lookup (efficient — O(d))
embed_B = embedding_matrix[token_to_id["cat"]]   # shape: (d,)

print(f"Methods match: {np.allclose(embed_A, embed_B)}")  # True

What to observe

  • Vector length is always V regardless of which token
  • Every pair of distinct tokens has dot product = 0
  • Every pair has Euclidean distance = √2
  • Embedding lookup is mathematically identical to matrix multiply

What to extend

  • Batch encode: stack one-hot rows into an (N × V) matrix
  • Compare memory: N × V floats vs N integer IDs
  • Try scipy.sparse for memory-efficient sparse storage
  • Add a cosine similarity check (should always be 0)
09

Hands-onExperiments to deepen intuition

Run these experiments in a Python notebook or your browser console. Each one challenges a common misconception.

Experiment set: four key checks

1.Add 10 tokens to the vocabulary → encode a token. What happens to V? Every previously encoded vector would need to grow by 10 dimensions. Re-encoding is not free.
2.Compute dot(cat, dog). Result should be exactly 0. Now compute dot(cat, cat). Result should be exactly 1. This is the orthonormality of the standard basis.
3.Count non-zero entries in any one-hot vector. Always exactly 1. If V = 50,000, that's 49,999 zeros per vector — a 99.998% sparse representation.
4.Estimate memory: V=50,000 tokens, float32 = 4 bytes per element. One vector: 50,000 × 4 = 200 KB. One million vectors: 200 GB. This is why nobody materializes one-hot at scale.
Key insight from experiment 4: A learned embedding of dimension 768 (BERT) requires 768 × 4 = ~3 KB per token — 67× more memory-efficient than a 50k-vocab one-hot vector. This is the practical motivation for embeddings, independent of semantics.
10

CompareToken ID vs One-hot vs Embedding

These three representations sit at successive levels of abstraction in the token → model pipeline. Understanding their relationship is foundational:

AspectToken IDOne-hotEmbedding
Representation Single integer V-dimensional binary vector d-dimensional float vector
Semantic info None — arbitrary ordinal None — pure categorical identity Potential — learned from context
Memory per token 4 bytes (int32) V × 4 bytes (e.g., 200 KB for V=50k) d × 4 bytes (e.g., 3 KB for d=768)
Pairwise similarity Meaningless ordinal distance Always 0 (orthogonal, equidistant) Meaningful — dot product / cosine
Role in pipeline Vocabulary index pointer Conceptual bridge; categorical identity Neural representation for model input
Materialized at runtime? Yes — always No — replaced by index lookup Yes — embedding_matrix[token_id]
Conceptual utility even when not materialized: One-hot vectors are rarely constructed in production, but the mental model — each token occupying its own orthogonal axis, all equally distant — is exactly what explains why embeddings can be understood as a learned compression of one-hot space.
11

ApplyWhere one-hot encoding is actually used

Classification targets

Multi-class classifiers output probability distributions. The ground-truth label is one-hot encoded — class 3 out of 10 is [0,0,0,1,0,0,0,0,0,0]. Cross-entropy loss directly compares model output to this one-hot label.

Tabular / categorical features

In classical ML (sklearn, XGBoost), one-hot encoding transforms categorical columns into indicator columns. Country "France" out of 5 countries becomes [0,1,0,0,0]. This is OneHotEncoder in sklearn.

Educational tooling

One-hot is the best pedagogical bridge from categorical variables to numeric vectors. Teaching tokenization, embedding space, or attention patterns all benefit from starting with one-hot as the intuition layer.

LLM intuition: embedding as projection

The embedding layer $W \in \mathbb{R}^{V \times d}$ can be understood as: "given the one-hot identity of token $i$, project it into a learned d-dimensional space". This framing makes weight tying (input/output embeddings) and transfer learning conceptually natural.

Rule of thumb: Whenever you see a softmax output over a vocabulary (token prediction), the model is producing a probability distribution over what would be a one-hot target. The argmax of that distribution is the predicted token ID.
12

LimitationsWhat one-hot fundamentally cannot do

  • Memory does not scale: For V = 100,000 tokens, each one-hot vector has 100,000 elements with 99,999 of them being zero. Storing a corpus of 1 billion tokens as dense one-hot would require ~400 GB of float32 data.
  • Every token is equidistant: Cat and dog, cat and democracy, cat and the number 7 — all are distance √2 from each other. One-hot encodes no topology of meaning, no clusters, no analogies.
  • No learned relationships: Synonyms, antonyms, hypernyms, analogies — none of these are captured. The encoding is purely identity-based; relationships must be learned on top (via embeddings).
  • Vocabulary must be fixed in advance: Adding a new token requires extending every previously encoded vector's dimension. This makes one-hot brittle for open-vocabulary or streaming settings.
Misconception to tackle: "One-hot vectors encode similarity — if two words appear in similar contexts, their one-hot vectors are similar." This is false. One-hot vectors carry zero similarity information. Any similarity you want must be learned separately in an embedding layer trained with a language modeling objective.

Common mistake

"I can measure word similarity by comparing one-hot vectors."

Better mental model

"One-hot vectors are maximally uninformative about similarity — that's their feature, not a bug. They delegate similarity learning to the embedding layer."

13

Feynman ChallengeCan you explain it simply?

Feynman Mastery Check

Explain one-hot encoding to a friend who knows spreadsheets but not linear algebra. Use the "survey checkbox" metaphor:

  • Imagine a survey question: "Which animal do you mean?" with checkboxes for cat / dog / fish / bird.
  • Exactly one box is checked. The "one-hot vector" is just the list of answers: [✓, ☐, ☐, ☐] for cat.
  • Every response has the same number of checkboxes. It doesn't matter that cat=0 or dog=1 — the position is what matters, not the number.
  • Now explain why one-hot knows nothing about which animals are similar — the boxes don't care about meaning, only identity.
  • Finally, explain that embeddings are the step where a model learns to move similar animals closer together in a new coordinate system.
10-second explanation: One-hot encoding gives each category its own coordinate axis with a single 1 — unambiguous identity, zero semantic relationships, bridge to learned embeddings.

Misconceptions to address:

  • "One-hot vectors encode similarity" — No: all distinct tokens are equidistant (dot product = 0, distance = √2).
  • "A larger ID means a more important word" — No: IDs are arbitrary indices with no semantic ordering.
  • "One-hot is what language models actually use internally" — No: LLMs use dense learned embeddings; one-hot is the conceptual foundation, not the runtime representation.
  • "I need to materialize the full one-hot vector in my code" — No: embedding_matrix[token_id] is mathematically equivalent and uses 99%+ less memory.
14

BuildMini-projects to cement your understanding

🔨 Mini-Projects

1 · One-hot playground

Build a tiny web widget: text input for vocabulary (comma-separated), click any token, render its one-hot vector as a row of colored blocks (blue for 1, grey for 0). Show the vector length and the active dimension index.

2 · Token comparison tool

Select two tokens, compute their dot product (always 0) and Euclidean distance (always √2). Then add a learned embedding matrix and show how cosine similarity changes to a meaningful value after one training step.

3 · Memory estimator

Build a calculator: input vocab_size and num_tokens, compute memory for (a) dense one-hot (vocab_size × 4 bytes), (b) integer IDs (4 bytes each), and (c) embeddings of dimension d. Display all three side by side.

15

SummaryOne-hot in one page

Active positions
Exactly 1
per vector, always
Vector length
V
vocabulary size
Sparsity
99.998%
for V=50,000
Semantic info
None
pure identity
  • What it is: A V-dimensional binary vector with exactly one 1, at the token's vocabulary index.
  • Why it exists: Prevents fake numeric ordering of raw integer IDs; gives each category its own orthogonal axis.
  • Geometry: All distinct tokens are perfectly orthogonal (dot = 0) and equidistant (distance = √2).
  • Memory: Too large to materialize at scale — V=50k means 200 KB per vector; replaced by direct index lookup.
  • Relationship to embeddings: An embedding lookup is mathematically W.T @ one_hot — the embedding matrix projects from one-hot space to a learned dense space.
  • Limitation: Encodes zero semantic similarity — motivates the move to learned dense embeddings.
Next: Sparse vs Dense Vectors → — explore why dense embeddings overcome one-hot's limitations, and what "learned geometry" means for model performance.
This page 0:00
This session 0:00
Total (all pages) 0:00
Today 0:00
▶ Running
📊 View all study stats →
0:00 studying