CBOW Model › Context Word Averaging
Language AI HandbookAll chapters CBOW Model › Context Word AveragingOne section · Sections in this chapter4 / 15 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
The averaging step is CBOW's defining operation. How should the model combine information from multiple context words into a single vector? CBOW takes the simplest possible answer: element-wise mean. If the context words "quick," "brown," "jumps," and "over" each contribute a -dimensional embedding, the averaged representation is the vector whose -th element is the mean of all four embeddings' -th elements.
More formally, given context words with indices in the vocabulary, the hidden representation is:
where:
- : the averaged hidden representation, a -dimensional vector representing the "centroid" of the context in embedding space
- : the number of context words (typically for a window of size , but fewer at sentence boundaries)
- : the embedding of the -th context word, the row at index in the embedding matrix
This averaging has an important geometric interpretation. Each embedding vector corresponds to a point in -dimensional space. The average corresponds to the centroid of those points. If the context words are semantically coherent (which they tend to be in natural language), their centroid points toward the region of the embedding space where the center word should live.
To see why this works, consider what the model must learn for the centroid to be useful. Each context word embedding must encode the word's own meaning and information about what words typically appear near it. After training, the centroid of "quick," "brown," "jumps," and "over" should point toward the region where nouns like "fox" live, because that is the region the model was repeatedly trained to predict from such context centroids.
There is an alternative design choice worth understanding: instead of averaging, you could sum the context embeddings. The sum is mathematically equivalent to the average (they differ only by a constant scaling factor), but the average has a practical advantage: the magnitude of the hidden representation does not grow with the number of context words. This stability is helpful for maintaining consistent gradient magnitudes during training regardless of window size or sentence boundary effects.
import numpy as np
# Small vocabulary for demonstration
small_vocab = ["the", "quick", "brown", "fox", "jumps", "over", "lazy", "dog"]
word_to_idx = {word: i for i, word in enumerate(small_vocab)}
idx_to_word = {i: word for word, i in word_to_idx.items()}
# Initialize small embedding matrix (random, untrained)
embedding_dim = 4
np.random.seed(42)
W = np.random.randn(len(small_vocab), embedding_dim) * 0.5
def average_context_embeddings(context_words, W, word_to_idx):
"""Average the embedding vectors of a set of context words."""
embeddings = np.array([W[word_to_idx[word]] for word in context_words])
return np.mean(embeddings, axis=0)
context = ["quick", "brown", "jumps", "over"]
avg_embedding = average_context_embeddings(context, W, word_to_idx)Context Word Averaging (embedding_dim=4): ---------------------------------------------------- Context words: ['quick', 'brown', 'jumps', 'over'] Individual embeddings: quick : [-0.117, -0.117, +0.790, +0.384] brown : [-0.235, +0.271, -0.232, -0.233] jumps : [-0.506, +0.157, -0.454, -0.706] over : [+0.733, -0.113, +0.034, -0.712] Averaged embedding (h-bar): h_bar : [-0.031, +0.050, +0.034, -0.317] Verification (manual column averages): Dim 1: mean(['-0.117', '-0.235', '-0.506', '+0.733']) = -0.031 Dim 2: mean(['-0.117', '+0.271', '+0.157', '-0.113']) = +0.050 Dim 3: mean(['+0.790', '-0.232', '-0.454', '+0.034']) = +0.034 Dim 4: mean(['+0.384', '-0.233', '-0.706', '-0.712']) = -0.317
The averaged embedding is not the embedding of any particular word. It is a synthetic point in the embedding space that represents the combined semantic context. After training, this averaged vector will be positioned such that the center word's row in receives the highest score.

The heatmap makes the averaging operation concrete. Each column of the upper four rows contains the embedding values for one dimension. The bottom row shows how the average smooths these values, placing the centroid between the extremes. In this random-initialization example, the values carry no semantic meaning yet, but the same averaging process applies once the embeddings have been trained. After training, the average of "quick," "brown," "jumps," and "over" will be a vector that the output matrix can reliably decode as "fox."
The Geometric View of Averaging
It is worth dwelling on the geometry a little longer because it explains both the strengths and the limitations of CBOW. In -dimensional embedding space, each word occupies a point. The average of points is the centroid, the center of mass of the configuration. When the context words form a tight cluster (because they are semantically similar or syntactically related), the centroid is a stable, representative point. When the context words are semantically diverse or scattered across the embedding space, the centroid can end up in an unusual region, away from any natural cluster.
This geometry explains CBOW.s stability on frequent words. Frequent words appear in many different contexts. Over many training examples, the model encounters "fox" predicted from contexts like ["quick", "brown", "jumps", "over"], ["cunning", "red", "ran", "through"], ["the", "chased", "by", "hound"], and many more. Each of these averages lands near the "fox" region of the space, and the gradients reinforce the embedding accordingly. The signal is consistent and strong.
Rare words, by contrast, may appear in only a handful of contexts. If "dhole" (a type of wild canid) appears in contexts mostly involving predation and forests, its averaged context vectors may cluster in a region that also corresponds to many other animals. The signal is weaker, and neighboring words may not be reliable discriminators. This is why Skip-gram, which trains on each context word individually, tends to outperform CBOW on rare vocabulary.