<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://ayushbatra.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://ayushbatra.github.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-08-14T13:46:40+00:00</updated><id>https://ayushbatra.github.io/feed.xml</id><title type="html">Ayush Batra</title><subtitle></subtitle><author><name></name></author><entry><title type="html">MultiArmedBandits with Stochastic, Adversarial, and Adversarially Corrupted Stochastic Rewards</title><link href="https://ayushbatra.github.io/MultiArmedBandits/" rel="alternate" type="text/html" title="MultiArmedBandits with Stochastic, Adversarial, and Adversarially Corrupted Stochastic Rewards" /><published>2023-01-03T00:00:00+00:00</published><updated>2023-01-03T00:00:00+00:00</updated><id>https://ayushbatra.github.io/multiarmedbandits</id><content type="html" xml:base="https://ayushbatra.github.io/MultiArmedBandits/"><![CDATA[<p>The multi-armed bandit (MAB) is a classic problem in probability theory and statistics that models exploitation-exploration trade-off, leveraging choices that have proven effective in the past versus choosing new options that might provide better-unexplored trade-offs. Imagine a row of slot machines, each with a different and unknown distribution of paying out a reward. The goal is to select the machine(or ‘arm’) at each time instance such that it maximizes the total reward over time. This article will discuss simulations for some known algorithms in MAB in stochastically chosen, adversarially chosen, and stochastically chosen but strategically corrupted reward scenarios and run simulations for the algorithms discussed.</p>

<h3 id="overview-of-the-algorithms">Overview of the Algorithms:</h3>
<p>Notations used:</p>
<ul>
  <li>\(K\): number of arms/actions</li>
  <li>\([K]\): the set of all arms/actions</li>
  <li>\(a \in [K]\): a unique arm/action</li>
  <li>\(T\): total number of rounds</li>
  <li>\(t \in [T]\): a specific round</li>
  <li>\(a_t\): arm chosen in round \(t\)</li>
  <li>\(X_{a\in [K],t\in [T]}\): reward for arm \(a\) in round \(t\)</li>
  <li>\(\Delta_{a,t}\): is the difference between the reward of optimal arm and arm \(a\) in round \(t\).</li>
  <li>\(n_t(a)\): is the number of pulls of arm \(a\) up to round \(t\).</li>
  <li>a*: be the optimal arm.</li>
  <li>\(\mathbb{I}\{predicate\}\): indicator function on predicate, it is \(1\) if predicate is true 0 otherwise. 
 
 
 </li>
</ul>

<h4 id="stochastic-bandits">Stochastic Bandits:</h4>

<p>Stochastic bandits are a type of problem in which the rewards of different actions are unrelated to each other, and the rewards of the same action at different time steps are an i.i.d distribution.</p>

<table>
  <thead>
    <tr>
      <th><strong>Protocol:</strong></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong><em>Parameters</em></strong>: \(K\) arms, \(T\) rounds, \(T &gt; K\), for each arm \(a \in [K]\), the reward for arm \(a\) is drawn from distribution \(D_a\).</td>
    </tr>
    <tr>
      <td>For each round \(t \in [T]\) the algorithm chooses an \(a_t\in[K]\) and observes a reward \(X_{a_t,t}\)</td>
    </tr>
  </tbody>
</table>

<p>The algorithm aims to minimize the deficit suffered from not always choosing the arm, with the highest total expected reward.
Let’s define this deficit as Pseudo-Regret:</p>

\[R = \max_{a\in [k]} \mathbb{E}\Big[\sum_{i\in[T]}X_{a,t} - \sum_{i\in[T]}X_{a_t,t} \Big]\]

<p>For this article, let’s assume that all stochastic rewards are drawn from Normal Distribution with a mean between 0 and 1, 1 standard deviation, and capped between -5 and 6.</p>

<p> 
 
 </p>

<h4 id="explore-then-commit">Explore-then-commit:</h4>

<p>Let’s start with a simple algorithm: explore arms uniformly selecting each action \(N\) times <em>(exploration phase)</em> and then committing to the best arm for the remaining \(T-NK\) rounds <em>(exploitation phase)</em>.</p>

<p>This simple-looking algorithm suffers from sub-linear i.e. o(T) regret.</p>

<p>Proof sketch:</p>

<p>From <a href="https://en.wikipedia.org/wiki/Hoeffding%27s_inequality">Hoeffding’s inequality</a>, we can infer that if \(N\) is chosen large enough, then the mean reward for each arm estimated by sampling in the exploration phase is almost equal to the true mean reward of the arm. Then the total regret for exploration rounds is bounded by \(NK\) times \(\max_{a\in[K]}\Delta_a\), and the total regret in exploration rounds should be close to negligible.</p>

<p style="font-size: small; font-style: italic;">(<a href="https://en.wikipedia.org/wiki/Hoeffding%27s_inequality">Hoeffding's inequality</a> is a type of <a href="https://en.wikipedia.org/wiki/Concentration_inequality">Concentration inequality</a>, such inequalities come in useful for proving bounds on various bandits algorithms.)</p>

<p>Let \(\mu_a\) be true mean of arm \(a\) and \(\overline{\mu}_{a,t}\) be the mean estimated by sampling untill round \(t\). 
Then, by <a href="https://en.wikipedia.org/wiki/Hoeffding%27s_inequality">Hoeffding’s inequality</a></p>

\[\implies\mathbb{P}\big[ \lvert \mu_a - \overline{\mu}_{a,t} \rvert &gt; \delta_{a,t} \big] \leq  2e^{\frac{-2n_a(t)\cdot\delta_{a,t}^2}{(6 - (-5 ))^2}} = 2e^{\frac{-2n_a(t)\cdot\delta_{a,t}^2}{121}}\]

<p>Let \(\delta_{a,t} = \sqrt{\frac{2\cdot 121\cdot log(T)}{n_a(t)}}\)</p>

\[\implies \mathbb{P}\big[ \lvert \mu_a - \overline{\mu}_{a,t} \rvert &gt; \delta_{a,t} \big] \leq\frac{2}{T^4}\]

<p>By Union Bound, \(\mathbb{P}\big[ \cup_{\forall a \in [K],t\in [T]} \lvert\mu_a - \overline{\mu}_{a,t} \rvert &gt; \delta_{a,t}\big] \leq \sum_{t\in[T]}\sum_{a\in[K]} \frac{2}{T^4} \lt \frac{2}{T^4}\)</p>

<p style="font-size: small; font-style: italic;">(For this particular proof we don't need such a strict condition on the difference between empirical and true mean, this proof only requires that the empirical mean is close to the true mean for <span style="font-family: serif;">t = NK</span> and not all <span style="font-family: serif;">t &in; [T]</span>. But this extra condition will be helpful for further proofs.)</p>

<p>Let the event that for all \(a\in[K]\) and \(t\in[T]\) , \(\lvert\mu_a - \overline \mu_{a,t}\rvert \leq \delta_{a,t}\) be called clean event, and it occurs with probabilty \(\geq 1-O(\frac{1}{T^2})\)</p>

<p>The total regret suffered by the algorithm is the regret suffered in the exploration phase + the regret suffered in the exploitation phase. The regret in any 1 round of the exploration phase is bounded by the limits of rewards distribution <em>(6 - (-5))</em> and in the exploitation phase, with high probability <em>(clean event occurred)</em> is no more than \(\max_{a} 2\delta_{a,NK}\) and with small probability <em>(clean even didn’t happen)</em> is bounded by the limit of rewards distribution.</p>

\[\implies \mathbb{E}[R] \leq N\cdot K\cdot 11 + (1-O(\frac{1}{T^2}))\cdot\max_{a} 2\delta_{a,NK} + O(\frac{1}{T^2})\cdot 11\]

<p>to minimize the above equation we can assume \(N\) to be \(O\big((\frac{T^2\log T}{K^2})^\frac{1}{3}\big)\) and \(\delta_{a,NK}\) for any arm is \(O\big(\sqrt{ \frac{2\cdot121\cdot\log(T)}{N} }\big)\)</p>

\[\implies \mathbb{E}[R] = O\big( T^{\frac{2}{3}}K^\frac{1}{3}(\log T)^\frac{1}{3} \big)\]

<p style="text-align: right;">&#9633;</p>

<p>A Python code implementation of the above algorithm looks like:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Explore_then_commit</span><span class="p">:</span>
	<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">actions</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">actions</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">N</span> <span class="o">=</span> <span class="p">(</span><span class="n">T</span><span class="o">**</span><span class="p">(</span><span class="mi">2</span><span class="o">/</span><span class="mi">3</span><span class="p">))</span><span class="o">*</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">T</span><span class="p">)</span><span class="o">**</span><span class="mi">1</span><span class="o">/</span><span class="mi">3</span><span class="p">)</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span>
	<span class="k">def</span> <span class="nf">get_weights</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="n">t</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">N</span><span class="p">:</span>
			<span class="k">return</span> <span class="p">[</span><span class="mi">1</span> <span class="k">if</span> <span class="n">arm</span> <span class="o">==</span> <span class="n">actions</span><span class="p">[</span><span class="n">t</span><span class="o">%</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">]</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">arm</span> <span class="ow">in</span> <span class="n">actions</span> <span class="p">]</span>
		<span class="n">best_arm</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span> <span class="n">actions</span> <span class="p">,</span> <span class="n">key</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">action</span> <span class="p">:</span> <span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">/</span><span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span> <span class="p">)</span>
		<span class="n">weights</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span> <span class="k">if</span> <span class="n">action</span> <span class="o">==</span> <span class="n">best_arm</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">action</span> <span class="ow">in</span> <span class="n">actions</span><span class="p">]</span>
		<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
	<span class="k">def</span> <span class="nf">next_action</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span> <span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span> <span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">return</span> <span class="n">choose_action</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">get_weights</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">))</span>	
	<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">chosen_action</span><span class="p">,</span> <span class="n">reward</span><span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">pass</span>
