#299LinUCB Contextual BanditHard

LinUCB Contextual Bandit

Background

LinUCB is a contextual bandit for personalised recommendations. Each arm learns a linear model θ^a=Aa1ba\hat\theta_a = A_a^{-1} b_a over the context vector; arm selection adds an upper confidence bound bonus proportional to the model's uncertainty in the current context direction. Classic baseline behind ad ranking and news personalisation.

Problem statement

Implement LinUCB(n_arms, d, alpha=1.0) with:

  • choose(x) — return int arm index with the highest UCB score:
UCBa(x)  =  θ^ax  +  αxAa1x\text{UCB}_a(x) \;=\; \hat\theta_a^\top x \;+\; \alpha \sqrt{x^\top A_a^{-1} x}
  • update(arm, x, reward) — Bayesian-style update: Aa+=xxA_a \mathrel{+}= xx^\top, ba+=rxb_a \mathrel{+}= r\,x.

Input

  • n_armsint >= 1, number of arms.
  • dint >= 1, context dimension.
  • alphafloat > 0, exploration weight (default 1.01.0).
  • choose(x)x is a length-dd array.
  • update(arm, x, reward)arm in [0,narms)[0, n_{\text{arms}}), x length-dd, reward scalar.

Output

  • choose returns an int arm index.
  • update returns None (mutates state).

Examples

Example 1 — cold start: all arms tied → arm 0

b = LinUCB(3, d=2)
b.choose([1.0, 0.0])  # -> 0  (tie-break by lower index)

Example 2 — positive reward shifts preference

b = LinUCB(2, d=2, alpha=0.01)
for _ in range(6): b.update(1, [1.0, 0.0], 10.0)
b.choose([1.0, 0.0])  # -> 1

Constraints

  • A initialised to identity for each arm; b initialised to zero.
  • alpha controls exploration vs exploitation; higher = more exploration.
  • Same input from a deterministic state returns the same arm.

Notes

  • Regret. LinUCB achieves O~(dT)\tilde O(d\sqrt{T}) regret under linear reward — provably better than ε-greedy for context dimensions that matter.
  • Disjoint vs hybrid. This is the disjoint variant (separate θ\theta per arm). Hybrid LinUCB shares a common θ0\theta_0 across arms plus per-arm θa\theta_a.
Python
Loading...

▶ Run executes the 3 visible sample tests below in your browser. Submit runs the full suite — including hidden tests — on the server for an official verdict.

  • Reference example: cold start picks arm 0
  • Example: positive reward shifts choice to arm 1
  • Sample: no exploration favors the rewarded arm