Skip to main content
© 2026 ePowerAI — instrumented learning, no login required.
CoursesContact
ePOWERAI
CoursesContact
Bandits: UCB1 and Thompson Sampling
Reinforcement Learning
01Reinforcement Learning: Agents, Rewards, and MDPs
02Bandits: Exploration, Exploitation, and Regret
03Returns, Value, and the Bellman Equation
04Bandits: UCB1 and Thompson Sampling
05Week 1: Reinforcement Learning Problem Formulation
06Week 2: Multi-Armed Bandits
07Week 3: Dynamic Programming for Finite MDPs
08Week 4: Monte Carlo and Temporal-Difference Learning
09Week 5: Function Approximation in Reinforcement Learning
10Week 6: Deep Q-Learning and Variants
11Week 7: Policy Gradient and Actor–Critic Methods
12Week 8: Modern Deep Reinforcement Learning Algorithms
13Week 9: Exploration, Partial Observability, and Multi-Agent Reinforcement Learning
14Week 10: Model-Based Reinforcement Learning and Planning
15Week 11: Offline Reinforcement Learning
16Week 12: Reinforcement Learning from Human Feedback
17Week 13: Direct Preference Optimization and GRPO
18Week 14: Agentic Systems and Course Capstone
· Reinforcement Learning· Guided Path · Beginner10 min read

Bandits: UCB1 and Thompson Sampling

Bandits: UCB1 and Thompson Sampling

Learning Outcomes

By the end of this step you will:

  • Explain optimism in the face of uncertainty in plain language
  • Read the UCB1 rule and say what each of its two terms does
  • Explain how Thompson sampling explores by sampling from what it believes
  • Compare the two algorithms and say when each is used
Prerequisites
  • Exploration, Exploitation, and Regret: the bandit problem, the trade-off, regret, and why a fixed exploration rate fails.
  • Random Variables and Distributions is useful for the idea of a distribution over an unknown quantity.

Every cell runs in the page.

The exploration rate in ε\varepsilonε-greedy ignores everything the agent has learned. The fix is to compute exploration from the data itself — from how uncertain the agent still is about each option.

The problem with a fixed exploration rate#

In the previous step, the flaw was precise: ε\varepsilonε is set before the run starts and never changes. Early on it is too small, because every arm is uncertain and a tenth of the pulls is not enough evidence to separate them. Later it is too large, because the arms have been separated and a tenth of the pulls is pure waste.

What the agent actually needs is an exploration rate that tracks its own uncertainty: high while an arm is unknown, low once that arm's value is pinned down. Both algorithms in this step do exactly that, from opposite directions.

Optimism in the face of uncertainty#

The first idea is usually stated as a motto:

“

When you are uncertain, act as if the best plausible outcome is going to happen.

Think about what an uncertain arm looks like. You have pulled it a few times and seen a spread of rewards, so its true average could plausibly be anywhere in a fairly wide range. A confident arm has been pulled many times, and its range is narrow.

The optimistic rule values each arm at the top of its plausible range, not at the middle. An unknown arm gets a high score simply because its range extends up; an arm that has been tried and found mediocre has a low top and gets ignored. This creates a self-correcting cycle:

  • An arm with a high optimistic score gets pulled.
  • Pulling it narrows its range.
  • The score falls back toward what the arm is actually worth.

No parameter decides how much to explore. The width of the plausible range does — and that width automatically shrinks as evidence accumulates.

Intuition: why optimism, and not pessimism?

Imagine the opposite rule: value each arm at the bottom of its range. Then an unknown arm looks bad because its range extends down, so it never gets pulled, so it stays unknown forever. That is pure exploitation with extra steps, and it inherits the same failure. Optimism is the smallest change to "pick the best estimate" that guarantees uncertain options get tried.

UCB1: a mean plus a bonus#

The Upper Confidence Bound rule turns that motto into a formula. Each arm gets a score with two parts:

score(a)=μ^a⏟what we have seen  +  2log⁡tNt(a)⏟how unsure we still are.\text{score}(a) = \underbrace{\hat{\mu}_a}_{\text{what we have seen}} \;+\; \underbrace{\sqrt{\frac{2\log t}{N_t(a)}}}_{\text{how unsure we still are}}.score(a)=what we have seenμ^​a​​​+how unsure we still areNt​(a)2logt​​​​.