</code></pre></div></div>
<p>The implementation of the function choose action is as follows:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">choose_action</span><span class="p">(</span> <span class="n">weights</span> <span class="p">):</span>
	<span class="n">weights</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span><span class="o">/</span><span class="nb">sum</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
	<span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
	<span class="n">choice</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">))</span> <span class="p">,</span> <span class="n">p</span><span class="o">=</span><span class="n">weights</span><span class="p">)</span>
	<span class="k">return</span> <span class="n">choice</span>
</code></pre></div></div>
<p>Here,</p>
<ul>
  <li>np is the library numpy</li>
  <li>the variable actions is the set \([K]\),</li>
  <li>history is a list of tuple of \((a_t,X_{a_t,t})\)</li>
  <li>reward_dict is a dictionary storing the number of pulls and the sum of rewards for each action.</li>
  <li>The function get_weights at any point returns the probabilities with which the algorithm chooses to select any action at a time instance. 
<em>Here the algorithm is deterministic so this function seems pointless but its utility will get clear in some time</em></li>
  <li>next_action returns the next action</li>
  <li>The update function is to update any internal state after observing the reward for the chosen action.
 
 
 </li>
</ul>

<h4 id="epsilon-greedy">\(\epsilon\)-Greedy:</h4>

<p>Another algorithm that achieves the same expected regret is the \(\epsilon\)-Greedy algorithm.
In each round, the algorithm chooses the arm with the highest empirical award with probability \(1-\epsilon_t\), and with probability \(\epsilon_t\) it chooses a random arm. With  \(\epsilon_t = O((\frac{K\log(t)}{t})^\frac{1}{3})\)</p>

<p>it achieves similar as explore_then _commit regret bound,</p>

\[\mathbb{E}[R] = O\big( T^{\frac{2}{3}}K^\frac{1}{3}(\log T)^\frac{1}{3} \big)\]

<p>Proof Sketch: For any round \(t\), we can expect that with a high probability that clean event occurs and that all arms would be pulled more than \(\frac{1}{2}\times\frac{\epsilon_t t}{k}\).</p>

<p>Hence regret in round \(t\) in expectation would be bounded by</p>

\[R_t \leq \Delta_{a_t} + \epsilon_t \cdot \max [\Delta_a]\]

<p>Since \(a_t\) has highest empirical reward, we can use the clean event condition and argue that</p>

\[\lvert\mu_{a*} - \mu_{a_t}\rvert \le \delta_{a_t} + \delta_{a*} \leq \sqrt{\frac{2\cdot121\log t}{n_t(a*)}}+\sqrt{\frac{2\cdot121\log t}{n_t(a_t)}}\]

\[\implies \mathbb{E}[R_t] \leq \epsilon_t\max_a \Delta_a + 2\sqrt{\frac{2\cdot2\cdot121\cdot k\log t}{\epsilon_t k}}\]

<p>Substituting the value of \(\epsilon_t\) that minimizes the expression on RHS and then summing this value for all \(t\in [T]\) gives the expected regret bound.</p>

<p style="text-align: right;">&#9633;</p>

<p>A Python code implementation of the above algorithm looks like:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">EGreedy</span><span class="p">:</span>
	<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">actions</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">epsilon</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o">/</span> <span class="n">t</span><span class="p">)</span><span class="o">**</span><span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="mi">3</span><span class="p">)</span>
	<span class="k">def</span> <span class="nf">get_weights</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">:</span>
			<span class="n">unchosen_actions</span> <span class="o">=</span> <span class="p">[</span><span class="n">el</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">actions</span> <span class="k">if</span> <span class="n">el</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="n">h</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">history</span> <span class="p">]</span> <span class="p">]</span>
			<span class="k">return</span> <span class="p">[</span><span class="mi">1</span> <span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">unchosen_actions</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)]</span> 		
		<span class="n">t</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span>
		<span class="n">best_arm</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span> <span class="n">actions</span> <span class="p">,</span> <span class="n">key</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">action</span> <span class="p">:</span> <span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">/</span><span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span> <span class="p">)</span>
		<span class="n">weights</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="bp">self</span><span class="p">.</span><span class="n">epsilon</span><span class="p">(</span><span class="n">t</span><span class="p">))</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span> <span class="k">if</span> <span class="n">action</span> <span class="o">==</span> <span class="n">best_arm</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">action</span> <span class="ow">in</span> <span class="n">actions</span><span class="p">])</span>
		<span class="n">weights</span> <span class="o">+=</span> <span class="bp">self</span><span class="p">.</span><span class="n">epsilon</span><span class="p">(</span><span class="n">t</span><span class="p">)</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="n">ones</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)</span>
		<span class="k">return</span> <span class="n">weights</span>
	<span class="k">def</span> <span class="nf">next_action</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span> <span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span> <span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">return</span> <span class="n">choose_action</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">get_weights</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">))</span>	
	<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">chosen_action</span><span class="p">,</span> <span class="n">reward</span><span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">pass</span>
</code></pre></div></div>
<p> 
 
 </p>

<h4 id="successive_elimination">Successive_Elimination:</h4>

<p>One drawback with the previous two algorithms is that the exploration phase is completely oblivious to the rewards observed. If certain arms have already shown that they have very bad rewards compared to others, there is no need to keep trying them out.
Based on this idea here is an algorithm that achieves better regret guarantees.</p>

<p>We have earlier shown that with a very high probability, the empirical mean and the true mean are within \(\delta_{a,t} = \sqrt{\frac{2\cdot121\cdot\log T}{n_t(a)}}\) difference. Based on this, for any arm at any time instance, we assume a window where its true mean lies.  \(\mu_a \in [\overline\mu_{a,t} - \delta_{a,t} , \overline\mu_{a,t} + \delta_{a,t}]\)
If at any time, we observe that the upper limit of the true mean for an arm is less than the lower limit of the true mean of another arm, we can safely assume that this arm is not the optimal arm.
The algorithm protocol is as follows: initially, all arms are active. If the upper limit of the mean reward of an arm becomes less than the lower limit of the mean reward of any other arm, mark this arm as inactive. Select any active arm at random.
This algorithm achives \(O(\sqrt{KT\log T})\) regret bound.
Proof Sketch: For any arm \(a_0\), that was last pulled at time \(t_0\), then</p>

\[\lvert\mu_{a*} - \mu_{a_0} \rvert \leq \delta_{a_0,t}+\delta{a* ,t} \leq \sqrt{\frac{2\cdot121\cdot\log T}{n_{t_0}(a_0)}}+\sqrt{\frac{2\cdot121\cdot\log T}{n_{t_0}(a*)}}\]

<p>Now, \(n_{t_0}(a*) \approx n_{t_0}(a_0) = n_{T}(a_0)\).</p>

<p>Hence, \(\lvert\mu_{a*} - \mu_{a_0} \rvert \leq O(\sqrt{\frac{\log T}{n_{T}(a_0)}})\).
The total regret suffered from by pulling this arm multiple times is \(\leq O(\sqrt{\frac{\log T}{n_{T}(a_0)}})\times n_{T}(a_0)\). On summing this quantity for all arms, the total regret for this algorithm can be bounded.</p>

<p style="text-align: right;">&#9633;</p>

<p>A Python code implementation of the above algorithm looks like:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Successive_elimination</span><span class="p">:</span>
	<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">actions</span><span class="p">,</span><span class="n">T</span><span class="p">):</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">actions</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">active_actions</span> <span class="o">=</span> <span class="n">actions</span><span class="p">.</span><span class="n">copy</span><span class="p">()</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">radius</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">n</span> <span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">T</span><span class="p">)</span><span class="o">/</span><span class="n">n</span><span class="p">)</span>
	<span class="k">def</span> <span class="nf">get_weights</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">:</span>
			<span class="n">unchosen_actions</span> <span class="o">=</span> <span class="p">[</span><span class="n">el</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">actions</span> <span class="k">if</span> <span class="n">el</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="n">h</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">history</span> <span class="p">]</span> <span class="p">]</span>
			<span class="k">return</span> <span class="p">[</span><span class="mi">1</span> <span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">unchosen_actions</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)]</span>
		<span class="k">return</span> <span class="p">[</span><span class="mi">1</span> <span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">.</span><span class="n">active_actions</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)]</span>
	<span class="k">def</span> <span class="nf">next_action</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">return</span> <span class="n">choose_action</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">get_weights</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">))</span>
	<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">chosen_action</span><span class="p">,</span> <span class="n">reward</span><span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">active_actions</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
			<span class="k">return</span>
		<span class="n">highest_lower_bound</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span> <span class="p">[</span> <span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">/</span><span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span> <span class="o">-</span> <span class="bp">self</span><span class="p">.</span><span class="n">radius</span><span class="p">(</span><span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">])</span> <span class="k">for</span> <span class="n">action</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">.</span><span class="n">active_actions</span> <span class="p">]</span> <span class="p">)</span>
		<span class="n">remaining_actions</span> <span class="o">=</span> <span class="p">[</span> <span class="n">action</span> <span class="k">for</span> <span class="n">action</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">.</span><span class="n">active_actions</span> <span class="k">if</span> <span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">/</span><span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span> <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">radius</span><span class="p">(</span><span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">])</span> <span class="o">&gt;</span> <span class="n">highest_lower_bound</span> <span class="p">]</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">active_actions</span> <span class="o">=</span> <span class="n">remaining_actions</span>
		<span class="k">return</span>
</code></pre></div></div>
<p> 
 
 </p>

