This experiment compares five routes to a Word2Vec model: two trained with gensim on movie reviews, a frozen pretrained model, a fine-tuned version of those pretrained weights, and a skip-gram implementation written from scratch. The three models trained from scratch are then retrained on text8, 17 million words of Wikipedia, to see how much the training text matters. The same pipeline measures sentiment accuracy, lexical structure, and runtime cost.
A, B and C appear twice, once trained on SST and once retrained on text8. Every model goes through the same evaluation. I look up each word vector, average the vectors into one sentence representation, fit logistic regression, and test on the same held-out SST-2 sentences. The classifier is never tuned for an individual model. This keeps the comparison focused on the embeddings.
Sentiment accuracy is the share of the 1,821 SST-2 test sentences classified correctly. Word similarity is the Spearman correlation between the model's cosine similarities and human ratings on WordSim-353: 1 is perfect agreement, 0 is none.
| Model | Architecture | Loss | Trained on | Accuracy | F1 | OOV |
|---|---|---|---|---|---|---|
| A (SST) | Skip-gram | Negative sampling, k=10 | 633,720 tok | 0.7611 | 0.7757 | 0.066 |
| A (text8) | Skip-gram | Negative sampling, k=10 | 17,005,207 tok | 0.7221 | 0.7413 | 0.169 |
| B (SST) | CBOW | Hierarchical softmax | 633,720 tok | 0.7293 | 0.7501 | 0.066 |
| B (text8) | CBOW | Hierarchical softmax | 17,005,207 tok | 0.7243 | 0.7490 | 0.169 |
| C (SST) | Skip-gram | Negative sampling, k=10 | 633,720 tok | 0.7441 | 0.7610 | 0.066 |
| C (text8) | Skip-gram | Negative sampling, k=10 | 17,005,207 tok | 0.7150 | 0.7340 | 0.169 |
| G | Skip-gram | Negative sampling, k=5 | 100,000,000,000 tok | 0.7979 | 0.8107 | 0.271 |
| G-ft | Skip-gram | Negative sampling, k=10 | 633,720 tok | 0.7919 | 0.8089 | 0.066 |
| A2 | Skip-gram | Negative sampling, k=10 | 633,720 tok | 0.6645 | 0.7070 | 0.066 |
A2 is a control, not a sixth model. Its 0.664 score is the lowest in the table, but that result is useful: it makes the claim about G-ft's warm start testable. The three text8 rows are A, B and C trained on Wikipedia instead of SST. More training text covers them.
These examples show the held-out sentiment task at sentence level. For each model, the table gives the classifier's two labels with their probabilities and the top-5 closest training sentences by cosine similarity. Neighbour agreement is the fraction of those retrieved sentences whose gold label matches the test example. It gives a small, concrete view of what evidence sits nearby in the embedding space.
I selected all five by rule, not by eye. The rule appears above each example. Accuracy within this small set is A 3/5, B 3/5, C 3/5, G 4/5, G-ft 3/5.
this is one of polanski 's best films .
| Model | Rank 1 | Rank 2 | Result | Neighbour agreement |
|---|---|---|---|---|
| A (SST) | positive 0.838 | negative 0.162 | correct | 1.0 |
| B (SST) | positive 0.694 | negative 0.306 | correct | 1.0 |
| C (SST) | positive 0.656 | negative 0.344 | correct | 1.0 |
| G | positive 0.855 | negative 0.145 | correct | 1.0 |
| G-ft | positive 0.808 | negative 0.192 | correct | 1.0 |
Training sentences are ordered by cosine similarity. A green tint means the retrieved sentence's label matches the test sentence's gold label. This is separate from the gold tint in the neighbour tables.
arnold 's jump from little screen to big will leave frowns on more than a few faces .
| Model | Rank 1 | Rank 2 | Result | Neighbour agreement |
|---|---|---|---|---|
| A (SST) | positive 0.593 | negative 0.407 | wrong | 1.0 |
| B (SST) | negative 0.534 | positive 0.466 | correct | 1.0 |
| C (SST) | negative 0.546 | positive 0.454 | correct | 0.8 |
| G | negative 0.668 | positive 0.332 | correct | 0.0 |
| G-ft | positive 0.512 | negative 0.488 | wrong | 1.0 |
Training sentences are ordered by cosine similarity. A green tint means the retrieved sentence's label matches the test sentence's gold label. This is separate from the gold tint in the neighbour tables.
finally , a genre movie that delivers -- in a couple of genres , no less .
| Model | Rank 1 | Rank 2 | Result | Neighbour agreement |
|---|---|---|---|---|
| A (SST) | negative 0.596 | positive 0.404 | wrong | 0.4 |
| B (SST) | negative 0.643 | positive 0.357 | wrong | 0.2 |
| C (SST) | negative 0.597 | positive 0.403 | wrong | 0.4 |
| G | positive 0.680 | negative 0.320 | correct | 0.4 |
| G-ft | negative 0.508 | positive 0.492 | wrong | 0.8 |
Training sentences are ordered by cosine similarity. A green tint means the retrieved sentence's label matches the test sentence's gold label. This is separate from the gold tint in the neighbour tables.
but what saves lives on the freeway does not necessarily make for persuasive viewing .
| Model | Rank 1 | Rank 2 | Result | Neighbour agreement |
|---|---|---|---|---|
| A (SST) | negative 0.592 | positive 0.408 | correct | 1.0 |
| B (SST) | positive 0.574 | negative 0.426 | wrong | 0.8 |
| C (SST) | positive 0.614 | negative 0.386 | wrong | 0.6 |
| G | positive 0.565 | negative 0.435 | wrong | 0.8 |
| G-ft | negative 0.502 | positive 0.498 | correct | 0.8 |
Training sentences are ordered by cosine similarity. A green tint means the retrieved sentence's label matches the test sentence's gold label. This is separate from the gold tint in the neighbour tables.
no movement , no yuks , not much of anything .
| Model | Rank 1 | Rank 2 | Result | Neighbour agreement |
|---|---|---|---|---|
| A (SST) | negative 0.972 | positive 0.028 | correct | 1.0 |
| B (SST) | negative 0.955 | positive 0.045 | correct | 1.0 |
| C (SST) | negative 0.860 | positive 0.140 | correct | 0.6 |
| G | negative 0.964 | positive 0.036 | correct | 1.0 |
| G-ft | negative 0.989 | positive 0.011 | correct | 1.0 |
Training sentences are ordered by cosine similarity. A green tint means the retrieved sentence's label matches the test sentence's gold label. This is separate from the gold tint in the neighbour tables.
no less is an intensifier rather than a negation. Of the
five main models, only the frozen GoogleNews model reads it that way. Every SST-trained model, including G-ft, predicts
negative.
no charm , no laughs , no fun, a near-duplicate of the test sentence's
stacked-negation pattern. The models succeed through lexical overlap, not by composing
the negation. The same shortcut fails on Example 3 but happens to work here.The five queries are meant to expose differences between the models: a polysemous noun, a sentiment adjective, a domain-sensitive word, a rare film term, and the most frequent word in English.
| Model | Top-1 | Top-2 to 5 | Top-6 to 10 |
|---|---|---|---|
| A (SST) | twists 0.48 | pawn 0.46device 0.46court 0.46oh-so 0.45 | nifty 0.45cliché-riddled 0.44stop-and-start 0.44triteness 0.44convenient 0.44 |
| A (text8) | ridolfi 0.55 | popish 0.51subplot 0.51gattaca 0.49plots 0.49 | babington 0.48whodunit 0.48counterpointed 0.48replicants 0.48dramatized 0.48 |
| B (SST) | ending 0.32 | accomplishment 0.28sweetness 0.26flourish 0.25despair 0.25 | flashy 0.25mastering 0.25clancy 0.25compressed 0.24sure-fire 0.24 |
| B (text8) | storylines 0.37 | storyline 0.36gattaca 0.36sequel 0.35story 0.34 | plots 0.32character 0.32villain 0.32flashback 0.32horror 0.31 |
| C (SST) | twists 0.86 | device 0.84oh-so 0.84halfwit 0.83court 0.83 | stop-and-start 0.81maneuvers 0.81sillified 0.81holes 0.80nurses 0.80 |
| C (text8) | ridolfi 0.59 | subplot 0.58plots 0.58popish 0.56storyline 0.55 | gattaca 0.55conspirators 0.53storylines 0.53fawkes 0.53macguffin 0.52 |
| G | plots 0.76 | Plot 0.65plotting 0.63plotted 0.60plotline 0.59 | plotters 0.54storyline 0.53conspiracies 0.52conspiracy 0.51foiled_plot 0.50 |
| G-ft | plots 0.77 | plotting 0.68plotted 0.62plotline 0.56storyline 0.52 | conspiracies 0.51conspiracy 0.51oh-so 0.50conspirators 0.48subplots 0.47 |
| Model | Top-1 | Top-2 to 5 | Top-6 to 10 |
|---|---|---|---|
| A (SST) | fitting 0.70 | synergistic 0.67stultifyingly 0.67reconstruction 0.66bloodwork 0.66 | besotted 0.59impulse 0.59propelled 0.58freaky 0.58regard 0.57 |
| A (text8) | horrible 0.55 | terrifying 0.51thulsa 0.51irreparable 0.50toils 0.50 | betrayals 0.49hitlerite 0.49frailty 0.48devastations 0.48calamity 0.48 |
| B (SST) | thrilling 0.40 | chump 0.36ballistic 0.34motion 0.34paint-by-numbers 0.33 | view 0.33derrida 0.33ecks 0.33cinderella 0.33raises 0.33 |
| B (text8) | disastrous 0.35 | devastating 0.34horrible 0.30tragic 0.29severe 0.29 | unfortunate 0.29appalling 0.29danger 0.28bad 0.28lendl 0.28 |
| C (SST) | + 0.85 | besotted 0.84allegedly 0.83unfulfilling 0.83dungeons 0.83 | phenomenal 0.82lanes 0.82retread 0.82inspired 0.81snl 0.81 |
| C (text8) | horrible 0.72 | horrific 0.71terrifying 0.70irreparable 0.69misfortune 0.69 | pestilence 0.68calamity 0.68wanton 0.67sorrow 0.67cruel 0.67 |
| G | horrible 0.92 | horrendous 0.85dreadful 0.80awful 0.75horrid 0.72 | atrocious 0.69horrific 0.68bad 0.68appalling 0.68horrible_horrible 0.67 |
| G-ft | horrible 0.89 | dreadful 0.80awful 0.78atrocious 0.72horrid 0.71 | appalling 0.70horrific 0.68lousy 0.67hideous 0.67clockstoppers 0.67 |
| Model | Top-1 | Top-2 to 5 | Top-6 to 10 |
|---|---|---|---|
| A (SST) | raving 0.59 | trek 0.59high-powered 0.58pop-induced 0.57jake 0.57 | bestowed 0.57anteing 0.56wattage 0.56lone 0.56indomitability 0.55 |
| A (text8) | trek 0.70 | stars 0.64eridani 0.56spangled 0.55procyon 0.55 | duetted 0.54ophiuchus 0.54gazer 0.54shatterpoint 0.54teleporters 0.54 |
| B (SST) | winners 0.33 | kevin 0.31splendid 0.30has 0.30acting 0.30 | pulls 0.30watstein 0.29contributes 0.29dustin 0.28teaming 0.28 |
| B (text8) | stars 0.57 | attractiva 0.36spoor 0.36kzin 0.35planet 0.35 | galaxies 0.34brightest 0.34bedivere 0.34mckellen 0.34amias 0.33 |
| C (SST) | jake 0.88 | rising 0.87gyllenhaal 0.85charismatic 0.85top-billed 0.82 | pop-induced 0.77willis 0.74bestowed 0.73high-powered 0.73kevin 0.73 |
| C (text8) | stars 0.64 | trek 0.63centauri 0.52ophiuchus 0.50prequels 0.49 | brightest 0.49procyon 0.49shatterpoint 0.48eclipsing 0.47gazer 0.47 |
| G | stars 0.78 | superstar 0.73starlet 0.64megastar 0.62heart_throb 0.57 | heartthrob 0.54superstars 0.53standout 0.52stardom 0.52hunk 0.51 |
| G-ft | superstar 0.75 | stars 0.74gyllenhaal 0.60top-billed 0.60pop-induced 0.58 | first-rate 0.58standout 0.58starring 0.56huston 0.56legend 0.55 |
| Model | Top-1 | Top-2 to 5 | Top-6 to 10 |
|---|---|---|---|
| A (SST) | rinzler 0.71 | water-born 0.70shimmering 0.70hennings 0.69lisa 0.69 | l. 0.69conrad 0.68italicized 0.68robotically 0.68pitted 0.67 |
| A (text8) | expressionistic 0.63 | bafta 0.60shazam 0.58screenwriting 0.57cine 0.57 | cinematographer 0.57filmmaking 0.57elmes 0.57rashomon 0.57desaturated 0.56 |
| B (SST) | color 0.38 | gantz 0.38beaches 0.37mattei 0.37hotels 0.36 | improbability 0.36acting 0.35lumpen 0.35procedural 0.35reggio 0.34 |
| B (text8) | film 0.41 | horror 0.37photography 0.36oscar 0.36films 0.36 | director 0.35picture 0.34projector 0.33vangelis 0.33smeeton 0.33 |
| C (SST) | hennings 0.90 | water-born 0.88dubbed 0.88naturalistic 0.87murky 0.87 | shimmering 0.86phenomenal 0.86robotically 0.86atrocious 0.84acute 0.84 |
| C (text8) | bafta 0.74 | cine 0.73versatility 0.73elmes 0.73directorial 0.73 | vangelis 0.73filmmaking 0.72expressionistic 0.71wuxia 0.70filmfare 0.70 |
| G | camerawork 0.77 | cinematographer 0.75Cinematography 0.70Cinematographer 0.67cinematography_editing 0.63 | cinematographers 0.63Best_Cinematography 0.62visual_effects 0.60filmmaking 0.60visuals 0.59 |
| G-ft | camerawork 0.76 | cinematographer 0.75visuals 0.61screenplay 0.59photography 0.59 | choreography 0.58filmmaking 0.56helmer 0.55lensing 0.54narration 0.54 |
| Model | Top-1 | Top-2 to 5 | Top-6 to 10 |
|---|---|---|---|
| A (SST) | of 0.40 | deleting 0.36outward 0.35tully 0.351987 0.35 | unambitious 0.35screenplays 0.35hubristic 0.35homeric 0.35indulges 0.35 |
| A (text8) | of 0.73 | and 0.71in 0.70a 0.69to 0.60 | s 0.58one 0.56platforming 0.56which 0.56thq 0.55 |
| B (SST) | our 0.22 | his 0.21current 0.19dong 0.16whose 0.15 | german 0.15of 0.15my 0.15in 0.14art 0.14 |
| B (text8) | a 0.44 | its 0.42this 0.37another 0.35their 0.31 | s 0.29an 0.29our 0.28his 0.28lindesfarne 0.26 |
| C (SST) | inside-show-biz 0.94 | producing 0.93pierce 0.93silent 0.931790 0.93 | savaged 0.93democratic 0.93shoulder 0.92worlds 0.92indulges 0.92 |
| C (text8) | nonparticipation 0.63 | xviith 0.63maastrichtian 0.62kingdomtide 0.62jedda 0.62 | jurua 0.62latitudinal 0.62of 0.62centromedian 0.61unpredicted 0.61 |
| G | this 0.59 | in 0.54that 0.53ofthe 0.52another 0.47 | however 0.47one 0.47entire 0.46its 0.46which 0.46 |
| G-ft | of 0.63 | . 0.592002 0.58spielberg 0.54entire 0.54 | salton 0.53self-conscious 0.53pacino 0.53revenge-of-the-nerds 0.52auteuil 0.52 |
visuals, screenplay and photography enter
cinematography, and storyline enters plot.
The three SST-trained models return almost noise for every query. Their 633,720-token corpus
does not contain enough co-occurrence evidence to organize the words reliably. The
similarity benchmarks measure that gap directly.terrible gives horrible for all three, and B's plot
gives storylines and storyline. Some neighbours now come from
encyclopedia topics rather than film reviews, such as trek for
star. More training text compares the two corpora in
full.king - man + woman = queen is the canonical test of whether an embedding space supports this kind of arithmetic.
Below it are four queries built from film-review vocabulary. Every word in
those four occurs in SST, so the SST-trained models cannot miss them for lack of
vocabulary. The standard Google analogy benchmark follows.
queen| Model | Top answer | Ranks 2 to 4 |
|---|---|---|
| A (SST) | scorpion 0.54 | lion 0.50lear 0.50nuts 0.49 |
| A (text8) | queen 0.48 | infanta 0.43hainault 0.43forkbeard 0.43 |
| B (SST) | sugar 0.39 | abbott 0.36ernest 0.36wildcard 0.35 |
| B (text8) | queen 0.44 | kings 0.39jehu 0.37monarch 0.34 |
| C (SST) | middle-aged 0.71 | lion 0.71creek 0.70haynes 0.70 |
| C (text8) | queen 0.51 | kings 0.42consort 0.42isabella 0.41 |
| G | queen 0.71 | monarch 0.62princess 0.59crown_prince 0.55 |
| G-ft | queen 0.70 | princess 0.60prince 0.57queens 0.56 |
actress| Model | Top answer | Ranks 2 to 4 |
|---|---|---|
| A (SST) | davies 0.47 | macdowell 0.46michel 0.46stoop 0.46 |
| A (text8) | actress 0.70 | comedienne 0.54singer 0.54gingold 0.50 |
| B (SST) | enigma 0.32 | actress 0.32unhinged 0.31role 0.30 |
| B (text8) | actress 0.69 | novelist 0.46musician 0.43writer 0.43 |
| C (SST) | succumb 0.65 | academy 0.62madonna 0.61appearing 0.59 |
| C (text8) | actress 0.71 | comedienne 0.55dancer 0.54socialite 0.53 |
| G | actress 0.86 | actresses 0.66thesp 0.63Actress 0.62 |
| G-ft | actress 0.82 | actresses 0.69singer 0.55actors 0.55 |
worse| Model | Top answer | Ranks 2 to 4 |
|---|---|---|
| A (SST) | concert 0.37 | antitrust 0.36einstein 0.36hungry-man 0.36 |
| A (text8) | worse 0.48 | smarter 0.42mattered 0.40anemic 0.40 |
| B (SST) | i.q. 0.32 | franchise 0.29further 0.29funnier 0.28 |
| B (text8) | more 0.41 | less 0.39fewer 0.38tougher 0.37 |
| C (SST) | enacted 0.71 | badder 0.69videotape 0.69runner 0.69 |
| C (text8) | worse 0.54 | happier 0.46slower 0.46smarter 0.45 |
| G | worse 0.73 | uglier 0.57sooner 0.53dumber 0.52 |
| G-ft | worse 0.66 | uglier 0.55differently 0.53scarier 0.51 |
best| Model | Top answer | Ranks 2 to 4 |
|---|---|---|
| A (SST) | moronic 0.36 | drowns 0.36resources 0.36bloated 0.35 |
| A (text8) | best 0.45 | razzie 0.42evar 0.41saddest 0.40 |
| B (SST) | parents 0.31 | teen-driven 0.28made 0.28shining 0.28 |
| B (text8) | greatest 0.33 | best 0.29toughest 0.27last 0.26 |
| C (SST) | moronic 0.69 | screenplays 0.69simmer 0.69sporting 0.66 |
| C (text8) | best 0.45 | greatest 0.44razzie 0.44evar 0.41 |
| G | best 0.69 | strongest 0.63greatest 0.57weakest 0.57 |
| G-ft | best 0.58 | strongest 0.57finest 0.56highest 0.56 |
horror| Model | Top answer | Ranks 2 to 4 |
|---|---|---|
| A (SST) | school-age 0.42 | zippy 0.42quadrangle 0.41dumb 0.41 |
| A (text8) | docu 0.51 | sitcoms 0.51screwball 0.51slapstick 0.51 |
| B (SST) | flick 0.36 | opens 0.28drama 0.28innovations 0.27 |
| B (text8) | screwball 0.33 | comedies 0.32scene 0.31mgm 0.31 |
| C (SST) | gross-out 0.76 | psychotic 0.76pandering 0.75aspires 0.74 |
| C (text8) | screwball 0.63 | drama 0.63comedies 0.62stardom 0.61 |
| G | horror_flick 0.55 | horror 0.51horror_thriller 0.51terrifying 0.51 |
| G-ft | gross-out 0.53 | frightening 0.50scarier 0.50dramas 0.50 |
queen first for
king - man + woman. Trained on SST alone, A, B and C return unrelated
words.actress second for actor - man + woman. G and G-ft put the
expected word first for the actor, better and worst queries. The text8 models do better
but not uniformly: all three rank actress first, A (text8) and C (text8)
also solve the better and worst queries, and B (text8) solves neither. For comedy - funny + scary, G returns
horror_flick and horror, and G-ft returns gross-out
and frightening. The SST-only models fail even on their own
vocabulary.An analogy works when the offset between two words, such as
man to woman, points the same way for other pairs, such as
king to queen and actor to actress.
A model learns a shared direction like that only after it sees each word in many
different contexts. In the 6,920 training sentences, the
expected answers appear between 11 and 131 times, and even the most
common query word appears only 214 times. The
table gives each count next to the count in the phrase rows the models were trained
on.
| Query | Occurrences: sentences / phrase rows |
|---|---|
king - man + woman | king 13 / 50man 65 / 313woman 29 / 153queen 11 / 43 |
actor - man + woman | actor 26 / 163man 65 / 313woman 29 / 153actress 16 / 89 |
better - good + bad | better 108 / 532good 214 / 1341bad 149 / 907worse 17 / 122 |
worst - bad + good | worst 40 / 271bad 149 / 907good 214 / 1341best 131 / 807 |
comedy - funny + scary | comedy 212 / 1053funny 181 / 1105scary 19 / 97horror 36 / 187 |
The phrase counts overstate what the models learned from. Most
phrase rows are fragments of those same sentences (see the data
section), so queen appears 43 times but in only
11 places in the original text. GoogleNews was trained on about
100 billion tokens, more than 150,000 times the 633,720
tokens here. The similarity benchmarks agree: on WordSim-353, A scores
+0.029, B -0.036 and C
+0.005, against G's +0.700.
Retraining A, B and C on text8 confirms the explanation. With
17,005,207 tokens and the same hyperparameters, all three
answer queen, and their analogy accuracy rises to
0.372,
0.314 and
0.353. See
More training text.
Sentiment classification holds up anyway. A reaches 0.761 on SST-2 against G's 0.798. A classifier over averaged vectors only needs positive and negative words to separate roughly. That is a much coarser property than consistent analogy offsets, so the two evaluations measure different things.
| Model | Analogy accuracy | Questions attempted | Coverage | Candidate pool |
|---|---|---|---|---|
| A (SST) | 0.0006 | 3,563 of 19,544 | 18.2% | top 50,000 |
| A (text8) | 0.3721 | 15,790 of 19,544 | 80.8% | top 50,000 |
| B (SST) | 0.0020 | 3,563 of 19,544 | 18.2% | top 50,000 |
| B (text8) | 0.3142 | 15,790 of 19,544 | 80.8% | top 50,000 |
| C (SST) | 0.0022 | 3,563 of 19,544 | 18.2% | top 50,000 |
| C (text8) | 0.3535 | 15,790 of 19,544 | 80.8% | top 50,000 |
| G | 0.7561 | 15,434 of 19,544 | 79.0% | top 50,000 |
| G-ft | 0.6750 | 3,563 of 19,544 | 18.2% | top 50,000 |
Accuracy needs to be read alongside coverage. gensim drops any question with an out-of-vocabulary word, so the SST-trained models are scored on only 18.2% of the set against G's 79.0%. G-ft's 0.675 comes from structure inherited through the warm start, not learned from SST.
A model stores each word as 300 numbers, which can't be drawn directly. PCA and t-SNE are two standard ways to squeeze them down to two, so every word becomes a dot on a page. PCA keeps the two directions along which the words vary most. t-SNE tries to keep each word's nearest neighbours close, at the cost of distorting larger distances. If a model has learned what words mean, related words should land near each other.
To test that, I picked 32 words before looking at any plot, eight
from each of four groups: positive words (good, charming),
negative words (dull, tedious), filmmaking terms
(screenplay, editing) and genres (horror,
western). Each dot is coloured by its group.
Clusters are easy to imagine in a scatter plot, so each one also gets a silhouette score. It compares how close a word sits to its own group against how close it sits to the nearest other group, and runs from -1 to 1. Near 0 means the groups are mixed together; higher means they form separate clumps. The plots below show G-ft, the clearest case, and A trained on each corpus.
PCA, Model G-ft. The two axes keep 16.2% and 9.6% of the variance. Silhouette score +0.164.
t-SNE, Model G-ft. Perplexity 10. Silhouette score +0.187.
PCA, Model A (SST). The two axes keep 8.6% and 7.5% of the variance. Silhouette score +0.036.
t-SNE, Model A (SST). Perplexity 10. Silhouette score +0.051.
PCA, Model A (text8). The two axes keep 11.7% and 7.8% of the variance. Silhouette score +0.066.
t-SNE, Model A (text8). Perplexity 10. Silhouette score +0.063.
A flat picture throws most of the information away. The first two PCA axes keep between 16% and 37% of the variance, depending on the model. So the last two score columns skip the projection and measure the same thing on the full 300-dimensional vectors, using cosine distance. The last of those asks only whether positive and negative words form separate groups.
| Model | 2-D, PCA | 2-D, t-SNE | 300-D, all groups | 300-D, positive vs negative |
|---|---|---|---|---|
| A (SST) | +0.036 | +0.051 | +0.063 | +0.076 |
| A (text8) | +0.066 | +0.063 | +0.054 | +0.035 |
| B (SST) | +0.035 | -0.033 | +0.075 | +0.059 |
| B (text8) | +0.072 | -0.107 | +0.039 | +0.004 |
| C (SST) | -0.004 | +0.110 | +0.142 | +0.126 |
| C (text8) | +0.050 | +0.063 | +0.060 | +0.035 |
| G | +0.120 | +0.121 | +0.141 | +0.211 |
| G-ft | +0.164 | +0.187 | +0.147 | +0.195 |
good and
bad in the same kinds of sentence, so the vectors for praise and criticism
end up close together. That fits the drop in sentiment accuracy described under
More training text.This analysis is included because sentiment accuracy alone makes the embeddings look more capable than they are.
The three benchmarks compare cosine similarity with human ratings using Spearman correlation. Coverage is the fraction of pairs where both words are in the vocabulary. It is part of the result: the SST-trained models cover only about half of WordSim-353 because many benchmark words never occur in the movie reviews.
| Model | WordSim-353 | SimLex-999 | MEN-3k | Coverage | SST-2 accuracy |
|---|---|---|---|---|---|
| A (SST) | +0.029 | +0.045 | +0.118 | 50.1% | 0.761 |
| A (text8) | +0.694 | +0.341 | +0.645 | 94.3% | 0.722 |
| B (SST) | -0.036 | +0.069 | -0.010 | 50.1% | 0.729 |
| B (text8) | +0.666 | +0.259 | +0.606 | 94.3% | 0.724 |
| C (SST) | +0.005 | +0.033 | +0.096 | 50.1% | 0.744 |
| C (text8) | +0.644 | +0.332 | +0.567 | 94.3% | 0.715 |
| G | +0.700 | +0.442 | +0.771 | 100.0% | 0.798 |
| G-ft | +0.585 | +0.405 | +0.702 | 50.1% | 0.792 |
tiger to sit near
cat. Downstream accuracy by itself would make these embeddings look nearly
as good as GoogleNews, which the intrinsic tests clearly contradict. The text8 rows are
the same three models trained on more text, and they score close to GoogleNews;
More training text covers them.This also clarifies what the warm start contributes. G-ft scores 0.585 on WordSim-353 against 0.029 for A, trained from scratch on the identical corpus with identical settings. The pretrained initialization does more than add 0.031 accuracy. It supplies all of Model G-ft's measurable lexical structure.
The sections above blame the size of the training data for the failures of A, B and C on similarity and analogies. To test that directly, I retrained all three on text8, the first 100 MB of cleaned English Wikipedia (mattmahoney.net/dc/text8.zip). It has 17,005,207 tokens, 27 times the SST phrase corpus. Every hyperparameter matches the SST runs. One implementation detail differs: C's text8 run uses sparse Adam, which updates only the rows a batch touches, because dense Adam is too slow at this vocabulary size (see Cost to run). C (text8) also trained on a PACE ICE A100 GPU, so its training time is not comparable with the laptop times. The sentiment test is also unchanged: the classifier is still fit on the SST phrase labels and scored on the same SST-2 test sentences, so only the word vectors differ.
| Model | Tokens | WordSim | Analogies | king − man + woman | SST-2 acc. | OOV | Train time |
|---|---|---|---|---|---|---|---|
| A (SST) | 634k | +0.029 | 0.001 | scorpion | 0.761 | 6.6% | 11.8 s |
| A (text8) | 17M | +0.694 | 0.372 | queen | 0.722 | 16.9% | 889.3 s |
| B (SST) | 634k | -0.036 | 0.002 | sugar | 0.729 | 6.6% | 3.6 s |
| B (text8) | 17M | +0.666 | 0.314 | queen | 0.724 | 16.9% | 176.6 s |
| C (SST) | 634k | +0.005 | 0.002 | middle-aged | 0.744 | 6.6% | 160.2 s |
| C (text8) | 17M | +0.644 | 0.353 | queen | 0.715 | 16.9% | 658.7 s (A100) |
| G | 100B | +0.700 | 0.756 | queen | 0.798 | 27.1% | - |
queen for
king - man + woman. The
analogy tables and neighbour lists
include the text8 models as extra rows.n't is missing, and it occurs in 129 of the
1,821 test sentences. Review vocabulary is missing too:
refreshingly, soggy, mesmerizing, sappy, clunker, heartwarming
are all in the SST vocabulary but not in text8's, and several of them are strong
sentiment words. Wikipedia teaches general word meaning. SST teaches the words
reviewers use to praise and criticize, and the sentiment test rewards that.Page 1 of the handout makes two claims about the architectures that the two corpora can test. CBOW trains several times faster. On text8, B took 177 seconds against A's 889, a 5.0× difference (963,171 against 191,213 words per second). The claim holds. Skip-gram does better on small data, and CBOW needs large data. On SST, skip-gram leads CBOW by 0.015 in sentiment accuracy averaged over three seeds, and neither has any similarity structure. On text8, the accuracy gap disappears (+0.002 for B), while A still leads on WordSim-353 by 0.028 and on analogies by 0.058. CBOW closes the gap as the data grows, which fits the claim, but skip-gram stays ahead on the finer-grained tests. The text8 figures are single runs. On SST, the hyperparameter sweep puts the seed-to-seed standard deviation of accuracy at 0.002 to 0.007, so the text8 accuracy gap is within noise. The WordSim-353 and analogy gaps are far larger than that.
| Model | Errors / 1,821 | Negation | Contrast | Other |
|---|---|---|---|---|
| G | 368 | 102 | 64 | 202 |
| G-ft | 379 | 96 | 64 | 219 |
| A (SST) | 435 | 101 | 72 | 262 |
| C (SST) | 466 | 114 | 79 | 273 |
| B (SST) | 493 | 120 | 62 | 311 |
Two test examples Model G-ft, the fine-tuned one, gets right and two it gets wrong. All four come from the same 1,821-sentence test split. Within each outcome, these are the highest-confidence cases.
| Outcome | Gold | Predicted | Confidence | Sentence |
|---|---|---|---|---|
| correct | positive | positive | 0.999 | an intelligent , moving and invigorating film . |
| correct | positive | positive | 0.998 | a smart , sweet and playful romantic comedy . |
| incorrect | negative | positive | 0.952 | it 's a great deal of sizzle and very little steak . |
| incorrect | negative | positive | 0.938 | a well acted and well intentioned snoozer . |
| Model | Sentence | Gold | Predicted | Confidence | Category |
|---|---|---|---|---|---|
| A (SST) | not a bad journey at all . | pos | neg | 0.958 | negation |
| A (SST) | an ultra-low-budget indie debut that smacks more of good intentions than talent . | neg | pos | 0.917 | other |
| A (SST) | a well acted and well intentioned snoozer . | neg | pos | 0.898 | other |
| G-ft | never -lrb- sinks -rrb- into exploitation . | pos | neg | 0.990 | negation |
| G-ft | there is n't a weak or careless performance amongst them . | pos | neg | 0.973 | negation |
| G-ft | despite the long running time , the pace never feels slack -- there 's no scene … | pos | neg | 0.955 | negation |
The failures follow directly from the representation.
not a bad journey at all averages not and bad into
negative territory. there is n't a weak or careless performance amongst them
pools two strongly negative adjectives without preserving the negation that reverses
them. In a great deal of sizzle and very little steak, the negative meaning
comes from the contrast between clauses, which averaging also removes.
A Word2Vec model comes down to two matrices and a dot product. It has
no hidden layer or nonlinearity. W_in stores one row per word and becomes the
final embedding table. W_out is used for the training objective, then
discarded.
A and C use skip-gram with negative sampling. A centre word predicts each surrounding word independently. Each observed pair is scored against 10 negative samples from the unigram distribution raised to 0.75, avoiding a softmax over all 14,309 words.
B uses CBOW with hierarchical softmax. The context rows are averaged into one vector, which predicts the centre word. A binary tree over the vocabulary reduces one prediction from V decisions to log2(V).
W_in is the encoder, its
300-dimensional row is the code, W_out is the decoder, and the predicted
context word is the output.The sentiment data comes from SST-2, but its two releases cannot be
swapped freely. GLUE replaces every test label with -1 because the split is reserved for
its leaderboard. I use the labelled SetFit test split instead. src/data.py
raises an error unless both classes appear in the loaded test labels.
| Split | Source | Rows | Tokens | Mean length | Positive | Used for |
|---|---|---|---|---|---|---|
| train | stanfordnlp/sst2 (phrase level) | 67,348 | 633,720 | 9.4 | 55.8% | embedding training and classifier fitting |
| dev | SetFit/sst2 | 872 | 17,046 | 19.5 | 50.9% | held out, unused |
| test | SetFit/sst2 | 1,821 | 35,023 | 19.2 | 49.9% | every number on this page |
Five training examples and four test examples, two positive and two negative. Each example was selected by a stated rule rather than picked by eye.
| Selected for | Text | Gold label |
|---|---|---|
| positive, plain | that loves its characters and communicates something rather beautiful about human nature | positive |
| negative, plain | remains utterly satisfied to remain the same throughout | negative |
| negation | for those moviegoers who complain that ` they do n't make movies like they used to … | negative |
| contrastive clause | the plot is nothing but boilerplate clichés from start to finish , | negative |
| film-domain vocabulary | , good action , good acting , good dialogue , good pace , good cinematography . | positive |
| Selected for | Text | Gold label |
|---|---|---|
| positive | this is one of polanski 's best films . | positive |
| positive | finally , a genre movie that delivers -- in a couple of genres , no less . | positive |
| negative | arnold 's jump from little screen to big will leave frowns on more than a few faces . | negative |
| negative | no movement , no yuks , not much of anything . | negative |
what 's next ? in both training and test data. I
removed it. There was no overlap with dev, and the training count fell from 67,349 to
67,348 rows.A, B and C were also trained on text8, the first 100 MB of an English
Wikipedia dump cleaned by Matt Mahoney
(mattmahoney.net/dc/text8.zip).
It has 17,005,207 tokens and a vocabulary of
135,335 words at min_count=2. The text contains only
lowercase letters and spaces. Punctuation is removed and numbers are spelled out digit
by digit, so 1989 becomes one nine eight nine. text8 is used
only to train word vectors; the classifier and every test stay on SST. The file is
downloaded by src/run_text8.py rather than stored in the repository.
The pretrained baseline is GoogleNews-300, a skip-gram model with negative sampling trained on roughly 100 billion news tokens. It comes from code.google.com/archive/p/word2vec, is loaded through gensim-data, and is capped at the 500,000 most frequent words. I did not use GloVe as the pretrained baseline because it factorizes a co-occurrence matrix rather than training Word2Vec. That would change the question being tested.
| Field | Value |
|---|---|
| Model | GoogleNews-vectors-negative300 |
| Reference | Mikolov, Sutskever, Chen, Corrado and Dean (2013), Distributed Representations of Words and Phrases and their Compositionality, NIPS. arxiv.org/abs/1310.4546 |
| Distribution URL | code.google.com/archive/p/word2vec, fetched through gensim-data as word2vec-google-news-300 |
| Training corpus | Google News, roughly 100 billion tokens. The corpus was not released, so there is no public corpus link. |
| Architecture | Skip-gram with negative sampling, 300 dimensions, 3M words and phrases |
| Test set used here | Google analogy set (questions-words.txt), 19,544 questions, shipped in data/eval/ |
| Accuracy, measured here | 0.7561 across 15,434 attempted questions (79.0% coverage, with the candidate pool limited to the top 50,000 words) |
| Accuracy, as published | Not quoted. The Google Code archive does not expose figures in a form that can be fetched, and its linked papers report results for the models studied in those papers, not this released file. I report the measured result above with its exact conditions instead of attaching an unverified published number to the model. |
A and B intentionally change two things together: the architecture and the loss. All other settings stay fixed, so the comparison is between the two standard Word2Vec configurations. The sweep below separates the two changes.
| A (SST) | B (SST) | C (SST) | G | G-ft | A2 | |
|---|---|---|---|---|---|---|
| Architecture (sg) | 1 | 0 | 1 | 1 | 1 | 1 |
| Hierarchical softmax | 0 | 1 | 0 | 0 | 0 | 0 |
| Negatives | 10 | 0 | 10 | 5 | 10 | 10 |
| Dimensions | 300 | 300 | 300 | 300 | 300 | 300 |
| Window | 5 | 5 | 5 | 5 | 5 | 5 |
| Min count | 2 | 2 | 2 | 5 | 2 | 2 |
| Epochs | 10 | 10 | 10 | not reported | 8 | 8 |
| Initial LR | 0.025 | 0.025 | 0.001 | 0.025 | 0.005 | 0.005 |
| Subsample threshold | 0.001 | 0.001 | 0.001 | 1e-05 | 0.001 | 0.001 |
Each setting below was trained 3 times on the SST phrase corpus, with seeds 42, 43, 44. The tables give the mean and standard deviation across seeds. One factor changes at a time, and everything else stays at A's or B's settings. Training time is the mean wall clock on the M2 Air.
| Setting | SST-2 accuracy | WordSim-353 | MEN-3k | Training time |
|---|---|---|---|---|
| skip-gram + NS | 0.752 ± 0.006 | +0.008 ± 0.018 | +0.122 ± 0.008 | 15.2 ± 0.9 s |
| skip-gram + HS | 0.752 ± 0.006 | +0.043 ± 0.014 | +0.042 ± 0.006 | 13.7 ± 0.5 s |
| CBOW + NS | 0.735 ± 0.005 | -0.005 ± 0.019 | +0.128 ± 0.004 | 5.8 ± 0.1 s |
| CBOW + HS | 0.737 ± 0.005 | -0.002 ± 0.018 | -0.000 ± 0.004 | 6.3 ± 0.6 s |
| Setting | SST-2 accuracy | WordSim-353 | MEN-3k | Training time |
|---|---|---|---|---|
| A, window 2 | 0.738 ± 0.002 | +0.028 ± 0.008 | +0.130 ± 0.002 | 11.2 ± 0.4 s |
| A, window 5 | 0.752 ± 0.006 | +0.008 ± 0.018 | +0.122 ± 0.008 | 15.2 ± 0.9 s |
| A, window 10 | 0.755 ± 0.005 | +0.029 ± 0.020 | +0.095 ± 0.002 | 26.1 ± 1.7 s |
| B, window 2 | 0.715 ± 0.002 | -0.006 ± 0.013 | +0.010 ± 0.010 | 4.8 ± 0.1 s |
| B, window 5 | 0.737 ± 0.005 | -0.002 ± 0.018 | -0.000 ± 0.004 | 6.3 ± 0.6 s |
| B, window 10 | 0.741 ± 0.007 | -0.014 ± 0.010 | +0.005 ± 0.008 | 7.1 ± 1.4 s |
| Setting | SST-2 accuracy | WordSim-353 | MEN-3k | Training time |
|---|---|---|---|---|
| A, 50 dims | 0.746 ± 0.006 | +0.007 ± 0.006 | +0.104 ± 0.009 | 6.6 ± 0.3 s |
| A, 100 dims | 0.751 ± 0.007 | +0.018 ± 0.019 | +0.106 ± 0.009 | 8.8 ± 0.2 s |
| A, 300 dims | 0.752 ± 0.006 | +0.008 ± 0.018 | +0.122 ± 0.008 | 15.2 ± 0.9 s |
| B, 50 dims | 0.681 ± 0.004 | -0.013 ± 0.012 | +0.012 ± 0.007 | 2.8 ± 0.3 s |
| B, 100 dims | 0.689 ± 0.003 | +0.020 ± 0.026 | +0.005 ± 0.003 | 3.2 ± 0.1 s |
| B, 300 dims | 0.737 ± 0.005 | -0.002 ± 0.018 | -0.000 ± 0.004 | 6.3 ± 0.6 s |
| Setting | SST-2 accuracy | WordSim-353 | MEN-3k | Training time |
|---|---|---|---|---|
| A, 5 negatives | 0.761 ± 0.004 | +0.008 ± 0.022 | +0.121 ± 0.004 | 18.5 ± 4.7 s |
| A, 10 negatives | 0.752 ± 0.006 | +0.008 ± 0.018 | +0.122 ± 0.008 | 15.2 ± 0.9 s |
| A, 20 negatives | 0.760 ± 0.004 | +0.018 ± 0.003 | +0.125 ± 0.009 | 38.4 ± 6.7 s |
Wider windows help both models. Going from a window of 2 to 10 raises A from 0.738 to 0.755 and B from 0.715 to 0.741. For skip-gram it also more than doubles training time, from 11.2 to 26.1 seconds, because every extra context word is another prediction. CBOW needs more dimensions than skip-gram. B gains 0.056 going from 50 to 300 dimensions, while A gains only 0.006. The number of negatives shows no clear trend. 5, 10 and 20 negatives give 0.761, 0.752 and 0.760. The middle setting is the lowest, which fits no trend, and with three seeds a gap that small cannot be separated from seed noise. 20 negatives take 38 seconds.
Training times drift as the fanless M2 Air warms up. The 10-negative settings were the first runs of the sweep, on a cool machine, and came out faster than the 5-negative runs even though they do more work. Small time differences between settings are therefore not reliable.
Fine-tuning Word2Vec is much simpler than fine-tuning a transformer.
There are no frozen layers or adapters. I initialize W_in with published
vectors, then continue ordinary skip-gram training on movie reviews at a low learning
rate.
intersect_word2vec_format only overwrites rows that
already exist. It does not import Google's three million words, so G-ft keeps the
vocabulary built from SST.vectors_lockf to ones explicitly
gensim 4.x does not create it. Without it the import either fails
or silently freezes every row, leaving the imported vectors unchanged.W_out
starts random. Early updates must learn a new decoder as well as adjust the imported
vectors. A standard learning rate distorts those vectors during the first
epoch.Writing the training loop makes each part
of Word2Vec concrete.
src/sgns.py implements the vocabulary and counts, subsampling of frequent
words, the unigram^0.75 noise table, a dynamic window, the two embedding matrices, and
linear learning-rate decay. to_keyedvectors wraps W_in in a
gensim object, which lets C use the same evaluation code as every other model.
| A, gensim | C, from scratch | |
|---|---|---|
| SST-2 accuracy | 0.7611 | 0.7441 |
| Wall clock | 11.8 s | 160.2 s |
| Words per second | 537,887 | 39,571 |
| Loss, first to last epoch | not exposed | 4.2288 to 2.8681 |
BCEWithLogitsLoss once on the positives and once on the negatives averages
over B entries and over B·k entries, so at a batch of
8,192 the effective per-pair learning rate was about 3e-6.
The measured gradient norm on W_in was exactly 0.0. I fixed it by writing
Mikolov's equation 4 directly, summing across the k negatives, and averaging only across
the batch.Two component checks made the failure quick to locate. Subsampling
retains 17.6% of occurrences of
the. The noise table maps the from a raw frequency of 4.30%
down to a sampled 1.31% while lifting execrable from effectively zero to
2e-5. Both results match the expected effect of the 0.75 exponent.
Query latency measures brute-force most_similar, which runs
a dense matrix-vector product over the full vocabulary. The mean, p50 and p95 per
query all come from the same 200 calls, cycling through the five
query words after one untimed warm-up call each. Memory is the RSS increase in an isolated subprocess,
compared with the size of the matrices the model retains.
| Model | Vocab | Mean ms | p50 ms | p95 ms | Keeps | Predicted MB | Measured MB | Ratio |
|---|---|---|---|---|---|---|---|---|
| A (SST) | 14,309 | 0.69 | 0.38 | 2.29 | 2 | 34.3 | 35.0 | 1.02 |
| B (SST) | 14,309 | 1.27 | 0.45 | 4.50 | 2 | 34.3 | 48.0 | 1.40 |
| C (SST) | 14,309 | 0.74 | 0.42 | 2.74 | 1 | 17.2 | 17.8 | 1.03 |
| G | 500,000 | 29.90 | 19.23 | 72.32 | 1 | 600.0 | 195.6 | 0.33 |
| G-ft | 14,309 | 1.15 | 0.49 | 4.06 | 2 | 34.3 | 34.8 | 1.01 |
The 2 · V · d · 4 prediction holds
within 3% for A, G-ft and C. B comes in at
1.40 because hierarchical softmax also
keeps Huffman-tree code and point arrays that the formula omits.
ru_maxrss to fall below the allocation. A Linux run should land near
600 MB if that explanation is correct. Until then, the gap
remains unresolved.A separate benchmark determined how C trains. On this vocabulary, MPS is slower than CPU (64.3 against 44.6 ms per batch) and sparse gradients are slower than dense gradients (52.6 against 44.6). The model is small enough for GPU launch and data transfer overhead to dominate. Sparse updates also offer little benefit. A batch of 8,192 pairs with 10 negatives touches roughly 90,000 index slots across 14,309 rows, so almost every row updates on each step.
Four setup and measurement problems took most of the debugging time. In each case, the visible error pointed away from the actual cause. The symptoms and fixes are recorded here.
import gensim fails on a fresh unpinned install
gensim 4.3.x imports scipy.linalg.triu, which scipy
1.13 removed. The ImportError points at gensim even though the incompatible scipy
version is the cause. requirements.txt pins scipy<1.13
and numpy<2.src/data.py
prevents that by requiring two classes in the test labels.src/measure_mem.py now measures an RSS delta in an isolated
subprocess per model.After pip install -r requirements.txt, these commands
produce the results the page is built from, in order:
python -m src.data
corpus statisticspython -m src.main
trains A and B on SST and loads Gpython -m src.run_e
trains C on SST, 160 seconds on CPUpython -m src.finetune
trains G-ft from the GoogleNews vectors, then the A2 control with
the same schedule and random initializationpython -m src.run_eval, python -m src.measure_mem,
python -m src.run_analogies, python -m src.testcases
similarity, latency, memory, errors, analogies and the worked test
examplespython -m src.examples
the example tables for training data and for G-ft's right and wrong calls, read back from
the data and from G-ft's mined errorspython -m src.run_text8
downloads text8 and retrains A and B on it, about
18 minutespython -m src.run_e --text8
trains C on text8. On a GPU cluster, sbatch slurm/c_text8.sbatch
runs the same command; it saves a checkpoint after every epoch, so an interrupted job
resumes where it stopped.python -m src.visualize
PCA and t-SNE projections and the cluster scorespython -m src.sweep
the hyperparameter sweeppython -m src.build_report
rebuilds both report variantssrc/build_report.py reads every reported figure from
results/*.json when it builds the page. Re-running a model and rebuilding
therefore updates the prose and tables together. gensim training with four workers
is not deterministic, so rerunning a model shifts its scores by roughly the seed spread
measured in the sweep.