The algorithm pulls the arm with the largest score. Term by term:

  • μ^a\hat{\mu}_aμ^​a​ is the average reward observed from arm aaa so far. This is the exploitation part: arms that have paid well look good.
  • Nt(a)N_t(a)Nt​(a) is how many times arm aaa has been pulled. It appears in the denominator of the bonus.
  • ttt is the current round. It appears in the numerator of the bonus.
  • The bonus grows with log⁡t\log tlogt but shrinks with each pull of that arm. A rarely pulled arm has a large bonus and looks promising; pulling it reduces the bonus.

Unpulled arms would divide by zero, so UCB1 pulls every arm once before the formula takes over.

There is nothing to tune. The constant 2 comes from a concentration bound — for rewards between 0 and 1, Hoeffding's inequality says a true mean is very unlikely to sit above the estimate plus this bonus. So the bonus is not a heuristic guess at uncertainty; it is a statistically justified high-confidence ceiling. That is why UCB1 comes with a regret guarantee: its total regret grows like log⁡T\log TlogT, which is the best order any algorithm can achieve on a bandit instance.

Thompson sampling: sample a belief, act greedily#

The second algorithm attacks exploration from the Bayesian side. Instead of computing a ceiling, it keeps a distribution over each arm's true average and lets that distribution decide.

Concretely, for arms that pay 0 or 1 — a click or no click, a thumbs-up or thumbs-down:

  1. Start with a flat prior for each arm: every success probability between 0 and 1 is equally plausible. This is written Beta(1,1)\text{Beta}(1, 1)Beta(1,1).
  2. Each round, draw one random sample from each arm's current distribution.
  3. Pull the arm whose sample is largest.
  4. Observe the reward and update that arm's distribution: a success adds one to α\alphaα, a failure adds one to β\betaβ.

The update is exact and costs nothing — the Beta distribution has a special property (conjugacy) that makes the posterior another Beta, so all you do is increment a counter. After sss successes and fff failures, the arm's belief is Beta(1+s, 1+f)\text{Beta}(1+s,\, 1+f)Beta(1+s,1+f), whose average is 1+s2+s+f\frac{1+s}{2+s+f}2+s+f1+s​: close to the observed success rate once the data accumulate, and near one half while the arm is still unknown.

Where does exploration come from? From the width of the distribution. A rarely pulled arm has a wide, uncertain distribution, so occasionally it produces a very high sample and gets chosen. An arm pulled hundreds of times has a narrow distribution clustered around its true value, so it rarely surprises you. Exploration is not a separate branch in the code; it falls out of sampling from what the agent does not yet know.

Thompson sampling is not merely a heuristic either: it matches the best achievable regret order asymptotically, and it frequently beats UCB1 in practice because sampling from a distribution tracks uncertainty more finely than a single ceiling.

Side by side#

ε\varepsilonε-greedyUCB1Thompson sampling
What drives explorationa fixed random ratea confidence bonusspread of the belief
Tuning neededchoose ε\varepsilonε (and its decay)nonechoose a prior
Regret over timelinear with fixed ε\varepsilonεlogarithmic, optimal orderlogarithmic, often better in practice
Extra machinerynonerunning means and countsa distribution per arm

The three sit on a ladder of statistical sophistication: a fixed rate, then a confidence bound, then a full belief. All three implement the same intuition — uncertain options deserve attention — but only the last two adjust that attention automatically as evidence arrives.

Where this shows up#

Bandit algorithms are some of the most widely deployed ideas in this course, because the setting is so common:

  • A/B testing and recommendation. Which headline, layout, or video to show next is an arm-selection problem, and exploration is how the system discovers a better option than the one it currently ships.
  • Language models tuned from preferences. Comparing candidate responses is a bandit in disguise: each prompt is a round, each response is an arm, and the feedback is a preference score. The exploration question — how much to keep testing alternatives versus commit to the current best — is exactly the one studied here.

Browser lab: UCB1 and Thompson sampling head to head#

Both algorithms run on the same four-armed bandit. Neither is told the true means; neither has an exploration rate to set.

python · runs in browser
import numpy as np

rng = np.random.default_rng(7)

N_ARMS = 4
N_ROUNDS = 1000
TRUE_MEANS = np.array([0.3, 0.5, 0.7, 0.9])   # hidden from the algorithms
BEST_MEAN = TRUE_MEANS.max()