<h4 id="ucb1">UCB1:</h4>
<p>Let us consider another approach with adaptive exploration. 
Assume that every arm is as good as it can possibly be and choose the arm with the highest upper limit on mean reward in each round.
The two summands in the estimation of the choice arm, \(\overline\mu+ \delta\) strike a balance between exploration and exploitation, the former increases for good arms and the latter for less explored arms.
This algorithm achieves an expected regret of \(O(\sqrt{KT\log T})\)</p>

<p>Proof Sketch:
The proof idea is the same as Successive elimination in a round \(t_0\) if an arm \(a_0\) is selected, then the regret with this round can be bounded with \(O(\sqrt{\frac{\log T}{n_{t_0}(a_0)} })\) with high probability and then the by summing this bound over all rounds, the total regret can be bounded with \(O(\sqrt{KT\log T})\).</p>

<p>A Python code implementation of the above algorithm looks like:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">UCB1</span><span class="p">:</span>
	<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">actions</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">radius</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">n</span> <span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">np</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">T</span><span class="p">)</span><span class="o">/</span><span class="n">n</span><span class="p">)</span>
	<span class="k">def</span> <span class="nf">get_weights</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">:</span>
			<span class="n">unchosen_actions</span> <span class="o">=</span> <span class="p">[</span><span class="n">el</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">actions</span> <span class="k">if</span> <span class="n">el</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="n">h</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">history</span> <span class="p">]</span> <span class="p">]</span>
			<span class="k">return</span> <span class="p">[</span><span class="mi">1</span> <span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">unchosen_actions</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)]</span>
		<span class="n">chosen_action</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">reward_dict</span> <span class="p">,</span> <span class="n">key</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">action</span><span class="p">:</span> <span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">/</span><span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span><span class="o">+</span><span class="bp">self</span><span class="p">.</span><span class="n">radius</span><span class="p">(</span><span class="n">reward_dict</span><span class="p">[</span><span class="n">action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]))</span>
		<span class="k">return</span> <span class="p">[</span><span class="mi">1</span> <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="n">chosen_action</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">actions</span><span class="p">]</span>
	<span class="k">def</span> <span class="nf">next_action</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">return</span> <span class="n">choose_action</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">get_weights</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">))</span>
	<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">chosen_action</span><span class="p">,</span> <span class="n">reward</span><span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">return</span>
</code></pre></div></div>
<p> 
 
 </p>

<h3 id="adversarial-bandits">Adversarial Bandits:</h3>

<p>Stochastic Bandits take a very strong assumption on the rewards of the actions. This strong assumption might limit the application and guarantees of the above algorithms where the i.i.d. assumption is violated. Adversarial bandits swing on the other side and take no assumption on the reward of each arm.</p>

<table>
  <thead>
    <tr>
      <th><strong>Protocol:</strong></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong><em>Parameters</em></strong>: \(K\) arms, \(T\) rounds, \(T &gt; K\), for any time \(t\in[T]\) the environment chooses reward \(X_{a,t}\) for each arm \(a \in [K]\), The environment can adapt the reward based on the algorithm protocol and the history of all chosen actions and rewards</td>
    </tr>
    <tr>
      <td>For each round \(t \in [T]\) the algorithm chooses an \(a_t\in[K]\) and observes a reward \(X_{a_t,t}\)</td>
    </tr>
  </tbody>
</table>

<p>No deterministic algorithm can hope to do well in this scenario, since the environment knows exactly which action the algorithm is going to choose apriori setting the rewards for the next round and set the rewards accordingly.
Even in this pessimistic scenario, we can guarantee some upper bounds on the regret suffered.
In adversarial bandits, pseudo-regret is defined as the deficit suffered from the best arm policy. 
\(E[R] = \max_{a\in[K]}\mathbb{E}\big[ \sum_{t\in[T]}X_{a,t} - \sum_{t\in[T]}X_{a_t,t} \big]\) 
 
 
 </p>

<h4 id="exp3">EXP3:</h4>
<p>Let’s define the loss of any reward as the difference between the maximum possible reward and the observed reward, scaled between 0 to 1, for our scenario, our rewards are bounded between -5 and 6, so our</p>

\[loss = \frac{-1}{11}\cdot(reward-6)\]

<p>The key idea in the exp3 algorithm is it tries to keep a record of cumulative loss for each arm. Since in any round reward/loss of only one action is observed keeping the exact record is not possible. The idea is to scale the loss with the inverse of the probability of observing it.</p>

<p>The loss of action \(a\) at round \(t\) is</p>

\[\tilde l_{a_0,t} = \begin{cases}
    l_{a_t,t}/\mathbb{P}[a_t = a_0] &amp; \text{if } a_t = a_0 \\ % &amp; is your "\tab"-like command (it's a tab alignment character)
    0 &amp; \text{otherwise.}
\end{cases}\]

<p>Here, \(\tilde l_{a_0,t}\) can be calculated for all arms \(a\in[K]\) irrespective if it were pulled or not.
The cummulative loss is \(\tilde L_{a,t} = \sum_{i\leq t}\tilde l_{a,i}\).</p>

<p>The expected value of \(\tilde l_{a,t}\) in round \(t\) is equal to the actual loss of the arm \(l_{a,t}\).</p>

<p>Let \(P_{a,t}\) be \(\mathbb{P}[a_t = a]\).</p>

<p>\(\implies \mathbb{E}[ \tilde l_{a_0,t}] = \sum_{a\in[K]} P_{a,t} \times \frac{l_{a,t}\cdot \mathbb{I}\{a=a_0\}}{P_{a,t}} = l_{a_0,t}\) and \(\mathbb E[\tilde l_{a,t}^2] = \frac{l_{a,t}^2}{p_{a,t}}\)</p>

<p>After the cumulative loss of each arm is known, the probability distribution for selecting an arm \(a_0\) is an exponential weight of the loss of that arm.</p>

<p>\(P_{a_0,t} = \frac{\exp(-\eta_t \tilde L_{a_0,t}) }{\sum_a \exp(-\eta \tilde L_{a,t})}\) for \(\eta \geq 0\).</p>

<p>For large \(\eta\) the algorithm tends to exploit the result and aggressively choose arms with less cumulative loss, on the other hand with smaller \(\eta\) it tends to explore more, and when \(\eta = 0\) it chooses all arms with equal likelihood.</p>

<p>If exp-3 is run with \(\eta = \sqrt{\frac{2\log K}{TK} }\) the pseudo-regret is \(\mathbb E[R] = O(\sqrt{TK\log K})\).</p>

<p>Proof Sketch:  Let \(w_{a,t} = e^{-\eta \tilde L_{a,t}}\) and \(W_{t} = \sum w_{a,t} = \sum e^{-\eta \tilde L_{a,t}}\)</p>

<p>The proof is using the idea that we can lower bound the total reduction in  \(W_T\) with the total loss incurred for any one arm. And for each round, whenever some loss \(l_{a_t,t}\) is observed, \(W_t\) can be upper bounded by the amount it reduces. Using the two bounds, we can show that the total loss incurred by the algorithm is not much larger than the loss incurred by the best arm.</p>

<p>Here is how the proof flows:</p>

<p>We can upper bound \(\frac{W_T}{W_0}\) by the total Loss of any arm as:</p>

\[\log(\frac{W_T}{W_0}) = \log(\frac{\sum_a e^{-\eta \tilde L_{a,T}}}{K}) \geq -log K - \eta \tilde L_{a,T}\text{        }\forall a\in[K]\]

<p>and for any one round \(t\), we can lower bound \(\frac {W_t}{W_{t-1}}\) by the loss incurred in that round by:</p>

\[\log(\frac{W_t}{W_{t-1}}) = \log{( \sum_a \frac{w_{a,t}}{W_{t-1}}\cdot e^{-\eta\tilde l_{a,t}}  )}=\log{( \sum_a p_{a,t}\cdot e^{-\eta\tilde l_{a,t}}  )}\]

\[\leq \log{( \sum_a p_{a,t}\cdot (1-\eta\tilde l_{a,t}+\frac{\eta^2}{2}\tilde l_{a,t}^2)  )}\leq \sum_a p_{a,t}(-\eta\tilde l_{a,t}+\frac{\eta^2}{2}\tilde l_{a,t}^2)\]

<p>This is using: \(e^x \leq 1+x+\frac{x^2}{2}\forall x \leq 0\text{ and }e^x \geq 1+x\)</p>

<p> 
 
By using the previous bound along with repeated application of the above bound for all \(t\).</p>

<p>We get that  \(\forall a: -log K - \eta \tilde L_{a,T} \leq \sum_{t\in[T]}\sum_b p_{b,t}(-\eta\tilde l_{b,t}+\frac{\eta^2}{2}\tilde l_{b,t}^2)\)</p>

<p>rearranging the term in the equation, we get:</p>

\[\sum_{t\in[T]}\sum_{b\in[K]}p_{b,t}\tilde l_{b,t} - \sum_t \tilde l_{a,t} \leq \frac{\log K}{\eta} + \frac{\eta}{2}\sum_{t\in[T]}\sum_{b\in[K]}p_{b,t}\tilde l_{b,t}^2\text{  } \forall a\]

<p>Now, using the expected value,</p>

\[\mathbb E[\sum_{t\in[T]}\sum_{b\in[K]}p_{b,t}\tilde l_{b,t} - \sum_t \tilde l_{a,t}] = \mathbb E[\sum_t l_{a_t,t} - \sum_t l_{a,t}]\]

<p>and definition of regret \(R = max_a\mathbb E[\sum l_{a_t,t} - \sum l_{a,t}]\)</p>

<p>we get the following bound on the regret.</p>

\[\implies R \leq \frac{\log K}{\eta} + \frac{\eta}{2}\sum_t\sum_b p_{b,t}\mathbb E [\tilde l_{b,t}^2] = \frac{\log K}{\eta} + \frac{\eta}{2}\sum_t\sum_b l_{b,t}^2 = \frac{\log K}{\eta} + \frac{\eta}{2}KT\Delta \text{ ; where }\Delta = \max_a \Delta_a\]

<p>A Python code implementation of the above algorithm looks like:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">EXP3</span><span class="p">:</span>
	<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">actions</span><span class="p">,</span><span class="n">T</span><span class="p">):</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">actions</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">L</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">zeros</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">p</span> <span class="o">=</span> <span class="bp">None</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">eta</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span> <span class="n">np</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">T</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)</span>  <span class="p">)</span>
	<span class="k">def</span> <span class="nf">get_weights</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="n">t</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span>
		<span class="k">return</span> <span class="p">[</span> <span class="n">np</span><span class="p">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">*</span> <span class="bp">self</span><span class="p">.</span><span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">eta</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)</span>  <span class="p">]</span>
	<span class="k">def</span> <span class="nf">next_action</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span> <span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span> <span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">p</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">get_weights</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">))</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">p</span> <span class="o">/=</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">p</span><span class="p">)</span>
		<span class="k">return</span> <span class="n">choose_action</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">p</span><span class="p">)</span>
	<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">chosen_action</span><span class="p">,</span> <span class="n">reward</span><span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="n">loss</span> <span class="o">=</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="o">/</span><span class="mi">11</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">reward</span><span class="o">-</span><span class="mi">6</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">L</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">]</span> <span class="o">+=</span> <span class="n">loss</span> <span class="o">/</span> <span class="bp">self</span><span class="p">.</span><span class="n">p</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">]</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">p</span> <span class="o">=</span> <span class="bp">None</span>
		<span class="k">return</span>
</code></pre></div></div>

<p>For a better understanding and complete proofs of the above algorithms, we refer to these three surveys:</p>

<p><strong>Bandits, Multi-Armed</strong>. (n.d.). <em>Introduction to Multi-Armed Bandits</em>.</p>

<p><strong>Bubeck, Sébastien, &amp; Cesa-Bianchi, Nicolo</strong>. (2012). <em>Regret analysis of stochastic and nonstochastic multi-armed bandit problems</em>. <em>Foundations and Trends® in Machine Learning</em>, 5(1), 1–122. Now Publishers, Inc.</p>

<p><strong>Lattimore, Tor, &amp; Szepesvári, Csaba</strong>. (2020). <em>Bandit algorithms</em>. Cambridge University Press.</p>

<p> 
 
 </p>

<h3 id="stochastic-bandits-with-adversarial-corruption">Stochastic Bandits with Adversarial Corruption:</h3>
<p>Both Stochastic and adversarial bandits swing too far with their assumptions on the reward scenarios. Here we want to discuss the work of Lykouris, Mirrokni, and Paes Leme (2018)</p>

<p>{Lykouris, Thodoris, Mirrokni, Vahab, &amp; Paes Leme, Renato. (2018). <em>Stochastic bandits robust to adversarial corruptions</em>. In <em>Proceedings of the 50th Annual ACM SIGACT Symposium on Theory of Computing</em> (pp. 114–122).}</p>

<p>Another approach to the reward assumption can be in a middle ground, in this model we assume that rewards are initially drawn from a fixed distribution, but are adulterated with a finite amount of corruption by an adaptive adversary.</p>

<table>
  <thead>
    <tr>
      <th><strong>Protocol:</strong></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong><em>Parameters</em></strong>: \(K\) arms, \(T\) rounds, \(T &gt; K\), for any time \(t\in[T]\) the environment chooses reward \(X_{a,t}\) for each arm \(a \in [K]\) from distribution \(D_a\). The adversary chooses a corruption \(c_{a,t}\) based on the algorithm protocol and the history of all chosen actions and rewards. The total corruption is bounded: \(\sum_t max_a \lvert c_{a,t}\rvert \text{  }\leq C\).</td>
    </tr>
    <tr>
      <td>For each round \(t \in [T]\) the algorithm chooses an \(a_t\in[K]\) and observes the corrupted reward \(X_{a_t,t}+c_{a,t}\)</td>
    </tr>
  </tbody>
</table>

<p>By varying the total corruption this model generalizes both stochastic and adversarial bandits.
 
 
 </p>

<h4 id="multi-layer-active-arm-elimination-race">Multi-layer Active Arm Elimination Race:</h4>
<p>This algorithm extends successive elimination. In successive elimination, we kept a record of all active arms and eliminated arms, under the assumption of clean event if they could not be the best arms. The idea is similar, but instead of keeping a single such list, the algorithm maintains multiple such lists, let’s call them layers(assume \(n\) layers). In each round, it selects a layer with probability \(\propto_{\approx} 2^{-n}\). The layer n updates its dictionaries of the number of arm pulls and empirical means, only when the layer is selected. The result of each subsequent layer is more robust to the corruption since they are likely to only admit about \(2^{-n}\) times the corruption, in their dictionaries. Whenever a layer \(n\) concludes that an arm \(a\) needs to be eliminated from all its previous layers, also remove that arm. In case a layer is selected but has no active arms, it selects the arm based on the next smallest layer that is not empty.</p>

<p>A Python code implementation of the above algorithm looks like:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">MultiLayer_active_arm_elimination</span><span class="p">:</span>
	<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">actions</span><span class="p">,</span><span class="n">T</span><span class="p">):</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">actions</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">ceil</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">T</span><span class="p">)))</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">sum_rewards</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">zeros</span><span class="p">(</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="p">,</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)</span> <span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">num_pulls</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="p">,</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">))</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span> <span class="o">=</span> <span class="p">[</span> <span class="n">actions</span><span class="p">.</span><span class="n">copy</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="p">)</span>  <span class="p">]</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span> <span class="o">=</span> <span class="bp">None</span>
		<span class="n">alpha</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">n</span> <span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="mi">4</span><span class="o">*</span> <span class="bp">self</span><span class="p">.</span><span class="n">k</span> <span class="o">*</span> <span class="n">T</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">T</span><span class="p">)</span> <span class="o">/</span> <span class="mf">0.01</span> <span class="p">)</span> <span class="o">/</span> <span class="n">n</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">radius</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">n</span> <span class="p">:</span> <span class="n">alpha</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="o">+</span> <span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">alpha</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
	<span class="k">def</span> <span class="nf">get_weight_nthlayer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="n">n</span><span class="p">])</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
			<span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">get_weight_nthlayer</span><span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">)</span>
		<span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span> <span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">actions</span><span class="p">])</span>	
	<span class="k">def</span> <span class="nf">get_weights</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="n">weights</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">zeros</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)</span>
		<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="p">):</span>
			<span class="n">weights</span> <span class="o">+=</span> <span class="mi">2</span><span class="o">**</span><span class="p">(</span> <span class="o">-</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="p">)</span> <span class="o">*</span> <span class="bp">self</span><span class="p">.</span><span class="n">get_weight_nthlayer</span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
		<span class="n">weights</span> <span class="o">+=</span> 	<span class="mi">2</span><span class="o">**</span><span class="p">(</span> <span class="o">-</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="p">)</span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">get_weight_nthlayer</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
		<span class="k">return</span> <span class="n">weights</span>
	<span class="k">def</span> <span class="nf">next_action</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">):</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">:</span>
			<span class="n">unchosen_actions</span> <span class="o">=</span> <span class="p">[</span><span class="n">el</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">actions</span> <span class="k">if</span> <span class="n">el</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="n">h</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">history</span> <span class="p">]</span> <span class="p">]</span>
			<span class="k">return</span> <span class="n">choose_action</span><span class="p">([</span><span class="mi">1</span> <span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">unchosen_actions</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">)])</span>
		<span class="n">p</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">2</span><span class="o">**</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="o">*</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="p">)</span> <span class="p">]</span>
		<span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">2</span><span class="o">**</span><span class="p">(</span> <span class="o">-</span><span class="mi">1</span><span class="o">*</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="p">)</span> <span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="p">)</span>  <span class="p">,</span> <span class="n">p</span> <span class="o">=</span> <span class="n">p</span> <span class="p">)</span>
		<span class="k">return</span> <span class="n">choose_action</span><span class="p">(</span> <span class="bp">self</span><span class="p">.</span><span class="n">get_weight_nthlayer</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">history</span><span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">)</span> <span class="p">)</span>
	<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">chosen_action</span><span class="p">,</span> <span class="n">reward</span><span class="p">,</span> <span class="n">history</span> <span class="p">,</span> <span class="n">reward_dict</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="p">.</span><span class="n">k</span><span class="p">:</span>
			<span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_layers</span><span class="p">):</span>
				<span class="bp">self</span><span class="p">.</span><span class="n">num_pulls</span><span class="p">[</span><span class="n">layer</span><span class="p">][</span><span class="n">chosen_action</span><span class="p">]</span><span class="o">+=</span><span class="mi">1</span>
				<span class="bp">self</span><span class="p">.</span><span class="n">sum_rewards</span><span class="p">[</span><span class="n">layer</span><span class="p">][</span><span class="n">chosen_action</span><span class="p">]</span><span class="o">+=</span><span class="n">reward</span>
			<span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span> <span class="o">=</span> <span class="bp">None</span>
			<span class="k">return</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">num_pulls</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">][</span><span class="n">chosen_action</span><span class="p">]</span><span class="o">+=</span><span class="mi">1</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">sum_rewards</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">][</span><span class="n">chosen_action</span><span class="p">]</span><span class="o">+=</span><span class="n">reward</span>
		<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">])</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
			<span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span> <span class="o">=</span> <span class="bp">None</span>
			<span class="k">return</span>
		<span class="n">lower_bounds</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span>			
			<span class="bp">self</span><span class="p">.</span><span class="n">sum_rewards</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">][</span><span class="n">arm</span><span class="p">]</span><span class="o">/</span><span class="bp">self</span><span class="p">.</span><span class="n">num_pulls</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">][</span><span class="n">arm</span><span class="p">]</span> 
			<span class="o">-</span> <span class="bp">self</span><span class="p">.</span><span class="n">radius</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_pulls</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">][</span><span class="n">arm</span><span class="p">])</span>			
			<span class="p">)</span>
			 <span class="k">for</span> <span class="n">arm</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">]</span> <span class="p">]</span>
		<span class="n">highest_lower_bound</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">lower_bounds</span><span class="p">)</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">arm</span> <span class="k">for</span> <span class="n">arm</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">]</span>
				<span class="k">if</span> <span class="p">(</span>
				<span class="bp">self</span><span class="p">.</span><span class="n">sum_rewards</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">][</span><span class="n">arm</span><span class="p">]</span><span class="o">/</span><span class="bp">self</span><span class="p">.</span><span class="n">num_pulls</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">][</span><span class="n">arm</span><span class="p">]</span>
				 <span class="o">+</span> <span class="bp">self</span><span class="p">.</span><span class="n">radius</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">num_pulls</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">][</span><span class="n">arm</span><span class="p">]</span> <span class="p">)</span> 
				 <span class="p">)</span> 
					<span class="o">&gt;</span> <span class="n">highest_lower_bound</span> 
				<span class="p">]</span>
		<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">):</span>
			<span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">&amp;</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">active_arms</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span><span class="p">]))</span>
		<span class="bp">self</span><span class="p">.</span><span class="n">chosen_layer</span> <span class="o">=</span> <span class="bp">None</span>
		<span class="k">return</span>
