Index Ai Academy
Phase 2 · Math, when you need it · Information

Entropy and surprise

Measure uncertainty in bits.

About 25 minutes · A free account opens the whole lesson

Create a free account Try part of it here

Already have an account? Sign in to open this lesson

Why it matters

Some things are easy to predict. After "Thank you for your", the next word is fairly easy to guess: "help", "time", "order". A product code like "XK-7Q2" is not. Information theory puts a number on that difference. It measures uncertainty in units called bits. The same number explains why a zip program shrinks some files a lot and others hardly at all. Most important here, it's the base of the loss function every language model is trained with (cross-entropy, the next lesson). It also tells you how sure a model is about its next word.

What you'll be able to do

  • Measure the surprise of an event in bits
  • Compute the entropy of a distribution as its average surprise
  • Explain why entropy is highest for uniform distributions and zero for certain ones
  • Use entropy to describe how uncertain a model's prediction is

What it covers

  1. How surprising is an event?
  2. Entropy: the average surprise
  3. How sure is the model?
  4. Worked example: two lunch habits
  5. Entropy and compression

How surprising is an event?

A friend texts you: "The sun came up this morning." That tells you nothing new. You were sure it would. Then they text: "It snowed in the desert today." That's real news. You'd never have guessed it.

The rarer an event, the more you learn when it happens. Information theory turns this into a number called surprise. It's also called information content. It's measured in bits.

One bit is the news in a single yes/no answer, when both answers are equally likely. A fair coin is the classic case. Before the flip, you don't know. Afterward, you know one yes/no fact: heads or not. That's 1 bit.

The guessing game

Now play a game. A friend picks one of 8 cards, each equally likely. You may only ask yes/no questions. "Is it one of the first four?" cuts the choices in half. Halve three times and only one card is left. So finding out which card it was is worth 3 bits. Each halving is one bit.

That gives a rule of thumb. Count how many times you'd halve the choices to pin the event down:

  • a 1-in-2 event: one halving, 1 bit;
  • a 1-in-8 event: three halvings, 3 bits;
  • a certain event: nothing to pin down, 0 bits.

You met this kind of counting in the exponentials and logarithms lesson. "How many 2s do I multiply to reach 8?" is log⁡28=3\log_2 8 = 3. So for an event with probability pp, the surprise is:

I(p)=log⁡21p=−log⁡2pbitsI(p) = \log_2 \frac{1}{p} = -\log_2 p \quad \text{bits}

The letter II stands for information. Both forms give the same answer. Books usually write the second one, with the minus sign.

In plain words: flip the probability upside down, then ask "how many 2s multiply to make this?" A 1-in-8 event has surprise log⁡28=3\log_2 8 = 3 bits. For numbers between powers of 2, the answer isn't a whole number. A 1-in-52 event gives about 5.7. The rarer the event, the bigger the surprise.

EventProbabilitySurprise
a certain event10 bits
a fair coin landing heads1/21 bit
a specific card from a deck1/525.7 bits
a 1-in-a-million event0.00000119.9 bits

A one-in-a-million event is only about 20 bits. Each extra bit halves the odds, so the numbers grow slowly. Here is the same table in Python:

import math

def surprise(p):
    return math.log2(1 / p)     # same as -log₂ p

print("certain event:   ", surprise(1))
print("fair coin heads: ", surprise(1 / 2))
print("one card from 52:", round(surprise(1 / 52), 1))
print("1 in a million:  ", round(surprise(1 / 1_000_000), 1))
It runs right here in your browser, with nothing to install.

Surprises add up

Flip two fair coins. The chance of two heads is 1/2 × 1/2 = 1/4. Its surprise is log⁡24=2\log_2 4 = 2 bits. That's 1 bit for each coin, added together.

