Skip to content

Epsilon-greedy

Be able to implement epsilon-greedy from memory, predict how changing ε\varepsilon changes both learning speed and final performance, and explain why the best ε\varepsilon depends on how long you get to play.

A purely greedy agent always pulls the arm with the highest current estimate. That fails in a specific and avoidable way: one lucky early win on a mediocre arm makes it look best, the agent keeps pulling it, and the genuinely best arm is never tried again. Its estimate stays at its initial value forever. The agent locks onto a bad answer and never collects the evidence that would change its mind.

Epsilon-greedy fixes this with the least machinery possible. Before each pull, flip a biased coin. With probability ε\varepsilon, ignore everything you know and pick uniformly at random. Otherwise act greedily.

That is the entire algorithm. Its guarantee is crude but real: every arm gets pulled infinitely often in the limit, so every Qt(a)Q_t(a) converges to q∗(a)q_*(a), so the greedy action eventually is the optimal one.

At={arg⁡max⁡aQt(a)with probability 1−εa∼Uniform(A)with probability εA_t = \begin{cases} \arg\max_a Q_t(a) & \text{with probability } 1 - \varepsilon \\[4pt] a \sim \mathrm{Uniform}(\mathcal{A}) & \text{with probability } \varepsilon \end{cases}

Epsilon-greedy, sample-average estimates

Initialise, for a=1a = 1 to kk:   Q(a)←0Q(a) \leftarrow 0,   N(a)←0N(a) \leftarrow 0

Loop forever:

A←{arg⁡max⁡aQ(a)w.p. 1−ε  (ties broken randomly)a random actionw.p. ε\quad A \leftarrow \begin{cases} \arg\max_a Q(a) & \text{w.p. } 1-\varepsilon \;\text{(ties broken randomly)} \\ \text{a random action} & \text{w.p. } \varepsilon \end{cases}

R←bandit(A)\quad R \leftarrow \mathrm{bandit}(A)

N(A)←N(A)+1\quad N(A) \leftarrow N(A) + 1

Q(A)←Q(A)+1N(A)[R−Q(A)]\quad Q(A) \leftarrow Q(A) + \dfrac{1}{N(A)}\left[R - Q(A)\right]

Note that the greedy branch takes a random action ε/k\varepsilon/k of the time by coincidence, so the true probability of selecting the greedy action is 1−ε+ε/k1 - \varepsilon + \varepsilon/k.

Three arms, ε=0.1\varepsilon = 0.1, all estimates starting at 0.

PullCoinBranchActionRewardUpdate
10.83exploit3-way tie → arm 21Q(2)=0+11(1−0)=1.00Q(2) = 0 + \tfrac11(1-0) = 1.00
20.42exploitarm 2 (highest QQ)0Q(2)=1+12(0−1)=0.50Q(2) = 1 + \tfrac12(0-1) = 0.50
30.07explorearm 3 (random)1Q(3)=0+11(1−0)=1.00Q(3) = 0 + \tfrac11(1-0) = 1.00
40.91exploitarm 3 (highest QQ)0Q(3)=1+12(0−1)=0.50Q(3) = 1 + \tfrac12(0-1) = 0.50
50.55exploit2-way tie → arm 21Q(2)=0.5+13(1−0.5)=0.67Q(2) = 0.5 + \tfrac13(1-0.5) = 0.67

Two things to notice. Pull 3 is the whole point of the algorithm: arm 3 would never have been tried by a greedy agent, and it turned out to be worth trying. And after a single win an estimate reads 1.00 — early estimates are wildly overconfident because they average over one sample.

Step through it one pull at a time and watch the branch taken, or turn on auto-play and watch the estimates converge. The seed field makes any run reproducible.

Open demo full screen ↗ View source ↗

Set ε=0\varepsilon = 0 and step repeatedly. The agent latches onto whichever arm happens to win first and never leaves. Reveal the true rates and you will usually find it is sitting on a mediocre arm. This is the failure epsilon-greedy exists to prevent.

Set ε=1\varepsilon = 1. Every pull is random. The estimates become excellent — every arm is sampled evenly — and the reward is terrible. Perfect knowledge, no exploitation.

Set ε=0.1\varepsilon = 0.1 and run a few hundred steps. The best arm accumulates most of the pulls while the others keep getting sampled occasionally. Watch the ”% optimal action” curve rise and then flatten.

Note the ceiling. With ε=0.1\varepsilon = 0.1 and 5 arms, the agent takes a random action 10% of the time forever, so it plays optimally at most 1−ε+ε/k=92%1 - \varepsilon + \varepsilon/k = 92\% of the time. The curve flattens below 100% by construction, not because learning stalled.

Run the comparison. This is the most important panel on the page. Four ε\varepsilon values, 150 independent runs each, 2000 steps, all facing the same set of environments.

  • ε=0\varepsilon = 0 climbs fastest for about fifty steps, then goes flat well below everything else. Across 200 seeds it ends up on a clearly suboptimal arm roughly 70% of the time.
  • ε=0.3\varepsilon = 0.3 learns quickly and then stays low: it throws away three pulls in ten forever.
  • ε=0.1\varepsilon = 0.1 leads for the first ~1500 steps.
  • ε=0.01\varepsilon = 0.01 is worst early and crosses above ε=0.1\varepsilon = 0.1 at around step 1500, ending near 0.89 against 0.86.

The crossover is the entire lesson. Neither value is better; the horizon decides. Note also that ε=0.1\varepsilon = 0.1 still has the higher cumulative average at step 2000 — it banked its lead early — even though ε=0.01\varepsilon = 0.01 is clearly ahead instantaneously by then. Which number you quote changes the answer.

Breaking ties by index. With all estimates at 0, argmax returns arm 0 every time. The agent then only ever explores by accident and the demo looks broken. Ties must be broken uniformly at random.

Comparing ε\varepsilon values on one run. A single run is dominated by luck. The comparison panel averages 150 independent runs for this reason, and holds the set of environments fixed so every ε\varepsilon faces the same problems. Compare two methods on one seed and you are mostly measuring the seed.

Exploring uniformly among the obviously-bad. Epsilon-greedy’s random branch is uniform: an arm already pulled 200 times with a terrible payout is just as likely to be explored as a promising one that has been pulled twice. This is the weakness UCB addresses.

Leaving ε\varepsilon constant when the run is long. Fixed ε\varepsilon means regret grows linearly forever. Decaying it — εt=1/t\varepsilon_t = 1/t, say — gets the early exploration without paying for it indefinitely.

  1. Set ε=0.5\varepsilon = 0.5 for the first 50 pulls, then drop it to 0.01. Compare the total against a constant ε=0.1\varepsilon = 0.1 over the same seed.
  2. Find a seed where ε=0\varepsilon = 0 beats ε=0.1\varepsilon = 0.1 over 200 steps, and explain why that is not evidence that greedy is better.
  3. Predict the flat-line value of ”% optimal action” for ε=0.3\varepsilon = 0.3 before running it, using 1−ε+ε/k1 - \varepsilon + \varepsilon/k. Then run it.
  4. Find the crossover step where ε=0.01\varepsilon = 0.01 overtakes ε=0.1\varepsilon = 0.1. Re-run with a different seed and see how much it moves.
  5. Watch regret rather than reward. Note that it never decreases, and compare its slope across ε\varepsilon values.

The thing that surprised me is that the best ε\varepsilon is a function of your time budget, not a property of the problem. Small ε\varepsilon wins asymptotically and loses over a short horizon. Asking “what is the best ε\varepsilon” without saying how many steps you get is asking an incomplete question.

The second thing: epsilon-greedy explores stupidly. It knows which arms it is uncertain about and throws that information away when it explores. Everything better — optimistic initialisation, UCB, Thompson sampling — comes from spending the exploration budget where the uncertainty actually is.

Both this page and the last assume the arms hold still. They do not, usually. Tracking a nonstationary problem is what changes when q∗(a)q_*(a) drifts while you play.

  • Sutton, R. S. & Barto, A. G. Reinforcement Learning: An Introduction, 2nd ed., §2.2–2.3.