</code></pre></div></div>
<p> 
 
 </p>

<h3 id="simulations">Simulations:</h3>

<p>Now that we have introduced all the algorithms, let’s see how they practically fare, by running some simulations.
 
 
 </p>

<h4 id="stochastic-bandits-1">Stochastic Bandits:</h4>
<p>Consider the case of when the rewards follow i.i.d. assumption at each time step.
The simulation code is as follows:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">simulate_stochastic_bandits</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">mean_rewards</span> <span class="p">,</span> <span class="n">solver</span><span class="p">):</span>
	<span class="k">assert</span> <span class="n">k</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span>
	<span class="n">actions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">))</span>
	<span class="n">reward_dict</span> <span class="o">=</span> <span class="p">{</span><span class="n">action</span><span class="p">:</span> <span class="p">{</span> <span class="s">'num_pulls'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s">'sum_rewards'</span><span class="p">:</span><span class="mi">0</span><span class="p">}</span> <span class="k">for</span> <span class="n">action</span> <span class="ow">in</span> <span class="n">actions</span><span class="p">}</span>
	<span class="c1"># a list of tuple of action chosen and reward observed
</span>	<span class="n">history</span> <span class="o">=</span> <span class="p">[</span>  <span class="p">]</span>
	<span class="n">mab</span> <span class="o">=</span> <span class="n">solver</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span> <span class="n">T</span><span class="p">)</span>
	<span class="k">for</span> <span class="n">iteration</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">T</span><span class="p">):</span>
		<span class="n">chosen_action</span> <span class="o">=</span> <span class="n">mab</span><span class="p">.</span><span class="n">next_action</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
	<span class="c1"># sampling reward for the chosen action
</span>		<span class="n">reward</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">normal</span><span class="p">(</span><span class="n">loc</span> <span class="o">=</span> <span class="n">mean_rewards</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">]</span> <span class="p">,</span> <span class="n">scale</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="n">reward</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span><span class="n">reward</span><span class="p">)</span>
		<span class="n">mab</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">chosen_action</span><span class="p">,</span><span class="n">reward</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
	<span class="c1">#updating the history of actions and rewards and dict of number of pulls and sum of rewards
