N-grams, Step by Step

N-grams, Step by Step

A language model predicts the next word as a probability for every word in the vocabulary. An n-gram model gets those probabilities by counting sequences of words in a corpus and dividing. We start with Shakespeare: first single words counted play by play, then word sequences across all his works. Then we take the counting apart on three tiny sentences.

What you will learn on this page

  1. Words and texts can be counted into vectors, and the cosine compares their directions: how similar two plays, or two words, are. → section 1
  2. An n-gram model predicts the next word from the last n−1 words by counting and dividing: P(next | context) = Count(context, next) / Count(context). → sections 2, 4
  3. A longer context sounds more like the text, and copies more of it: long word sequences are rare, so their counts are sparse. → sections 2, 3
  4. Greedy writing takes the most probable next word; sampling draws one by its probability. → section 5
  5. One unseen pair makes a whole sentence's probability 0; smoothing moves some probability to unseen pairs. → sections 4, 6
  6. Real counts from books: “an aunt of mine” is rare in English, which matters for translation. → section 7

1Shakespeare, counted by play

Count how often each word occurs in each play. Read down a column and a play becomes a list of numbers: a vector. Read across a row and a word becomes a vector too. Similar plays use words in similar proportions, so their vectors point in similar directions.

The drawing shows two dimensions at a time. Similarity below uses all of them.

Similarity of every pair (click a cell)

The arithmetic for the selected pair

Table on the slide: Jurafsky & Martin, Speech and Language Processing, lecture slides on vector semantics. Counted columns: Project Gutenberg eBook #100, so a few numbers differ from the slide's edition.

2Shakespeare, one word at a time

Four models counted from the complete works of Shakespeare. Each one writes a sentence by drawing the next word from the counts, given the last n−1 words. The longer the context, the more it sounds like Shakespeare, and the more it simply quotes him.

Reading the complete works…

only one word ever followed here 2 to 5 choices longest stretch copied word for word from Shakespeare, when longer than the model's context

Click a word to see the model's choices at that step

How sparse are the counts?

There are far more possible word sequences than Shakespeare could ever write, so a long context has usually been seen once, with a single continuation. The 4-gram model then has no choice but to copy.

Example after Jurafsky & Martin, Speech and Language Processing (3rd ed. draft), Ch. 3, Fig. 3.4. Generating text to see what a model has learned goes back to Shannon (1948) and Miller & Selfridge (1950). Text: Project Gutenberg eBook #100, lower-cased, punctuation counted as words, speaker names and stage directions removed.

3Shakespeare or n-gram?

One line is a real sentence from the plays and poems, the other was written by the model. Pick the real one.

Model:
0 / 0

4Count, then divide

The same model, small enough to see every count: three sentences about an aunt and an uncle. Edit the corpus here and every section below updates.

Corpus

Edit the corpus

One sentence per line. Try adding my uncle spoke kindly and watch P(·|my) change.

Count(w1 w2): rows are the first word, columns the next word

The last column is Count(w1): how often the row word is followed by any word. Click a row to divide.

The formula, with this row's numbers

Counting, then dividing. That is the whole model. Every word in the vocabulary gets a probability; most of them get 0 because the pair never occurred.

Smoothing: add k to every count

k = 0

Total probability is always 1. Smoothing takes some of it from the pairs the corpus saw and spreads it over the pairs it never saw. Part of it goes to <UNK>, the slot for every word that is not in the vocabulary: that share is P(<UNK> | word).

kept given away received by an unseen pair received by <UNK>, any word outside the vocabulary

5Generate text with it

Start from a word, look up its row, pick a next word, repeat. Greedy takes the most frequent next word; sampling draws one at random, each word as often as its probability says (see the draw under the bars). Both use the smoothing set in section 4.

6One unseen pair, and the sentence gets 0

The probability of a sentence is the product of one probability per pair of neighboring words. If the corpus never saw one of the pairs, that factor is 0, and so is the whole product. Generation from “my” stopped at “quiet” for the same reason: nothing ever followed “quiet”, so every next word has a count of 0. A word outside the vocabulary is read as <UNK>; try her aunt stayed quiet.

k = 0

7A bigger example: how natural is “an aunt of mine”?

The aunt and uncle corpus has three sentences. Real counts come from much more text. Google Books has counted how often every short word sequence appears in millions of books. Here we compare two n-grams for each noun: “a friend of mine” (4 words) and “my friend” (2 words).

Why? “A friend of mine” picks one friend out of several, and most people have many friends. With close family, “my brother” or “my aunt” usually means one specific person, so “a brother of mine” or “an aunt of mine” sounds marked.

This matters for translation. In Galician, unha tía miña is an ordinary way to introduce an aunt. Its word-for-word English version, “an aunt of mine”, is correct but rare, so a translator writes something like “I had an aunt who…”. The neural translation page comes back to this, with a model trained to write it.

Source: Google Books Ngram Viewer, English, 1990–2019, case-insensitive, averaged over the years. Counted in books, like our sentence, which is from a novel.