def run_ucb1(rng):
    """Optimism: score each arm by its average plus a shrinking bonus."""
    counts = np.zeros(N_ARMS)
    means = np.zeros(N_ARMS)
    regret = 0.0
    t = 0

    for _ in range(N_ROUNDS):
        if np.any(counts == 0):
            arm = int(np.argmax(counts == 0))        # try each arm once first
        else:
            bonus = np.sqrt(2.0 * np.log(t) / counts)
            arm = int(np.argmax(means + bonus))
        reward = float(rng.random() < TRUE_MEANS[arm])
        t += 1
        counts[arm] += 1
        means[arm] += (reward - means[arm]) / counts[arm]
        regret += BEST_MEAN - TRUE_MEANS[arm]        # reward the oracle would have kept

    return counts.astype(int), regret


def run_thompson(rng):
    """Sampling: draw a belief sample per arm, act greedily on the sample."""
    alphas = np.ones(N_ARMS)     # Beta(1, 1) prior: no opinion yet
    betas = np.ones(N_ARMS)
    counts = np.zeros(N_ARMS)
    regret = 0.0

    for _ in range(N_ROUNDS):
        samples = rng.beta(alphas, betas)
        arm = int(np.argmax(samples))
        reward = float(rng.random() < TRUE_MEANS[arm])
        alphas[arm] += reward            # success -> alpha + 1
        betas[arm] += 1.0 - reward       # failure -> beta + 1
        counts[arm] += 1
        regret += BEST_MEAN - TRUE_MEANS[arm]

    return counts.astype(int), regret


for label, run in [("UCB1", run_ucb1), ("Thompson sampling", run_thompson)]:
    counts, regret = run(rng)
    print(f"{label:<18} pulls per arm = {counts}, regret = {regret:.1f}")

print("Notice: both algorithms concentrate their pulls on the best arm, with no exploration rate to tune.")

What to look for.

  • Almost all pulls land on the arm with mean 0.9, and the loss (regret) stays small despite the early rounds where nothing was known.
  • UCB1's counts are more even; Thompson sampling's are more concentrated. The reason is visible in the mechanisms: UCB1 rewards uncertainty with a bonus that has to be pulled down, while sampling from a wide belief only occasionally produces a winning sample.
  • Change the seed or the true means and the pattern holds. Neither algorithm needs the gaps between arms — the thing that made decaying ε\varepsilonε impractical.

Key takeaways#

  • Optimism in the face of uncertainty values an arm at the top of its plausible range, so unknown arms look promising and get tried; pulling them shrinks the range.
  • UCB1 scores each arm as its observed average plus a bonus that grows with log⁡t\log tlogt and shrinks with each pull. It needs no tuning, and its regret grows logarithmically.
  • Thompson sampling keeps a probability distribution over each arm's value, samples from it, and acts greedily on the sample. Exploration emerges from the width of the belief.
  • Both adapt exploration to their own uncertainty, which is what fixed-rate ε\varepsilonε-greedy cannot do.
  • Bandits are deployed wherever options must be tried and compared: recommendations, A/B tests, and preference-based tuning of language models.

Knowledge Check#

Check that you can read the two rules, not just name them.

Exercise · Fill in the blank

In UCB1, the term added to the observed average grows with log t and shrinks as the arm is pulled more. It is called the ______ .

Exercise · Multiple choice

In Beta-Bernoulli Thompson sampling, what happens when an arm returns a reward of 1?

Alpha is increased by one and beta is left alone
Beta is increased by one and alpha is left alone
Both alpha and beta are increased by one
The prior is reset to Beta(1, 1)
Question 1 of 3

Why does UCB1 need no exploration rate to tune?

Because it never explores after the first round
Because the exploration bonus is computed from each arm's pull count and the round number
Because it uses a fixed value of epsilon internally
Because it is told the true arm means

Where the path goes next#

You have finished the reinforcement-learning steps of the Guided Foundations Path. You now have the vocabulary — agent, state, action, reward, return, value, exploration — and the two core algorithmic ideas of the simplest setting.

The path continues with robotics, where the same loop becomes physical: how a robot senses its own motion, and how it estimates where it is when its sensors are noisy.

If you want to keep going with reinforcement learning itself, the full course continues from here with dynamic programming for finite MDPs — turning the Bellman equation into a concrete algorithm — and then function approximation and policy-gradient methods.

Browse the full Reinforcement Learning course

← Previous
Returns, Value, and the Bellman Equation
Next →
Week 1: Reinforcement Learning Problem Formulation
On this page
  • The problem with a fixed exploration rate
  • Optimism in the face of uncertainty
  • UCB1: a mean plus a bonus
  • Thompson sampling: sample a belief, act greedily
  • Side by side
  • Where this shows up
  • Browser lab: UCB1 and Thompson sampling head to head
  • Key takeaways
  • Knowledge Check
  • Where the path goes next