Thompson Sampling Mock Bandit in Python

Implement a Thompson sampling multi-armed bandit to explore and exploit reward probabilities across multiple options, updating Beta distributions over time.

Medium Python 3.9+ Aug 9, 2026 A/B testing & experimentation 12 views 0 copies

Python code

31 lines
Python 3.9+
import random

class ThompsonSamplingBandit:
    def __init__(self, num_arms, alpha=1.0, beta=1.0):
        self.num_arms = num_arms
        self.alpha = [alpha] * num_arms
        self.beta = [beta] * num_arms

    def select_arm(self):
        samples = [random.betavariate(a, b) for a, b in zip(self.alpha, self.beta)]
        return max(range(self.num_arms), key=lambda i: samples[i])

    def update(self, arm, reward):
        if reward:
            self.alpha[arm] += 1
        else:
            self.beta[arm] += 1

if __name__ == "__main__":
    random.seed(42)
    true_probabilities = [0.2, 0.5, 0.8]
    bandit = ThompsonSamplingBandit(len(true_probabilities))
    total_reward = 0
    for _ in range(1000):
        arm = bandit.select_arm()
        reward = 1 if random.random() < true_probabilities[arm] else 0
        bandit.update(arm, reward)
        total_reward += reward
    print(f"Arm selections per arm: {[bandit.alpha[i] + bandit.beta[i] - 2 for i in range(len(true_probabilities))]}")
    print(f"Total reward: {total_reward}")
    print(f"Estimated probabilities: {[round(bandit.alpha[i] / (bandit.alpha[i] + bandit.beta[i]), 3) for i in range(len(true_probabilities))]}")

Output

stdout
Arm selections per arm: [6, 81, 913]
Total reward: 767
Estimated probabilities: [0.125, 0.457, 0.795]

How it works

Thompson sampling treats each arm's reward probability as a random variable with a Beta distribution. The select_arm method samples from each Beta and picks the arm with the highest sample, balancing exploration and exploitation. After receiving a binary reward, update increments the alpha parameter on success or beta on failure, refining the distribution. This converges to selecting the best arm (0.8 probability) over time, as seen in the high selection count. The approach is simple yet effective for online decision-making scenarios.

Common mistakes

  • Forgetting to update both alpha and beta based on reward type
  • Using incorrect Beta parameter order (alpha is success count, beta is failure count)
  • Not setting a random seed when reproducibility is needed

Variations

  1. Use numpy's `random.beta` for faster vectorized sampling with large numbers of arms
  2. Replace uniform prior with domain-specific prior counts for faster convergence

Real-world use cases

  • Automating A/B test allocation to minimize regret while learning conversion rates.
  • Dynamic ad placement to maximize click-through rate without sacrificing exploration.
  • Recommendation system arm selection to balance new content trials against proven items.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from A/B testing & experimentation

Related tutorials and quizzes for this topic.