This is why surprise uses a logarithm. When two events are independent (one doesn't affect the other), their probabilities multiply. A logarithm turns multiplying into adding. So the surprises of independent events add up, like the news from two separate texts.

Go deeper Why the log makes surprises add

Say two independent events have probabilities pp and qq. The chance of both is p⋅qp \cdot q. The log of a product is the sum of the logs:

−log⁡2(p⋅q)=(−log⁡2p)+(−log⁡2q)-\log_2 (p \cdot q) = (-\log_2 p) + (-\log_2 q)

Read it as: "the surprise of both events equals the surprise of the first plus the surprise of the second." With two coins: −log⁡2(12⋅12)=1+1-\log_2(\frac{1}{2} \cdot \frac{1}{2}) = 1 + 1, which is 2 bits.

Base 2 gives the answer in bits. Other bases give other units. You'll meet one near the end.

Quick check
What does this print?
import math
p = 1 / 8
print(math.log2(1 / p))
  1. -3.0
  2. 3.0
  3. 8.0
  4. 0.125
Show the answer

3.0

Flip 1/8 upside down to get 8. Since 2 × 2 × 2 = 8, log₂ 8 = 3. A 1-in-8 event carries 3 bits of surprise: the three halvings of the card game. (Without the flip, math.log2(1 / 8) would print -3.0. That's why the other form has a minus sign.)

Entropy: the average surprise

Surprise is about one event. Entropy is about a whole situation: every outcome that could happen, with its probability. A list like that is a distribution.

Picture two towns. In a desert town, it's sunny 9 days in 10 and rains 1 day in 10. In a coin-flip town, sun and rain are equally likely.

In the desert town, most days bring almost no news. A sunny day has a surprise of log⁡210.9\log_2 \frac{1}{0.9}, about 0.15 bits. A rainy day is a shock: log⁡210.1\log_2 \frac{1}{0.1}, about 3.32 bits. But rain is rare. So on average, how much news does the weather bring?

Weight each surprise by how often it happens, then add:

  • sunny: 0.9 × 0.152 = 0.137 bits;
  • rainy: 0.1 × 3.322 = 0.332 bits;
  • average: 0.137 + 0.332 = 0.469 bits per day.

The coin-flip town gets a full 1 bit every day. Its weather is harder to predict, so its entropy is higher.

That weighted average is the entropy. As a formula:

H(p)=−∑ipilog⁡2piH(p) = -\sum_i p_i \log_2 p_i

The letter HH stands for entropy. pip_i is the probability of outcome number ii. The big Σ\Sigma (sigma, a Greek capital S) means "add this up over every outcome". In Python, it's a for loop or a sum.

In plain words: for each outcome, multiply its probability by its surprise. Add up the results. The total is how many bits of news you get on average. That's how uncertain the situation is.

One small rule: an outcome with probability 0 never happens, so it adds nothing. Books say 0log⁡00 \log 0 is treated as 0. The code below drops those outcomes with p[p > 0]. Then it multiplies each probability by its surprise, np.log2(1 / p), and adds the results.

import numpy as np

def entropy(p):
    p = np.asarray(p, dtype=float)
    p = p[p > 0]
    return np.sum(p * np.log2(1 / p))     # same as -Σ p log₂ p

print("fair coin:        ", entropy([0.5, 0.5]))
print("biased coin 90/10:", round(entropy([0.9, 0.1]), 3))
print("certain:          ", entropy([1.0, 0.0]))
print("fair 8-sided die: ", entropy([1 / 8] * 8))

The 90/10 coin gives 0.469 bits, the same as the desert town. The 8-sided die gives 3 bits, the same as the 8-card game. Three patterns show up:

  • Entropy is zero when one outcome is certain. There's nothing to learn.
  • It's largest when all outcomes are equally likely. Call the number of outcomes KK. Then the largest possible entropy is log⁡2K\log_2 K bits. The die has 8 sides, and log⁡28=3\log_2 8 = 3.
  • In between, the more lopsided the distribution, the lower the entropy.
Go deeper Why outcomes with probability 0 count as 0

The formula asks for log⁡20\log_2 0, which doesn't exist. But look at what happens as a probability shrinks toward 0. At p=0.001p = 0.001, the outcome's share is 0.001 × 9.97, about 0.01 bits. The smaller pp gets, the closer its share gets to 0. So treating it as exactly 0 is the natural choice. Code has to skip those outcomes, or NumPy returns nan ("not a number").

Quick check
A spinner lands on red half the time, blue a quarter of the time, and green a quarter of the time. What is its entropy?
  1. 2 bits
  2. 1.5 bits
  3. About 1.58 bits
  4. 1 bit
Show the answer

1.5 bits

Red: 0.5 × 1 bit = 0.5. Blue: 0.25 × 2 bits = 0.5. Green: also 0.5. The total is 1.5 bits. That's a little below the 1.58-bit maximum for 3 outcomes, because the spinner favors red.

Try it now

Entropy of a next-word distribution. Push one score far above the others and entropy falls toward 0. Make the scores equal and it reaches the maximum, log₂ 4 = 2 bits.

Quick check
Which distribution over 4 options has the highest entropy?
  1. [1, 0, 0, 0]
  2. [0.5, 0.5, 0, 0]
  3. [0.25, 0.25, 0.25, 0.25]
  4. [0.7, 0.1, 0.1, 0.1]
Show the answer

[0.25, 0.25, 0.25, 0.25]

Equal odds are the most uncertain case. With 4 outcomes, that's log₂ 4 = 2 bits.

How sure is the model?

A language model predicts the next token (a word or a piece of a word). It gives a probability for every token it knows. That list is a distribution, so it has an entropy too.

After "The capital of France is", nearly all the probability sits on " Paris". The entropy is close to 0: the model is confident. After "My favorite color is", the probability spreads across many colors. The entropy is higher: the model is less sure, and rightly so.

import numpy as np

def entropy(p):
    p = np.asarray(p, dtype=float)
    p = p[p > 0]
    return np.sum(p * np.log2(1 / p))     # same as -Σ p log₂ p

capital = {"Paris": 0.96, "a": 0.02, "located": 0.01, "the": 0.01}
color = {"blue": 0.28, "green": 0.2, "red": 0.17, "purple": 0.13, "black": 0.12, "yellow": 0.1}
print("after 'The capital of France is':", round(entropy(list(capital.values())), 2), "bits")
print("after 'My favorite color is':   ", round(entropy(list(color.values())), 2), "bits")

The capital prompt scores about 0.3 bits. The color prompt scores about 2.5 bits. Six equally likely colors would give the maximum, log⁡26\log_2 6, about 2.58 bits. So the model's color guess is close to a shrug.

This is useful in practice. High entropy on a factual question can signal that the model is unsure. That's a hint it might hallucinate: give a fluent answer that's made up. Some systems use entropy to decide when to fetch more context or ask a clarifying question.

Watch out: low entropy means confident, not correct. A model can put 96% on a wrong answer.

Worked example

Worked example: two lunch habits

Sam eats lunch at four spots, each equally often. Alex eats at a favorite cafe 7 days in 10. On the other 3 days, Alex picks one of three other spots, evenly. Whose lunch is harder to predict, and by how much?

import math

sam = [0.25, 0.25, 0.25, 0.25]   # four spots, equally often
alex = [0.7, 0.1, 0.1, 0.1]      # a favorite cafe, plus three others

for name, probs in [("Sam", sam), ("Alex", alex)]:
    h = sum(p * math.log2(1 / p) for p in probs)
    print(name, "entropy:", round(h, 2), "bits")

print("Alex at the cafe:   ", round(math.log2(1 / 0.7), 2), "bits of surprise")
print("Alex anywhere else: ", round(math.log2(1 / 0.1), 2), "bits of surprise")
In the lesson you can change this and run it.

Sam's lunch has 2.0 bits of entropy. That's the maximum for four options, since log⁡24=2\log_2 4 = 2. Alex's lunch has 1.36 bits, so it's easier to predict. A day at the cafe carries only 0.51 bits of surprise. A day anywhere else carries 3.32 bits, but those days are rare.

Think back to the guessing game. To learn Sam's spot, you need 2 yes/no questions every time. For Alex, ask "The cafe?" first. Seven days in 10, one question settles it. That plan averages 1.5 questions. No plan can average fewer questions than the entropy, 1.36.

Entropy and compression

Think about how you text. You type "lol" and "brb" for things you say all the time. You spell out rare words in full. Short codes for common things, longer codes for rare ones. Morse code works the same way: E, the most common letter in English, is a single dot.

Entropy sets the limit on this trick. On average, you can't record outcomes in fewer bits than the entropy of their distribution. Predictable data has low entropy, so it shrinks a lot when you zip it. Random data has high entropy, so it barely shrinks at all.

This links straight back to language models. A model that predicts text well can be used to compress text well. In a precise sense, a good predictor of text is a good compressor of text. A model's training loss is measured in the same units as entropy. You'll meet that loss, cross-entropy, in the next lesson.

Note: with natural logs (np.log), entropy comes out in nats instead of bits. 1 nat is about 1.44 bits. Training code usually uses natural logs. The ideas are identical.

Quick check
Which of these files would a zip program shrink the most?
  1. An encrypted file
  2. A server log where 99% of the lines say "OK"
  3. All three would shrink by the same amount
  4. A file of random bytes
Show the answer

A server log where 99% of the lines say "OK"

The log is very predictable, so its entropy is low and it compresses well. Random bytes and encrypted data look like noise: high entropy, so they barely shrink.

Practice what you just read

  • 4 code examples you can edit and run
  • a practice exercise that checks your code
  • a 5-question quiz
  • 4 review cards for spaced repetition

Create a free account

Try a quiz question

What does an entropy of 0 mean for a model's next-token distribution?

  1. All probability is on one token: the model is certain
  2. All tokens are equally likely: it has no idea
  3. The model is broken, and has stopped predicting
  4. The next token is impossible to predict from here

Answer it at the end of the lesson to see if you're right, and why.

Before this lesson