</span>		<span class="n">history</span><span class="p">.</span><span class="n">append</span><span class="p">(</span> <span class="p">(</span><span class="n">chosen_action</span> <span class="p">,</span> <span class="n">reward</span><span class="p">)</span> <span class="p">)</span>
		<span class="n">reward_dict</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span><span class="o">+=</span><span class="mi">1</span>
		<span class="n">reward_dict</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">+=</span><span class="n">reward</span>
	<span class="n">regret</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span> <span class="o">-</span> <span class="nb">sum</span><span class="p">([</span><span class="n">el</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">history</span><span class="p">])</span><span class="o">/</span><span class="n">T</span>
	<span class="k">return</span><span class="p">(</span> <span class="nb">max</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span> <span class="p">,</span> <span class="nb">sum</span><span class="p">([</span><span class="n">el</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">history</span><span class="p">])</span><span class="o">/</span><span class="n">T</span>  <span class="p">,</span> <span class="n">regret</span> <span class="p">)</span>
</code></pre></div></div>

<p>Here, history is a list of tuples of actions chosen and rewards observed, the reward dictionary maintains the number of pulls and sum of rewards for each action. The simulation returns the maximum expected reward for an arm, the average reward observed by the algorithm, and the average regret suffered by the algorithm.</p>

<p>Let’s observe the regret for \(k = 3\), with mean rewards be \([0,0.3,1]\) and \(T = 50000\).
The results are:</p>

<table>
  <thead>
    <tr>
      <th>algorithm</th>
      <th>Expected reward of optimal arm</th>
      <th>Average reward in each round</th>
      <th>average Regret in each round</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Explore_then_commit</td>
      <td>1.0</td>
      <td>0.82844</td>
      <td>0.17156</td>
    </tr>
    <tr>
      <td>EGreedy</td>
      <td>1.0</td>
      <td>0.83584</td>
      <td>0.16416</td>
    </tr>
    <tr>
      <td>Successive_elimination</td>
      <td>1.0</td>
      <td>0.99825</td>
      <td>0.00175</td>
    </tr>
    <tr>
      <td>UCB1</td>
      <td>1.0</td>
      <td>0.99574</td>
      <td>0.00426</td>
    </tr>
    <tr>
      <td>EXP3</td>
      <td>1.0</td>
      <td>0.88704</td>
      <td>0.11296</td>
    </tr>
    <tr>
      <td>MultiLayer_active_arm_elimination</td>
      <td>1.0</td>
      <td>0.94698</td>
      <td>0.05302</td>
    </tr>
  </tbody>
</table>

<p> 
 
 </p>
<h4 id="stochastic-bandits-with-switched-mean">Stochastic Bandits with switched mean:</h4>
<p>Let’s simulate another scenario in which the mean rewards are switched after T/2 rounds.</p>

<p>The simulation code is as follows:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">simulate_switchmean_stochastic_bandits</span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="n">T</span><span class="p">,</span><span class="n">mean_rewards</span><span class="p">,</span><span class="n">switched_rewards</span><span class="p">,</span><span class="n">solver</span><span class="p">):</span>
	<span class="k">assert</span> <span class="n">k</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">switched_rewards</span><span class="p">)</span>
	<span class="n">actions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">))</span>
	<span class="n">reward_dict</span> <span class="o">=</span> <span class="p">{</span><span class="n">action</span><span class="p">:</span> <span class="p">{</span> <span class="s">'num_pulls'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s">'sum_rewards'</span><span class="p">:</span><span class="mi">0</span><span class="p">}</span> <span class="k">for</span> <span class="n">action</span> <span class="ow">in</span> <span class="n">actions</span><span class="p">}</span>
	<span class="n">history</span> <span class="o">=</span> <span class="p">[]</span>
	<span class="n">mab</span> <span class="o">=</span> <span class="n">solver</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span> <span class="n">T</span><span class="p">)</span>
	<span class="k">for</span> <span class="n">iteration</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">T</span><span class="p">):</span>
		<span class="n">chosen_action</span> <span class="o">=</span> <span class="n">mab</span><span class="p">.</span><span class="n">next_action</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">normal</span><span class="p">(</span><span class="n">loc</span> <span class="o">=</span> <span class="n">mean_rewards</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">]</span> <span class="p">,</span> <span class="n">scale</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span>
		<span class="k">if</span> <span class="n">iteration</span> <span class="o">&gt;</span> <span class="n">T</span><span class="o">//</span><span class="mi">2</span><span class="p">:</span>
			<span class="n">reward</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">normal</span><span class="p">(</span><span class="n">loc</span> <span class="o">=</span> <span class="n">switched_rewards</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">]</span> <span class="p">,</span> <span class="n">scale</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="n">reward</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span><span class="n">reward</span><span class="p">)</span>
		<span class="n">mab</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">chosen_action</span><span class="p">,</span><span class="n">reward</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
		<span class="n">history</span><span class="p">.</span><span class="n">append</span><span class="p">(</span> <span class="p">(</span><span class="n">chosen_action</span> <span class="p">,</span> <span class="n">reward</span><span class="p">)</span> <span class="p">)</span>
		<span class="n">reward_dict</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span><span class="o">+=</span><span class="mi">1</span>
		<span class="n">reward_dict</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">+=</span><span class="n">reward</span>
	<span class="n">regret</span> <span class="o">=</span>  <span class="nb">max</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nb">max</span><span class="p">(</span><span class="n">switched_rewards</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span> <span class="o">-</span> <span class="nb">sum</span><span class="p">([</span><span class="n">el</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">history</span><span class="p">])</span><span class="o">/</span><span class="n">T</span>
	<span class="k">return</span><span class="p">((</span><span class="nb">max</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nb">max</span><span class="p">(</span><span class="n">switched_rewards</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span> <span class="p">),(</span><span class="nb">sum</span><span class="p">([</span><span class="n">el</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">history</span><span class="p">])</span><span class="o">/</span><span class="n">T</span><span class="p">),</span><span class="n">regret</span><span class="p">)</span>
