Part II opened with the distributional hypothesis. Firth’s slogan that “you shall know a word by the company it keeps”. We turned it into geometry by counting co-occurrences and reducing the matrix with an SVD.
Those count based vectors work. They also carry the whole matrix’s baggage. They are large, they are sparse, and they must be rebuilt from scratch whenever the corpus changes.
Around 2013 a different idea took over, and every modern system inherits it. Do not count contexts and then compress. Learn a small dense vector for each word directly, by training a model to predict context.
The distributional hypothesis is unchanged. Only the machinery is new. That machinery turns out to be faster and smaller, and it produces geometry with structure nobody put there on purpose.
The canonical method is word2vec, from Mikolov and colleagues in 2013. It trains vectors through a deliberately trivial prediction task.
There are two formulations, and they are mirror images.
Slide a window across the corpus. Take the word at the centre. Try to predict each of the words around it, one at a time.
That is the entire supervised signal. Centre word in, one context word out. No labels are needed, because the corpus labels itself.
Formally, for a corpus and a window of words on each side, skip-gram maximises
CBOW, for continuous bag of words, reverses every arrow. Take the surrounding words and predict the one in the middle.
The context words are combined before they reach the hidden layer, and the combination is a simple average:
That average is where the name comes from. The context is a bag. Order inside the window is discarded, so the cat sat and sat cat the give the same hidden vector.
Take “the quick brown fox jumps” with a window of two words on each side. Both formulations see the same windows and make different training data from them.
| centre | context words | skip-gram pairs | CBOW example |
|---|---|---|---|
| the | quick, brown | (the, quick), (the, brown) | (quick brown) the |
| quick | the, brown, fox | (quick, the), (quick, brown), … | (the brown fox) quick |
| brown | the, quick, fox, jumps | (brown, the), (brown, quick), … | (the quick fox jumps) brown |
| fox | quick, brown, jumps | (fox, quick), (fox, brown), … | (quick brown jumps) fox |
| jumps | brown, fox | (jumps, brown), (jumps, fox) | (brown fox) jumps |
The counts differ, and that difference explains everything else about the two.
Skip-gram produces 14 training pairs from this one sentence, one per centre and context combination. CBOW produces 5, one per centre word.
| CBOW | Skip-gram | |
|---|---|---|
| direction | context centre | centre context |
| examples per centre | 1 | up to |
| speed | faster | slower |
| rare words | weaker | stronger |
| context handling | averaged into one | each predicted separately |
The averaging in Equation (9.2) is what costs CBOW its accuracy on rare words. A rare word in a context of four is one quarter of one hidden vector. The three common words beside it smooth its contribution away.
Skip-gram gives that rare word its own training pair with every neighbour, so it gets chances to shape its own vector. It pays for this in time. More pairs means more updates.
The rule of thumb: CBOW for large corpora where speed matters, skip-gram when the tail matters.
The model has almost no parameters. One vector per word, or strictly two.
Every word has an input vector , a row of , used when is the centre or context being fed in. It also has an output vector , a column of , used when is the word being predicted.
Training nudges those vectors so words appearing in similar contexts end up with similar vectors. When training finishes the output vectors are usually thrown away, and the input matrix is what people mean by “the embeddings”.
word2vec is a neural network with one hidden layer and no nonlinearity in it. Writing it out properly takes four steps.
Let the vocabulary be size and the embedding size . There are two weight matrices. is and holds the input vectors. is and holds the output, or context, vectors.
The input is one hot for the centre word . So
which is just row of . No arithmetic happens here. Multiplying a one hot vector by a matrix selects a row, and that row is the word’s embedding.
For each candidate output word , take the dot product of the hidden vector with that word’s context vector:
Turn the scores into a distribution:
We want to maximise the probability of the true context word , so we minimise its negative log probability. That is cross entropy against a one hot target:
The two terms pull in opposite directions. Push up the score of the right word. Push down the total of all scores.
Everything now follows from the chain rule, and the first derivative is the one you already know from Chapter 8.
Let be the target, for the true context word and otherwise. Differentiating Equation (9.6) gives the prediction minus target rule again:
That is the error at output unit . Every remaining gradient is multiplied by whatever it was attached to.
| gradient | chain rule | result |
|---|---|---|
| output weights | ||
| hidden layer | ||
| input weights |
Two consequences follow.
The output gradient touches every word in the vocabulary, because is nonzero for all . That is the cost we are about to attack.
The input gradient is multiplied by , which is one hot. So only one row of moves per training example. The centre word’s embedding is updated and no other.
Now count the work. Equation (9.5) has a denominator summing over the whole vocabulary, and Equation (9.7) produces an error for every one of those words.
With in the hundreds of thousands, and billions of training examples, this is ruinous. Both fixes below attack the same denominator.
The first fix changes the shape of the output layer. Instead of independent output units, build a binary tree whose leaves are the words.
Reaching any word in a balanced tree takes decisions. For a million words that is about twenty steps rather than a million.
Each internal node carries its own vector . There are no output vectors for words at all any more, only for the nodes on the way to them.
Write for the number of nodes on the path from the root to word . Write for the th node on that path. Then
where the indicator is
The whole construction rests on one identity:
At every node the probability of going left and the probability of going right sum to one. So the probabilities of all leaves sum to one automatically. We get a proper distribution without ever computing a normalising sum.
Take and a balanced tree of depth 3. Suppose the path to cat goes left, then right, then left, and the hidden vector is .
| node | ||||
|---|---|---|---|---|
Multiply the three: .
Three sigmoid evaluations replaced a softmax over eight words. Check the identity at the first node: and , which sum to exactly .
The loss is the negative log of Equation (9.8):
For the path above, .
Differentiating gives a familiar shape:
and the centre word is updated with .
Only the nodes on the path are touched. Every other node in the tree is left alone.
In practice the tree is a Huffman tree, built from word frequencies. Frequent words then sit on short paths and cost least to compute.
The output layer is the problem. Predicting a context word means a softmax over the entire vocabulary. With a vocabulary in the hundreds of thousands, computing that denominator for every training example is ruinous.
word2vec’s decisive trick is negative sampling. Do not ask which of all words is the context. Ask a handful of much easier yes or no questions.
Is this the real context word? Yes. Is this randomly drawn word? No, it is a negative.
Train the vectors to say yes to true pairs and no to a few random ones. A -way softmax becomes a handful of binary decisions per example. That is what made word2vec fast enough to train on billions of words on one machine.
Chapter 7 promised this exponent would return, so here it is.
The negatives are not drawn uniformly, and they are not drawn from the raw unigram distribution either. They come from the unigram counts raised to the power :
Why bend the distribution at all? Draw negatives from the raw counts and nearly every negative is the, which teaches the model almost nothing. Draw them uniformly and rare words appear as negatives far more often than they ever appear as real words.
The power sits between the two. Here is what it does to a five word vocabulary.
| word | count | ||||
|---|---|---|---|---|---|
| the | 1000 | 0.5910 | 177.8 | 0.5301 | |
| of | 600 | 0.3546 | 121.2 | 0.3614 | |
| dog | 50 | 0.0296 | 18.8 | 0.0561 | |
| cat | 40 | 0.0236 | 15.9 | 0.0474 | |
| aardvark | 2 | 0.0012 | 1.7 | 0.0050 |
In the last column, the most frequent word is sampled slightly less than its share, and the rarest more than four times its share. Raising counts to a power below one compresses the range, which lifts the tail and trims the head.
The same exponent did the same job for PMI in Chapter 7. There it smoothed the context distribution, to stop rare words earning inflated scores. Two methods, one correction, and no coincidence. word2vec can be shown to be implicitly factorising a shifted PMI matrix.
The update is the prediction minus target rule from Chapter 8, applied to a dot product. Nothing new is needed.
Take a centre word cat with vector . Take the true context word sat with vector , and one sampled negative the with . The learning rate is .
For each pair the model scores , squashes it with a sigmoid, and compares with the label. The label is for the true context and for a negative.
| pair | label | gradient | ||
|---|---|---|---|---|
| cat, sat (positive) | 1 | |||
| cat, the (negative) | 0 |
The signs are the whole story. The positive pair gets a negative gradient, which pulls the two vectors together. The negative pair gets a positive one, which pushes them apart.
Now apply to each context vector.
| vector | arithmetic | new value |
|---|---|---|
Did it work? Recompute both scores with the updated vectors.
| before | after | |
|---|---|---|
| , want it up | ||
| , want it down |
True pairs pulled together, random pairs pushed apart. Repeat a few billion times and the geometry of Part II falls out.
Try it yourself.
code/worked_examples/word2vec.pyprints both tables above.--exponentlets you change the and watch the sampling distribution flatten or sharpen.
Written out, the loss for one centre word with negatives is
where is the score of a candidate word.
Apply Equation (9.10) and the second term becomes , which is the form usually printed. Both say the same thing. Make the true pair score high and the sampled pairs score low.
Compare this with the full softmax loss of Equation (9.6). The sum over has become a sum over , and is typically 5 to 20.
Put the three side by side. Let be the corpus size, the embedding dimension, and the window size.
| method | cost |
|---|---|
| Full softmax | |
| Hierarchical softmax | |
| Negative sampling |
For , the full softmax costs a million operations per prediction. Hierarchical softmax costs about twenty. Negative sampling costs , and does not grow with the vocabulary at all.
Both fixes are approximations, and they approximate different things. Hierarchical softmax still computes a genuine probability distribution, just factored over a tree. Negative sampling abandons the distribution entirely and solves a set of binary classification problems instead. In practice negative sampling won, because it is simpler and trains faster on frequent words.
Negative sampling is a pattern this book meets again. Pull true pairs together, push random pairs apart. The contrastive training behind dense retrieval in Chapter 20 is the same idea one level up, with positive and negative pairs shaping a representation.
Something unplanned fell out of these vectors.
Take the vector for king. Subtract man. Add woman. The nearest vector to the result is queen.
The relationship from male to female turns out to be, approximately, a direction in the space. The same displacement carries uncle to aunt and he to she. Plural formation is another direction. Capital of country is another.
Nobody designed this. It emerged because consistent semantic relationships produce consistent contextual differences, and training recorded them as consistent geometric ones.
Analogy solving becomes arithmetic:
excluding , and themselves from the answer.
Take a toy space with three interpretable dimensions: how royal a word is, how male, how female.
| word | royal | male | female |
|---|---|---|---|
| king | 1.00 | 0.90 | 0.10 |
| man | 0.10 | 0.90 | 0.10 |
| woman | 0.10 | 0.10 | 0.90 |
| queen | 0.95 | 0.15 | 0.85 |
| prince | 0.90 | 0.85 | 0.15 |
| throne | 0.80 | 0.45 | 0.45 |
| child | 0.20 | 0.50 | 0.50 |
Compute the target. Subtracting man from king strips the male component and keeps the royal one. Adding woman puts a female component back:
Now rank every word by cosine to that target.
| word | cosine | |
|---|---|---|
| queen | the answer | |
| throne | royal, but not gendered | |
| woman | query word, must be excluded | |
| child | ||
| prince | royal, but male | |
| king | query word, must be excluded | |
| man |
Queen wins at , and the runners up are interpretable. Throne is royal but carries no gender. Prince is royal but male. Both are near, and both are wrong for the right reasons.
Note where woman lands: third, ahead of four other words. On real spaces a query word very often comes first, because stays close to . Forget the exclusion and your analogy scores will look far better than they are. It is the single most common way to overstate an embedding.
The analogy above used a famous example on a space built to make it work. Here is a more honest use of the same arithmetic, and it doubles as a diagnosis of the corpus.
Take a space trained on technology news. Ask for the nearest neighbours of apple.
| neighbour | cosine | |
|---|---|---|
| mac | ||
| samsung | ||
| iphone | ||
| android | ||
| orange | the first fruit, far behind | |
| juice |
The top four are technology. The first fruit trails at , and it is orange, which is a phone network as well as a fruit.
This tells us something about the corpus rather than about English. Apple is overwhelmingly a company here. The fruit sense exists in the vector, but it is buried under the company sense, because the training text talked about one far more than the other.
Now subtract the strongest technology association and see what is left:
Rank every word by cosine to .
| neighbour of | cosine | |
|---|---|---|
| fruit | ||
| banana | ||
| juice | ||
| orange | ||
| mac | now pointing the other way | |
| samsung |
The list has inverted completely. Fruits fill the top. The technology words have gone negative, meaning they now point away from what is left.
Nothing was told to the model about fruit or about companies. Subtracting one word removed a whole semantic dimension, and the sense that had been buried came to the surface.
A vector is a mixture of the senses and associations the corpus gave the word. Apple carries a large technology component and a smaller fruit one. Iphone carries the technology component and no fruit at all.
Subtracting cancels what they share and keeps what only the first has. The technology part very nearly annihilates, and the fruit part survives untouched. The residue is the minority sense.
This is a practical diagnostic, and worth more than analogy scores.
It reveals the dominant sense of a polysemous word, which is a fact about your training data. If apple comes out as a company, your corpus is technology news. If it comes out as a fruit, your corpus is recipes or agriculture. The same probe on bank, java, python or amazon will tell you what your text was about before you read a line of it.
It also shows the limit of a single vector per word. Both senses are jammed into one point, and pulling them apart takes arithmetic and a guess about what to subtract. Chapter 15 solves this properly by letting the sentence decide which sense is present.
Try it yourself.
code/worked_examples/word2vec.py --appleprints both tables.--subtracttakes any word, so you can strip a different association and see what surfaces.
word2vec learns from local windows, one at a time. It never sees the corpus as a whole. GloVe asks whether that is wasteful, given that the global co-occurrence counts are sitting right there.
GloVe’s founding observation is not about counts. It is about ratios of counts.
Let be the number of times word occurs in the context of word . The conditional probability is
Take a single probability such as . It is hard to interpret. Is large? There is nothing to compare it against.
Now take two words and probe them with a third. Compare against for various probe words . The ratio is immediately readable.
| probe | solid | gas | water | fashion |
|---|---|---|---|---|
| related to ice? | yes | no | both | neither |
| related to steam? | no | yes | both | neither |
| large | small |
The ratio is large when the probe belongs to the first word. It is small when the probe belongs to the second. It sits near one when the probe belongs to both, or to neither.
That is the discrimination raw probabilities could not give. Water and fashion both score near one, for opposite reasons, and the ratio quite properly refuses to distinguish them: neither tells ice from steam.
If ratios carry the meaning, the model should predict them. GloVe arranges for the dot product of two word vectors to approximate the log of the co-occurrence count, because differences of logs are ratios.
That gives a weighted least squares problem:
Each piece earns its place.
is the vector for the word, the vector for the context. Every word again gets two, exactly as word2vec has input and output vectors. The final embedding is usually , since both carry signal.
The biases and absorb how common each word is on its own. Without them the model would have to encode raw frequency in the vectors, which is the pollution PMI existed to remove in Chapter 7.
The target is , not . A log turns the multiplicative structure of counts into an additive one, so a difference of dot products lands on a ratio of probabilities. That is the whole design.
The last piece is , and without it the objective would be dominated by whichever pairs happen to be most frequent.
It does three jobs at once.
At it gives , so pairs that never co-occur contribute nothing. This matters, because is undefined and most of the matrix is zeros.
Between and it rises, so rarer pairs count less than common ones, which suppresses noise from pairs seen once or twice.
Above it is flat at . A pair seen ten thousand times gets no more weight than one seen a hundred times, so the cannot dominate the fit.
That exponent is for the third time in this book, after PMI smoothing and negative sampling. Three different models, three different mechanisms, and the same correction: compress the range so the head does not swamp the tail.
At release in 2014 it beat the alternatives on three tasks: word analogy, word similarity and named entity recognition. It captured syntactic and semantic relationships equally well.
It shares word2vec’s fatal limitation, though. GloVe produces static embeddings, one vector per word, and contextual models have since displaced it for most tasks.
Both models so far treat a word as an atom. A word is either in the vocabulary with a vector of its own, or it is unknown and has nothing.
Chapter 3 showed why that fails. Heaps’ law guarantees the vocabulary never closes, so unknown words keep arriving forever.
FastText answers the same pressure that subword tokenisation answered in Chapter 5, but at the embedding rather than the tokeniser.
Break each word into overlapping character n-grams. Mark the
boundaries with < and >, so a prefix can
be told from the same letters appearing mid-word.
For apple with :
<ap app ppl
ple le>
FastText normally uses several values of together. Here is technical at and .
| 3-grams | <te, tec,
ech, chn, hni, nic,
ica, cal, al> |
| 4-grams | <tec, tech,
echn, chni, hnic,
nica, ical, cal> |
Every n-gram gets its own learned vector . The word’s vector is their sum, and the whole word is included in the set as well:
Written out for our example,
Everything else is skip-gram with negative sampling, unchanged. Only the definition of a word vector has moved.
Meet technicality for the first time and FastText still
produces something sensible. Its n-grams tec,
ech, chn and nic were all trained
on technical and its relatives, so the sum lands near them.
word2vec and GloVe can only return an unknown token here. FastText returns a vector in roughly the right neighbourhood.
Walk, walks, walked and walking share most of their n-grams, so their vectors are close by construction rather than by luck.
This matters far more in some languages than in English. A morphologically rich language such as Tamil, Finnish or Turkish generates enormous numbers of inflected forms, most of them individually rare. Treating each as an unrelated atom wastes almost all the evidence. Sharing subword vectors pools it.
The n-gram table is larger than a word table, and a word vector must be assembled at query time rather than looked up. FastText also cannot separate unrelated words that happen to share spelling. Nothing tells it that ear in earth has no connection to ear in hearing.
FastText itself is little used now. Its central move is everywhere.
Every modern tokeniser builds its vocabulary from frequent character sequences rather than whole words. BPE in Chapter 5, WordPiece, SentencePiece. All of them answer the open vocabulary problem the same way, by composing rare things from common pieces.
FastText made that argument at the embedding layer first.
Part II has now built dense word vectors three separate times. Chapter 7 factored a PPMI matrix with an SVD. This chapter trained word2vec by gradient descent, then fitted GloVe to global counts.
Three methods, three chapters, three sets of vectors that behave alike. That is not a coincidence, and the reason is the most useful idea in Part II.
All three are matrix factorisations of the same co-occurrence statistics. They differ in which matrix, which loss and which optimiser. They do not differ in kind.
Every method here produces two matrices. A word matrix of size , and a context matrix of the same size. Row of is the vector . Row of is the context vector .
Every method then asks the dot product of a word and a context to reproduce some association score:
That is the whole family. Choosing a method means choosing three things: the matrix , the weight each cell carries, and how you solve for and .
| SVD of PPMI | word2vec (SGNS) | GloVe | |
|---|---|---|---|
| target | |||
| cell weight | all cells equal | the counts | |
| zero cells | fitted as | pushed down | dropped |
| solved by | closed form | stochastic gradient | gradient on counts |
| needs | the whole matrix | a stream of windows | the whole matrix |
The middle column is the surprising one. Nothing in word2vec’s training loop mentions PMI. The next subsection shows why PMI turns up anyway.
Recall the negative sampling objective of Equation (9.13). Take one word and one context, and write for their dot product.
Over the whole corpus that pair is seen times as a real pair. It also turns up as a sampled negative. A word is the centre of windows, each draws negatives, and each negative is with probability . So the pair appears as a negative times in expectation.
Collect the two contributions:
Now differentiate and set the result to zero. Using ,
Write and . Then , and since , this gives . Substituting , where is the number of pairs in the corpus:
This is the result of . The optimum of skip-gram with negative sampling is a PMI matrix, shifted down by . Two hundred dimensions of gradient descent, and the answer was in Chapter 7 all along.
The shift has a plain reading. More negatives means a higher bar. With every entry moves down by , so a pair needs stronger evidence before its dot product goes positive.
The claim is checkable on the eight-word matrix of Chapter 7. Train the objective directly, then compare each learned dot product against .
| pair | learned | difference | |
|---|---|---|---|
| cat, vet | |||
| vet, vet | |||
| dog, fur | |||
| fuel, tyre | |||
| vet, feed | |||
| pet, feed |
Across all observed pairs the mean absolute difference is , with . The largest is . The network was never shown a PMI value.
GloVe looks like a different animal, because Equation (9.17) fits rather than an association score. The biases close the gap.
Start from the definition of PMI and expand it in raw counts. Write for a row total, for a column total, and for the grand total:
Now read GloVe’s objective again. It asks for . The two biases are free parameters, fitted from the data. Set
and the right hand side becomes exactly Equation (9.25). GloVe’s dot product is fitting PMI, up to whatever the biases absorb.
That is what the biases were introduced to do. The GloVe section justified them as removing raw frequency from the vectors. Equation (9.25) says what removing raw frequency means. It means subtracting a row effect and a column effect, which is the arithmetic PMI performs.
The fitted numbers agree. On the same eight-word matrix the bias rises with the word’s row total. Tracking that total is the only job it has.
| word | bias | row total |
|---|---|---|
| cat | ||
| truck | ||
| dog | ||
| vet |
So three chapters of machinery converge on one target. SVD fits PPMI. word2vec fits PMI shifted by . GloVe fits PMI with the shift absorbed into two bias terms.
That also settles a puzzle from earlier. The exponent appears in PMI smoothing, in negative sampling and in GloVe’s weighting function. It is the same correction applied to the same statistic, three times over.
Sharing a target does not make three methods interchangeable. The differences sit in the two remaining columns of the table: how each cell is weighted, and what happens to the zeros.
Weighting first. The SVD minimises squared error over every cell equally. A pair seen once therefore counts as much as a pair seen ten thousand times. word2vec weights each pair by how often it occurred, since the objective sums over actual windows. GloVe states its weighting outright in , and can therefore tune it.
The zeros matter more, and they are easy to miss. Most of a co-occurrence matrix is zeros, and the three methods treat them in three different ways. PPMI writes an explicit and the SVD fits it like any other cell. word2vec never fits a zero cell directly. Negative sampling still drags it down, because an unseen pair is drawn as a negative and never as a positive. GloVe sets and drops those cells entirely.
Take the matrix from Chapter 7: four animal words, four vehicle words, and no shared context at all. Compress to two dimensions by each method, then ask for nearest neighbours.
| query | SVD of PPMI | word2vec | GloVe |
|---|---|---|---|
| dog | cat | cat | truck |
| car | truck | truck | dog |
| vet | dog | pet | fuel |
| fuel | car | drive | vet |
Two methods get all four right. GloVe gets all four wrong, and it is not a training failure. Its fit to is good, at a mean absolute error of .
The explanation is the zeros. On this matrix every fact that separates an animal from a vehicle lives in a cell that is zero. GloVe drops those cells, so it is never shown a single piece of evidence that a dog is unlike a truck. The two groups are fitted on disjoint contexts, and nothing ties them together. Their relative positions are left to the initialiser.
Fill each zero with a count of and GloVe recovers all four. Real corpora have almost no structural zeros, because in a large enough corpus most pairs eventually co-occur once. That is why this never became a practical problem, and it is also why the toy exposes the mechanism so cleanly.
The remaining difference is cost. The SVD needs the whole matrix in memory and a full decomposition, which is cubic in the smaller dimension. word2vec needs only a stream of windows and never builds the matrix at all. That, rather than vector quality, is why the learned methods took over in 2013.
The factorisation view also settles what the embedding dimension means.
In the SVD picture the top singular values carry most of the semantic structure. Chapter 7 used their decay to choose , through the contribution ratio of Equation (7.10).
word2vec’s hidden layer dimension plays the identical role. It is a budget for how many directions you are willing to keep. The lectures put it as a parallel between hidden units and significant eigenvalues.
Choosing is therefore the bias variance trade off in disguise. Too few dimensions and semantic information is lost. Too many and you fit noise.
This predicts something you can check. Raise past the number of significant singular values and it should buy little. In practice it does.
So the useful tends to land near the count of large singular values. That is what the scree plot of Chapter 7 was showing all along.
Try it yourself.
code/worked_examples/factorisation.pyproduces every number in this section, on the matrix Chapter 7 already used. Run it plain for all four steps.--sgns --k 1shows the shift vanishing when there is one negative, and--k 15shows it growing.--compareprints the neighbour table above, and--compare --fill 1removes the structural zeros and watches GloVe come back into line.
An embedding space is not a black box. It is an object you can interrogate, and learning to read one is a practitioner’s core skill.
Every question you can ask reduces to one operation, the cosine similarity of Chapter 4:
It ranges from for the same direction, through for orthogonal, to for opposite.
We use the angle rather than the raw dot product for a specific reason. Vector length in these spaces tracks word frequency more than meaning. Direction is where the semantics live.
From cosine, three tools follow.
Nearest neighbours are the words of highest cosine to a target, excluding the target itself. They reveal what a word means to the space. The neighbours of bank expose whether your corpus was about rivers or money.
Analogies, through Equation (9.14), probe whether a relationship is encoded as a clean direction.
Failures are as informative as successes. On a corpus of a few thousand documents many analogies return nonsense. The relationship was never witnessed often enough to become a stable direction. Knowing that a bad analogy usually means thin data, not a broken method, is exactly the forensic skill Project 3 trains.
The geometry records whatever the corpus contains, including its social regularities. The apple probe above was a mild instance. What follows is the same fact with higher stakes.
Suppose a body of text systematically places occupation words near one gender’s pronouns. The space will place them near that gender’s vector. No single sentence is biased. The aggregate association is real and measurable.
Measuring it needs only cosine. The tool is the Word Embedding Association Test . In the simplified form this course uses, it scores the differential association of target words with two attribute sets and :
A positive means the targets sit closer on average to set . A negative means closer to . The magnitude is the strength.
Point it at institutional against narrative vocabulary and it separates registers. Point it at gendered attributes and it exposes occupational stereotypes in web scale spaces.
The number is honest and it demands honesty back. Three cautions.
It measures the corpus, through the model. Change either and changes.
The word lists are a design choice. Report them with the score, or the score means nothing.
A near zero result means these lists do not separate. It does not mean the space is unbiased.
Any system built on these vectors inherits their associations silently. Search, screening, classification, all of it. That is why measuring them is not an ethical afterthought. It is part of knowing what you have built.
For all their elegance, these embeddings share one fatal limitation. Each word gets exactly one vector, forever.
The bank of a river and the bank that holds money collapse into a single point. That point is the blurred average of both senses, and it is correct for neither.
A word’s meaning depends on its sentence. A lookup table cannot represent that, because it committed to the vector before the sentence existed.
Repairing this is the achievement of the contextual embeddings and transformers of Part IV. Let a word’s representation depend on its context.
The tools you build here do not go away. Cosine, nearest neighbours and association tests are exactly how those larger models are probed and audited. Learning to read a space by hand now is learning to read every space later.
introduce negative sampling. on GloVe and on FastText are the siblings. is the WEAT paper and a model of careful measurement. explains word2vec’s parameter updates step by step. extends the idea from words to whole sentences and documents. analyses the linear algebraic structure that lets a single vector encode several senses of a word. proves that negative sampling factorises a shifted PMI matrix, and shows that much of word2vec’s reported advantage over counting was down to hyperparameters rather than method.
Build the toolkit. Start from a trained embedding space. PPMI plus SVD over a corpus of your choice works well. Implement three functions: cosine similarity, nearest neighbours, and analogy solving. Make sure your analogy function excludes the three query words from the answer. Omitting that exclusion is the most common way to overstate performance.
The exclusion trap, measured. Run twenty analogies twice, once with the query words excluded and once without. Report how much the score improves when you cheat. Which query word wins most often, and why is it usually rather than or ?
Bend the sampling distribution. Using Equation (9.12), recompute the five word table in this chapter with exponents , and . At which exponent does aardvark get sampled ten times its share? What would go wrong at each extreme?
Embedding forensics. Take five word vectors, add a little random noise to each, and identify the original words using only cosine and nearest neighbours. Report how much noise your identification survives, and which words are easiest and hardest to recover.
Audit the analogies. Run twenty analogy queries of your own and record which succeed and which fail. Group the failures and propose an explanation for each group: frequency effects, polysemy, a missing relation direction. Analogies are honestly hit or miss. Your job is to say when and why.
Derive the shift. Starting from Equation (9.22), differentiate with
respect to
and recover Equation (9.24). Then state what
happens to the target as
grows, and why
makes the shift disappear. Verify one row of the table numerically with
factorisation.py --sgns --k 1.
Break GloVe on purpose. Build a small co-occurrence matrix whose two word groups share no context. Fit GloVe to it and report the nearest neighbours. Explain, using , why the groups are not separated. Then add a single count to every empty cell and report what changes. Which of SVD and word2vec would you expect to survive the original matrix, and why?
Measure a bias. Choose two target sets and two attribute sets, for example two families of names against two families of adjectives. Compute a WEAT score with Equation (9.27). Interpret its sign and magnitude, and state one thing the number does not license you to conclude.