All studies
Online Learning

Discounted UCB in a Changing Environment

Study how forgetting old rewards helps after a change point, and distinguish time-based discounting from the selected-arm update used in the archived experiment.

Nonstationary Bandits
UCB
Discounting

Yong-Hwan Lee

Published · Updated

Overview

When reward distributions change, a long history of observations can slow adaptation. This study compares UCB with an exponentially weighted variant in a two-arm environment whose best arm switches halfway through a run.

The archived code discounts only the selected arm. This differs from standard elapsed-time discounting in discounted UCB. The distinction is central to interpreting the results below.

What time-based discounting means

Let AsA_s denote the selected arm at step ss, rsr_s its observed reward, and 0<γ≤10<\gamma\leq1 the discount factor. After step tt, define

Nt(i)=∑s=1tγt−s1{As=i},St(i)=∑s=1tγt−srs1{As=i}.N_t(i)=\sum_{s=1}^{t}\gamma^{t-s}\mathbf1\{A_s=i\}, \qquad S_t(i)=\sum_{s=1}^{t}\gamma^{t-s}r_s\mathbf1\{A_s=i\}.

For Nt(i)>0N_t(i)>0, the discounted mean is μ^t(i)=St(i)/Nt(i)\widehat\mu_t(i)=S_t(i)/N_t(i). An arm's older observations lose weight with every elapsed round, whether or not that arm is selected.

The following dependency-free example updates these statistics. It is not a complete policy: action selection, initialization, and the confidence bonus must also be specified.

def update_discounted_statistics(counts, sums, arm, reward, gamma):
    if not 0 < gamma <= 1:
        raise ValueError("gamma must be in (0, 1]")
    if len(counts) != len(sums) or not 0 <= arm < len(counts):
        raise ValueError("counts, sums, and arm must describe the same arm set")
    next_counts = [gamma * count for count in counts]
    next_sums = [gamma * total for total in sums]
    next_counts[arm] += 1
    next_sums[arm] += reward
    return next_counts, next_sums

Discounting both a sum and its count leaves an unselected arm's mean unchanged, but reduces its effective evidence. A discounted confidence rule can then encourage revisiting it.

Discount factorEffect on the statistics
γ=1\gamma=1No discounting; ordinary counts and reward sums
γ\gamma close to 1Slow forgetting, with finite accumulated weight when γ<1\gamma<1
Smaller positive γ\gammaFaster forgetting and potentially noisier estimates

For an arm selected every round, its count approaches 1/(1−γ)1/(1-\gamma) when γ<1\gamma<1. This is an approximate memory scale, not a guarantee of the best setting. “Close to one” is not mathematically equivalent to one.

What the archived code actually does

In lib/DiscountedUCBBandit.py, the selected arm receives

Ni←γNi+1,Si←γSi+r.N_i\leftarrow\gamma N_i+1,\qquad S_i\leftarrow\gamma S_i+r.

All other arms retain their previous statistics. Thus an observation is discounted according to later selections of the same arm, not according to elapsed global time. The code's confidence bonus uses the undiscounted update counter:

μ^i+2αlog⁡tNi.\widehat\mu_i+\sqrt{\frac{2\alpha\log t}{N_i}}.

For example, after selecting arm 0 once and then arm 1 twice, the time-discounted count of arm 0 is γ2\gamma^2. The archived implementation keeps that count at 1.

The experiment should therefore be read as a comparison with this selected-arm-discount variant. The illustrative update above explains the standard time-based statistics; it does not retroactively change the archived results or update the external repository.

Experiment setup

The linked simulation configures:

SettingValue
Horizon1,000 iterations
Arms / users2 / 1
First half: expected rewardsArm 0 = 1, arm 1 = 0
Second half: expected rewardsArm 0 = 0, arm 1 = 1
Observation noiseGaussian, mean 0 and standard deviation 0.1
Exploration parameterα=0.5\alpha=0.5

The comparator chooses the best arm at each step, including after the switch. Regret uses expected reward gaps: the simulator adds the same noise to the selected and optimal rewards, so the noise cancels in their difference. In this binary-mean environment, each suboptimal action contributes one unit.

The script logs at zero-based iterations 0, 100, …, 900, then prints the last logged value. That value covers 901 actions, not all 1,000. The source needs an explicit final checkpoint before its printed output can be called full-horizon regret.

Recorded results

The five-trial table is preserved from the original report. The mean row is the arithmetic mean of the displayed values. Seeds and per-run logs were not preserved alongside the table, so these values have not been re-established as full-horizon totals.

TrialUCBVariant: γ=0.1\gamma=0.1Variant: γ=0.5\gamma=0.5Variant: γ=0.9\gamma=0.9
111346
237326
359427
48323
512227
Mean25.43.02.45.8

Within these recorded values, all three discounted variants have lower means than UCB. The γ=0.5\gamma=0.5 setting has the lowest mean, but five trials without matched seeds or uncertainty estimates do not establish a broadly optimal discount factor. These runs also do not measure the standard time-discounted algorithm.

UCB: five recorded trials
UCB cumulative regret, trial 1
Trial 1
UCB cumulative regret, trial 2
Trial 2
UCB cumulative regret, trial 3
Trial 3
UCB cumulative regret, trial 4
Trial 4
UCB cumulative regret, trial 5
Trial 5
Discounted variant, gamma = 0.1: five recorded trials
Discounted variant, gamma = 0.1 cumulative regret, trial 1
Trial 1
Discounted variant, gamma = 0.1 cumulative regret, trial 2
Trial 2
Discounted variant, gamma = 0.1 cumulative regret, trial 3
Trial 3
Discounted variant, gamma = 0.1 cumulative regret, trial 4
Trial 4
Discounted variant, gamma = 0.1 cumulative regret, trial 5
Trial 5
Discounted variant, gamma = 0.5: five recorded trials
Discounted variant, gamma = 0.5 cumulative regret, trial 1
Trial 1
Discounted variant, gamma = 0.5 cumulative regret, trial 2
Trial 2
Discounted variant, gamma = 0.5 cumulative regret, trial 3
Trial 3
Discounted variant, gamma = 0.5 cumulative regret, trial 4
Trial 4
Discounted variant, gamma = 0.5 cumulative regret, trial 5
Trial 5
Discounted variant, gamma = 0.9: five recorded trials
Discounted variant, gamma = 0.9 cumulative regret, trial 1
Trial 1
Discounted variant, gamma = 0.9 cumulative regret, trial 2
Trial 2
Discounted variant, gamma = 0.9 cumulative regret, trial 3
Trial 3
Discounted variant, gamma = 0.9 cumulative regret, trial 4
Trial 4
Discounted variant, gamma = 0.9 cumulative regret, trial 5
Trial 5

Reproduction notes

Use the repository's main branch and SimulationDiscountedUCB.py, which preserves the archived experiment's simulation script unchanged. The algorithm dictionary selects UCB or DiscountedUCBBandit and sets α\alpha and γ\gamma.

A revised experiment should distinguish the archived variant from a time-discounted implementation, append the final-horizon checkpoint, and use matched seeds across methods. Testing multiple change points, reward gaps, and stationary periods would show whether faster forgetting helps consistently.

The curves above remain the original archive. No simulations were rerun for this content revision.

Takeaways

  • Forgetting by elapsed time and forgetting by arm selections are different algorithms.
  • Smaller discount factors can improve responsiveness while increasing estimation noise.
  • A performance table must identify the implemented policy, comparator, and recorded horizon.
  • These archived trials motivate a controlled rerun; they do not validate a universal ranking.

Sources

Keep exploring

Bandit Algorithms: Methods & Implementation Review