</code></pre></div></div>
<p>Let’s observe the regret for \(k = 3\), with mean rewards be \([0,0.3,1]\) and switched rewards be \([1,0.3,0]\) and \(T = 50000\).
The results are:</p>

<table>
  <thead>
    <tr>
      <th>algorithm</th>
      <th>Expected reward of optimal arm</th>
      <th>Average reward in each round</th>
      <th>average Regret in each round</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Explore_then_commit</td>
      <td>1.0</td>
      <td>0.3263</td>
      <td>0.6737</td>
    </tr>
    <tr>
      <td>EGreedy</td>
      <td>1.0</td>
      <td>0.45929</td>
      <td>0.54071</td>
    </tr>
    <tr>
      <td>Successive_elimination</td>
      <td>1.0</td>
      <td>0.49763</td>
      <td>0.50237</td>
    </tr>
    <tr>
      <td>UCB1</td>
      <td>1.0</td>
      <td>0.89242</td>
      <td>0.10757</td>
    </tr>
    <tr>
      <td>EXP3</td>
      <td>1.0</td>
      <td>0.50991</td>
      <td>0.49009</td>
    </tr>
    <tr>
      <td>MultiLayer_active_arm_elimination</td>
      <td>1.0</td>
      <td>0.45982</td>
      <td>0.54018</td>
    </tr>
  </tbody>
</table>

<p> 
 
 </p>
<h4 id="adaptive-adversarial-bandits">Adaptive Adversarial bandits:</h4>
<p>Let’s simulate the case where the adversary for the first T/10 rounds, simulates stochastic bandits, and then sets the reward for each arm either 0 or 1, depending if the probability of it getting pulled is greater or less than \(1/K\).
The simulation code is as follows:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">simluate_adaptive_adversarial_bandits</span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="n">T</span><span class="p">,</span><span class="n">mean_rewards</span><span class="p">,</span><span class="n">solver</span><span class="p">):</span>
	<span class="k">assert</span> <span class="n">k</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span>
	<span class="n">actions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">))</span>
	<span class="n">reward_dict</span> <span class="o">=</span> <span class="p">{</span><span class="n">action</span><span class="p">:</span> <span class="p">{</span> <span class="s">'num_pulls'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s">'sum_rewards'</span><span class="p">:</span><span class="mi">0</span><span class="p">}</span> <span class="k">for</span> <span class="n">action</span> <span class="ow">in</span> <span class="n">actions</span><span class="p">}</span>
	<span class="n">history</span> <span class="o">=</span> <span class="p">[]</span>
	<span class="n">rewards</span> <span class="o">=</span> <span class="p">[]</span>
	<span class="n">mab</span> <span class="o">=</span> <span class="n">solver</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span> <span class="n">T</span><span class="p">)</span>
	<span class="k">for</span> <span class="n">iteration</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">T</span><span class="p">):</span>
		<span class="n">weights</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">mab</span><span class="p">.</span><span class="n">get_weights</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="n">float64</span><span class="p">)</span>
		<span class="n">weights</span> <span class="o">/=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
		<span class="k">if</span> <span class="n">iteration</span> <span class="o">&lt;</span> <span class="n">T</span><span class="o">/</span><span class="mi">10</span><span class="p">:</span>
			<span class="n">current_rewards</span> <span class="o">=</span> <span class="p">[</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">normal</span><span class="p">(</span><span class="n">loc</span> <span class="o">=</span> <span class="n">mean_rewards</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">,</span> <span class="n">scale</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">)</span> <span class="p">]</span>
		<span class="k">else</span><span class="p">:</span>
			<span class="n">current_rewards</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">0</span> <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="o">/</span><span class="n">k</span> <span class="k">else</span> <span class="mi">1</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">weights</span> <span class="p">]</span>
		<span class="n">chosen_action</span> <span class="o">=</span> <span class="n">mab</span><span class="p">.</span><span class="n">next_action</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="n">current_rewards</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">]</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="n">reward</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span><span class="n">reward</span><span class="p">)</span>
		<span class="n">mab</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">chosen_action</span><span class="p">,</span><span class="n">reward</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
		<span class="n">rewards</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">current_rewards</span><span class="p">)</span>
		<span class="n">history</span><span class="p">.</span><span class="n">append</span><span class="p">(</span> <span class="p">(</span><span class="n">chosen_action</span> <span class="p">,</span> <span class="n">reward</span><span class="p">)</span> <span class="p">)</span>
		<span class="n">reward_dict</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span><span class="o">+=</span><span class="mi">1</span>
		<span class="n">reward_dict</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">+=</span><span class="n">reward</span>
	<span class="n">rewards</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">rewards</span><span class="p">)</span>
	<span class="n">sum_rewards</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">rewards</span><span class="p">,</span> <span class="n">axis</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
	<span class="n">regret</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">sum_rewards</span><span class="p">)</span><span class="o">/</span><span class="n">T</span> <span class="o">-</span> <span class="nb">sum</span><span class="p">([</span><span class="n">el</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">history</span><span class="p">])</span><span class="o">/</span> <span class="n">T</span>
	<span class="k">return</span> <span class="p">((</span><span class="nb">max</span><span class="p">(</span><span class="n">sum_rewards</span><span class="p">)</span> <span class="o">/</span> <span class="n">T</span><span class="p">),(</span><span class="nb">sum</span><span class="p">([</span><span class="n">el</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">history</span><span class="p">])</span><span class="o">/</span> <span class="n">T</span><span class="p">),</span><span class="n">regret</span><span class="p">)</span>
</code></pre></div></div>
<p>Let \(k = 3\), mean rewards be \([0,0.3,1]\) and T = 50000.
The results are:</p>

<table>
  <thead>
    <tr>
      <th>algorithm</th>
      <th>Expected reward of optimal arm</th>
      <th>Average reward in each round</th>
      <th>average Regret in each round</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Explore_then_commit</td>
      <td>0.83454</td>
      <td>0.04437</td>
      <td>0.79016</td>
    </tr>
    <tr>
      <td>EGreedy</td>
      <td>0.68796</td>
      <td>0.23788</td>
      <td>0.45008</td>
    </tr>
    <tr>
      <td>Successive_elimination</td>
      <td>0.92911</td>
      <td>0.09626</td>
      <td>0.83285</td>
    </tr>
    <tr>
      <td>UCB1</td>
      <td>0.89915</td>
      <td>0.09995</td>
      <td>0.7992</td>
    </tr>
    <tr>
      <td>EXP3</td>
      <td>0.53629</td>
      <td>0.51533</td>
      <td>0.02097</td>
    </tr>
    <tr>
      <td>MultiLayer_active_arm_elimination</td>
      <td>0.65429</td>
      <td>0.12936</td>
      <td>0.52493</td>
    </tr>
  </tbody>
</table>

<p> 
 
 </p>
<h4 id="stochastic-bandits-with-finite-corruption">Stochastic bandits with finite corruption:</h4>
<p>Let’s simulate the case, where the rewards are drawn from an i.i.d. assumption, but an adversary can inject a finite amount of adversarial noise in order to increase the regret of the algorithm.
There can be many strategies for the adversary, but we are using a strategy that whenever the algorithm has greater than \(1/K\) probability of choosing the best arm, it reduces its reward by 5 and increases the reward of all other arms by 5.
The simulation code is as follows:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">simulate_stochastic_bandits_with_finite_corruption</span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="n">T</span><span class="p">,</span><span class="n">mean_rewards</span><span class="p">,</span><span class="n">corruption_limit</span><span class="p">,</span><span class="n">solver</span><span class="p">):</span>
	<span class="n">actions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">))</span>
	<span class="n">reward_dict</span> <span class="o">=</span> <span class="p">{</span><span class="n">action</span><span class="p">:</span> <span class="p">{</span> <span class="s">'num_pulls'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s">'sum_rewards'</span><span class="p">:</span><span class="mi">0</span><span class="p">}</span> <span class="k">for</span> <span class="n">action</span> <span class="ow">in</span> <span class="n">actions</span><span class="p">}</span>
	<span class="n">history</span> <span class="o">=</span> <span class="p">[]</span>
	<span class="n">rewards</span> <span class="o">=</span> <span class="p">[]</span>
	<span class="n">corruption_used</span> <span class="o">=</span> <span class="mi">0</span>
	<span class="n">mab</span> <span class="o">=</span> <span class="n">solver</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span> <span class="n">T</span><span class="p">)</span>
	<span class="n">best_arm</span> <span class="o">=</span> <span class="n">mean_rewards</span><span class="p">.</span><span class="n">index</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">))</span>
	<span class="k">for</span> <span class="n">iteration</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">T</span><span class="p">):</span>
		<span class="n">weights</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">mab</span><span class="p">.</span><span class="n">get_weights</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="n">float64</span><span class="p">)</span>
		<span class="n">weights</span> <span class="o">/=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
		<span class="n">current_rewards</span> <span class="o">=</span> <span class="p">[</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">normal</span><span class="p">(</span><span class="n">loc</span> <span class="o">=</span> <span class="n">mean_rewards</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">,</span> <span class="n">scale</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">k</span><span class="p">)</span> <span class="p">]</span>
		<span class="k">if</span> <span class="n">weights</span><span class="p">[</span><span class="n">best_arm</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="mi">1</span><span class="o">/</span><span class="n">k</span> <span class="ow">and</span> <span class="n">corruption_used</span> <span class="o">&lt;</span> <span class="n">corruption_limit</span><span class="p">:</span>
			<span class="c1"># for i in range(1,k):
</span>				<span class="c1"># current_rewards[i] -= 1
</span>			<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">k</span><span class="p">):</span>
				<span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">best_arm</span><span class="p">:</span>
					<span class="n">current_rewards</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">5</span>
			<span class="n">current_rewards</span><span class="p">[</span><span class="n">best_arm</span><span class="p">]</span> <span class="o">-=</span> <span class="mi">5</span>
			<span class="n">corruption_used</span> <span class="o">+=</span><span class="mi">5</span>
		<span class="n">chosen_action</span> <span class="o">=</span> <span class="n">mab</span><span class="p">.</span><span class="n">next_action</span><span class="p">(</span><span class="n">actions</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="n">current_rewards</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">]</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="n">reward</span><span class="p">)</span>
		<span class="n">reward</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span><span class="n">reward</span><span class="p">)</span>
		<span class="n">mab</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">chosen_action</span><span class="p">,</span><span class="n">reward</span><span class="p">,</span><span class="n">history</span><span class="p">,</span><span class="n">reward_dict</span><span class="p">,</span><span class="n">T</span><span class="p">)</span>
		<span class="n">rewards</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">current_rewards</span><span class="p">)</span>
		<span class="n">history</span><span class="p">.</span><span class="n">append</span><span class="p">(</span> <span class="p">(</span><span class="n">chosen_action</span> <span class="p">,</span> <span class="n">reward</span><span class="p">)</span> <span class="p">)</span>
		<span class="n">reward_dict</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">][</span><span class="s">'num_pulls'</span><span class="p">]</span><span class="o">+=</span><span class="mi">1</span>
		<span class="n">reward_dict</span><span class="p">[</span><span class="n">chosen_action</span><span class="p">][</span><span class="s">'sum_rewards'</span><span class="p">]</span><span class="o">+=</span><span class="n">reward</span>
	<span class="n">rewards</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">rewards</span><span class="p">)</span>
	<span class="n">sum_rewards</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">rewards</span><span class="p">,</span> <span class="n">axis</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
	<span class="n">regret</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">sum_rewards</span><span class="p">)</span> <span class="o">/</span> <span class="n">T</span> <span class="o">-</span> <span class="nb">sum</span><span class="p">([</span><span class="n">el</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">history</span><span class="p">])</span><span class="o">/</span> <span class="n">T</span>
	<span class="k">return</span> <span class="p">((</span><span class="nb">max</span><span class="p">(</span><span class="n">sum_rewards</span><span class="p">)</span> <span class="o">/</span> <span class="n">T</span><span class="p">),(</span><span class="nb">sum</span><span class="p">([</span><span class="n">el</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">el</span> <span class="ow">in</span> <span class="n">history</span><span class="p">])</span><span class="o">/</span> <span class="n">T</span><span class="p">),</span><span class="n">regret</span><span class="p">)</span>
</code></pre></div></div>
<p>Lets, run with mean rewards as \([0,0.3,1]\), \(T = 50000\) and corruption limit as \(1000\)
The results are:</p>

<table>
  <thead>
    <tr>
      <th>algorithm</th>
      <th>Expected reward of optimal arm</th>
      <th>Average reward in each round</th>
      <th>average Regret in each round</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Explore_then_commit</td>
      <td>0.98127</td>
      <td>0.81756</td>
      <td>0.16371</td>
    </tr>
    <tr>
      <td>EGreedy</td>
      <td>0.98259</td>
      <td>0.79073</td>
      <td>0.19187</td>
    </tr>
    <tr>
      <td>Successive_elimination</td>
      <td>1.00005</td>
      <td>0.29011</td>
      <td>0.70994</td>
    </tr>
    <tr>
      <td>UCB1</td>
      <td>1.00494</td>
      <td>0.2935</td>
      <td>0.71144</td>
    </tr>
    <tr>
      <td>EXP3</td>
      <td>0.98156</td>
      <td>0.90013</td>
      <td>0.08142</td>
    </tr>
    <tr>
      <td>MultiLayer_active_arm_elimination</td>
      <td>0.97867</td>
      <td>0.90995</td>
      <td>0.06872</td>
    </tr>
  </tbody>
</table>

<p> 
 
 </p>
<h3 id="expected-regret-vs-psuedo-regret">Expected Regret vs Psuedo Regret:</h3>
<p>Throughout this article, we used the algorithm objective to minimize pseudo-regret. Another similar objective could be to minimize expected regret.</p>

<p>Expected regret \(\mathbb E [R] = \mathbb E \big [\max_a\sum_tX_{a,t} - \sum_t X_{a_t,t}\big]\).</p>

<p>Whereas our psedo regret is \(\overline R = \max_a \mathbb E\big[ \sum_t X_{a,t}  - \sum_{t}X_{a_t,t}\big]\).</p>

<p>Since pseudo regret is the expected deficit from optimal action whereas expected regret is the expectation of regret with the action that is optimal.
The expected regret is a stronger notion and \(\overline R \leq \mathbb E [R]\).
Here is a simulation to highlight that Expected regret is \(\geq\) pseudo-regret.
it shows that for normal rewards with mean \(= [1 , 0.5, 0.99 , 0.9 , 0.2  , 0.1 , 0]\)</p>

\[E[\max_a \sum_t X_{a,t}] \geq \max_a\mathbb E[\sum_t X_{a,t}]\]

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">expected_vs_psuedo_regret</span><span class="p">():</span>
	<span class="n">T</span> <span class="o">=</span> <span class="mi">1000</span>
	<span class="n">mean_rewards</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span> <span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.99</span> <span class="p">,</span> <span class="mf">0.9</span> <span class="p">,</span> <span class="mf">0.2</span>  <span class="p">,</span> <span class="mf">0.1</span> <span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
	<span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span>
	<span class="n">alpha</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">normal</span><span class="p">(</span><span class="n">loc</span> <span class="o">=</span> <span class="n">mean_rewards</span><span class="p">,</span> <span class="n">scale</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">size</span> <span class="o">=</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span><span class="n">k</span><span class="p">))</span>
	<span class="n">alpha</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">alpha</span><span class="p">,</span> <span class="n">axis</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
	<span class="n">alpha</span> <span class="o">/=</span> <span class="n">T</span>
	<span class="n">expected_max_avg_value</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">alpha</span><span class="p">)</span>
	<span class="n">max_expected_value</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">mean_rewards</span><span class="p">)</span>
	<span class="k">return</span> <span class="n">expected_max_avg_value</span> <span class="o">-</span> <span class="n">max_expected_value</span>
</code></pre></div></div>
<p>Running this simulation 10000 times, average difference \(E[\max_a \sum_t X_{a,t}] - \max_a\mathbb E[\sum_t X_{a,t}]\) was: 0.013302.</p>

<p>This happens because with arms that are close to optimal, like with mean 0.99, instead of 1, there is a chance that its sum of rewards is greater than the sum of rewards by the actual optimal arm.</p>

<p>This difference vanishes as T increases, running the same simulation with \(T = 10000\), 10 times the previous, the average difference was: 0.0019969. about a tenth of the previous difference.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[The multi-armed bandit (MAB) is a classic problem in probability theory and statistics that models exploitation-exploration trade-off, leveraging choices that have proven effective in the past versus choosing new options that might provide better-unexplored trade-offs. Imagine a row of slot machines, each with a different and unknown distribution of paying out a reward. The goal is to select the machine(or ‘arm’) at each time instance such that it maximizes the total reward over time. This article will discuss simulations for some known algorithms in MAB in stochastically chosen, adversarially chosen, and stochastically chosen but strategically corrupted reward scenarios and run simulations for the algorithms discussed.]]></summary></entry><entry><title type="html">Monty Hall, A Misunderstood Problem</title><link href="https://ayushbatra.github.io/The_Monty_Hall_Problem/" rel="alternate" type="text/html" title="Monty Hall, A Misunderstood Problem" /><published>2023-01-02T00:00:00+00:00</published><updated>2023-01-02T00:00:00+00:00</updated><id>https://ayushbatra.github.io/monty-hall-problem</id><content type="html" xml:base="https://ayushbatra.github.io/The_Monty_Hall_Problem/"><![CDATA[<p>The Monty Hall Problem is a classic puzzle in probability theory that may seem straightforward at first but is surprisingly tricky and confusing. This article will delve into the problem by examining how the host’s choice of door affects the game, to better understand the problem.</p>

<h3 id="the-problem">The Problem</h3>

<p>You are on a game show with 3 doors labeled \(\{A, B, C\}\). Behind one door is a prize, and behind the other two doors are empty. Here’s how the game works:</p>

<ol>
  <li>You choose one of the doors.</li>
  <li>The host selects a different door.</li>
  <li>The host’s door is opened and it is revealed that that door does not hide the prize.</li>
  <li>You are offered to reconsider your option, you can select the other unopened door or you can stick with your current door.</li>
</ol>

<p>What should you do to maximize your chances of winning?</p>

<p>The above problem is a slightly perturbed version of the MHP, in the Monty Hall problem, you are given a crucial piece of information about step 2 i.e. how the host chooses his door. In MHP you are told that the host is aware of the price door and deliberately chooses the other door without the prize.</p>

<p>Now, consider a Not-Monty Hall problem, where the host is also unaware of the location of the prize and randomly chooses one of the other doors. The remaining steps remain the same.</p>

<p>Let’s run a simulation, for the Monty Hall and the Not-Monty Hall problem to see the probability of winning with changing the door choice.</p>

<p>For the not-monty hall problem:</p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">import</span> <span class="nn">random</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span></code></pre></figure>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">not_monty_hall_sim</span><span class="p">():</span>
	<span class="n">doors</span> <span class="o">=</span> <span class="p">[</span><span class="s">'a'</span><span class="p">,</span><span class="s">'b'</span><span class="p">,</span><span class="s">'c'</span><span class="p">]</span>
	<span class="c1">#Let the prize be randomly chosen
</span>	<span class="n">prize</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span> <span class="n">doors</span> <span class="p">)</span>
	<span class="c1">#Your randomly chosen initial guess
</span>	<span class="n">contestant_choice</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="n">doors</span><span class="p">)</span>
	<span class="c1">#Host randomly choosing one of the remaining doors.
</span>	<span class="n">host_choice</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span><span class="n">x</span><span class="o">!=</span><span class="n">contestant_choice</span><span class="p">,</span> <span class="n">doors</span><span class="p">)))</span>
	<span class="c1">#This is to satisfy the conditional information given to us.
</span>	<span class="c1"># since we know that when the host choice was revealed it was not the prize doors
</span>	<span class="k">if</span> <span class="p">(</span>  <span class="n">host_choice</span> <span class="o">==</span> <span class="n">prize</span> <span class="p">):</span>
		<span class="c1"># Abort the simulation
</span>		<span class="k">return</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span>
	<span class="c1">#Returing the output, the first index is if the initial guess was correct, and the second index is if this is a valid iteration. 
</span>	<span class="k">if</span> 	<span class="n">contestant_choice</span> <span class="o">!=</span> <span class="n">prize</span><span class="p">:</span>
		<span class="k">return</span> <span class="p">(</span><span class="mi">1</span> <span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
	<span class="k">else</span><span class="p">:</span>
		<span class="k">return</span> <span class="p">(</span><span class="mi">0</span> <span class="p">,</span> <span class="mi">1</span><span class="p">)</span>	</code></pre></figure>

<p>For the standard Monty Hall problem</p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">monty_hall_sim</span><span class="p">():</span>
	<span class="n">doors</span> <span class="o">=</span> <span class="p">[</span><span class="s">'a'</span><span class="p">,</span><span class="s">'b'</span><span class="p">,</span><span class="s">'c'</span><span class="p">]</span>
	<span class="c1">#Let the prize be randomly chosen
</span>	<span class="n">prize</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span> <span class="n">doors</span> <span class="p">)</span>
	<span class="c1">#Your randomly chosen initial guess
</span>	<span class="n">contestant_choice</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="n">doors</span><span class="p">)</span>
	<span class="c1">#Host randomly choosing one of the remaining doors, which is not the prize door
</span> 	<span class="c1">#Since, the host is aware of the prize door and is deliberately choosing one that is not the prize door.
</span>	<span class="n">host_choice</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">choice</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span><span class="n">x</span><span class="o">!=</span><span class="n">contestant_choice</span> <span class="ow">and</span> <span class="n">x</span><span class="o">!=</span> <span class="n">prize</span><span class="p">,</span> <span class="n">doors</span><span class="p">)))</span>
	<span class="c1">#This is to satisfy the conditional statement given to us.
</span> 	<span class="c1"># since we know that when the host choice was revealed it was not the prize doors
</span>	<span class="k">if</span> <span class="p">(</span><span class="n">host_choice</span> <span class="o">==</span> <span class="n">prize</span><span class="p">):</span>
		<span class="c1"># Abort the simulation
</span>		<span class="k">return</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span>
	<span class="c1">#Returing the output, the first index is if the initial guess was correct, and the second index is if this is a valid iteration. 
</span>	<span class="k">if</span> <span class="n">contestant_choice</span> <span class="o">!=</span> <span class="n">prize</span><span class="p">:</span>
		<span class="k">return</span> <span class="p">[</span><span class="mi">1</span> <span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
	<span class="k">else</span><span class="p">:</span>
		<span class="k">return</span> <span class="p">[</span><span class="mi">0</span> <span class="p">,</span> <span class="mi">1</span><span class="p">]</span>	</code></pre></figure>

<p>After running the above simulation 10,000 times, the probability of winning with changing the doors is:</p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">ans</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">])</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10000</span><span class="p">):</span>
	<span class="n">ans</span> <span class="o">+=</span> <span class="n">not_monty_hall_sim</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="n">ans</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">/</span><span class="n">ans</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></code></pre></figure>

<p>For Monty Hall Problem : 0.6653 \(\approx \frac{2}{3}\)</p>

<p>For Not-Monty Hall Problem: 0.49126  \(\approx \frac{1}{2}\)</p>

<p>Let’s discuss the above result:</p>

<p>When the contestant observes that the host’s door does not contain the prize, how does the random variable(of prize door) update with this new information?
Let’s say the contestant had chosen door A.</p>

<p>This new probability distribution can be calculated by the concept of Conditional Random Variable.</p>

<p>For the not-monty hall problem,</p>

\[=P( A \text{ is prize | One of randomly chosen B/C door is empty} )\]

\[= \frac{P( A \text{ is prize} \cap\text{ One of randomly chosen B/C door is empty}  )}{P(\text{One of randomly chosen B/C door is empty})}\]

\[= \frac{P( A\text{ is prize})}{P(\text{One of randomly chosen B/C door is empty})}\]

\[= \frac{1/3}{2/3} = 1/2\]

<p>Thus, in this case, it does not matter if you choose to switch or not since either way your winning odds are at half.</p>

<p>In the actual Monty Hall problem, the host is aware of the prize and deliberately chooses a door that does not contain the prize. In this case,</p>

\[= P( A \text{ is prize | there exists a door not A, that does not have the prize} )\]

\[= \frac{P( A\text{ is prize }\cap\text{ there exists a door not A, that does not have the prize } )}{P(\text{there exists a door not }A\text{, that does not have the prize})}\]

\[= \frac{P( A\text{ is prize})}{P(\text{there exists a door not A, that does not have the prize})}\]

\[= \frac{1/3}{1} = 1/3\]

<p>In this case, the probability of your previously selected door containing the reward is \(1/3\), and hence, the contestant’s chances of winning are higher if they choose to switch.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[The Monty Hall Problem is a classic puzzle in probability theory that may seem straightforward at first but is surprisingly tricky and confusing. This article will delve into the problem by examining how the host’s choice of door affects the game, to better understand the problem.]]></summary></entry><entry><title type="html">Insurance? A Dummy example</title><link href="https://ayushbatra.github.io/Insurance/" rel="alternate" type="text/html" title="Insurance? A Dummy example" /><published>2023-01-01T00:00:00+00:00</published><updated>2023-01-01T00:00:00+00:00</updated><id>https://ayushbatra.github.io/insurance</id><content type="html" xml:base="https://ayushbatra.github.io/Insurance/"><![CDATA[<p>Let’s try to understand what insurance means from the hypothetical example of Alex.<br />
Alex one day wakes to find a magic coin with the following instructions:</p>

<ul>
  <li>You are only allowed to flip the coin once and it will vanish afterward.</li>
  <li>The coin has an equal probability of landing either ‘Heads’ or ‘Tails’.</li>
  <li>If the coin lands on ‘Heads’ you will be given 10 million.</li>
  <li>If the coin lands on ‘Tails’ you will be given nothing.</li>
</ul>

<p><img src="/assets/story.png" alt="Rules" title="Rules" /></p>

<p>Now Alex is very happy at the prospect of earning 10 million but is not ready to accept that this deal is not guaranteed and there is a 0.5 probability that he may not get anything. So instead he goes to Alpha Insurance company and offers them the following deal:
<br />
He will flip the magic coin and if it lands on heads he will share 6 million from his 10 million winnings but if the coin lands tails, the insurance company will have to pay him 4 million.
<br />
The company accepts the deal thinking this is a net positive for their profits and Alex walks out with 4 million irrespective of what side the coin lands.
<br /><br /></p>

<p>This hypothetical example illustrates how insurance works in a simplified and ideal manner.</p>

<h2 id="who-gets-what">Who gets what?</h2>

<p>Let’s try to understand how Alpha Insurance or Alex would benefit from a deal like this and why would they rationally choose to participate.</p>

<h3 id="alpha-insurance">Alpha Insurance</h3>
<p>Alpha Insurance would participate in this deal because this is an expected positive money for them.
A simple calculation would suggest</p>

\[E[money] = \frac{1}{2}\cdot 6 Million + \frac{1}{2}\cdot-1 * 4 Million = 1 Million\]

<p>that on average they are profiting by 1 million, and since they are in the market to maximize their profits they took this deal.</p>

<h3 id="alex">Alex</h3>
<p>Since this deal is an expected positive money for Alpha Insurance, and the net amount of money is constant, this deal is an expected negative money for Alex.</p>

\[E[money] = \frac{1}{2}\cdot -1 * 6 Million + \frac{1}{2} \cdot 4 Million = -1 Million\]

<p>Why would Alex participate in this deal if he knows that he is losing money? It is because he is not trying to maximize the expected amount of money, he is trying to maximize another attribute - let’s call it utility - that expresses the value this money brings to his life. The value that this money brings, becomes less when he has more money. The value of the \(1^{st}\) million in his life is much more, than 1 million when he has already gotten 3 million.</p>

<p><img src="/assets/Law_of_Dim_Mar_U.png" alt="Law of Diminishing Marginal Utility" width="700" /></p>

<p>This phenomenon is understood by the “Law of Diminishing Marginal Utility” which implies that the value of something gets lower if you have a large amount of this thing. In this case, Alex would prefer having more money as depicted by the increasing function of utility with money but this value increases less and less when he has larger and larger amounts of money.<br /> Thus, the value that he expects to gain in his life by getting 4 million is more than the value he expects to lose in his life by losing 6 million. Thus he has a positive expected value in this deal and would choose to participate in this stochastic transaction with Alpha Insurance.</p>

<p><br />
<br /></p>

<p>In other words, an insurance service could be considered a courier service to send money from your more prosperous futures to your less prosperous futures.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Let’s try to understand what insurance means from the hypothetical example of Alex. Alex one day wakes to find a magic coin with the following instructions: You are only allowed to flip the coin once and it will vanish afterward. The coin has an equal probability of landing either ‘Heads’ or ‘Tails’. If the coin lands on ‘Heads’ you will be given 10 million. If the coin lands on ‘Tails’ you will be given nothing.]]></summary></entry></feed>