{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# default_exp models.bandits"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bandits\n",
    "> Bandit models including beta bandit, and epsilon bandit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "import math\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class BetaBandit:\n",
    "    \"\"\"\n",
    "    Bandit class that is used in Thompson sampling.\n",
    "    Attributes:\n",
    "        alpha: Alpha parameter of the beta distribution (number of positive examples).\n",
    "        beta: Beta parameter of the beta distribution (number of negative examples).\n",
    "    \n",
    "    Methods:\n",
    "        update: Updates alpha and beta priors of the BetaBandit.\n",
    "        sample: Samples the BetaBandit's distribution n times.\n",
    "    \"\"\"\n",
    "    def __init__(self, alpha: int=0, beta: int=0, alpha_prior: float=1., beta_prior: float=1.):\n",
    "        \"\"\"\n",
    "        Initializes new BetaBandit with passed parameters.\n",
    "        Args:\n",
    "            alpha: Alpha parameter of the beta distribution (number of positive examples).\n",
    "            beta: Beta parameter of the beta distribution (number of negative examples).\n",
    "            alpha_prior: The prior for alpha parameter.\n",
    "            beta_prior: The prior for beta parameter.\n",
    "        \"\"\"\n",
    "        self.alpha = alpha + alpha_prior\n",
    "        self.beta = beta + beta_prior\n",
    "    \n",
    "    def update(self, positive_examples: int=0, negative_examples: int=0):\n",
    "        \"\"\"\n",
    "        Updates alpha and beta priors of the BetaBandit.\n",
    "        Args:\n",
    "            positive_examples: Number of positive examples.\n",
    "            negative_examples: Number of negative examples.\n",
    "        \"\"\"\n",
    "        self.alpha += positive_examples\n",
    "        self.beta += negative_examples\n",
    "    \n",
    "    def sample(self, n: int) -> np.ndarray:\n",
    "        \"\"\"\n",
    "        Samples the BetaBandit's distribution n times.\n",
    "        Args:\n",
    "            n: Sample size.\n",
    "        Returns:\n",
    "            An array filled with n examples sampled\n",
    "            from the BetaBandit's distribution.\n",
    "        \"\"\"\n",
    "        return np.random.beta(self.alpha, self.beta, n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class EpsilonBandit:\n",
    "    \"\"\"\n",
    "    Bandit class that is used in Epsilon-greedy multi-armed bandits.\n",
    "    Attributes:\n",
    "        positive_examples: Number of positive examples.\n",
    "    \n",
    "    Methods:\n",
    "        update: Updates the number of positive examples of the EpsilonBandit.\n",
    "        get_value: Gets the number of positive examples of the EpsilonBandit.\n",
    "    \"\"\"\n",
    "    def __init__(self, positive_examples: int=0):\n",
    "        \"\"\"\n",
    "        Initializes a new EpsilonBandit and sets its positive examples.\n",
    "        Args:\n",
    "            positive_examples: Number of positive examples.\n",
    "        \"\"\"\n",
    "        self.positive_examples = positive_examples\n",
    "    \n",
    "    def update(self, positive_examples: int=0):\n",
    "        \"\"\"\n",
    "        Updates the number of positive examples of the EpsilonBandit.\n",
    "        Args:\n",
    "            positive_examples: Number of positive examples.\n",
    "        \"\"\"\n",
    "        self.positive_examples += positive_examples\n",
    "    \n",
    "    def get_value(self) -> int:\n",
    "        \"\"\"\n",
    "        Gets the number of positive examples of the EpsilonBandit.\n",
    "        Returns:\n",
    "            The number of positive examples of the EpsilonBandit.\n",
    "        \"\"\"\n",
    "        return self.positive_examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Author: Sparsh A.\n",
      "\n",
      "Last updated: 2021-12-18 05:12:47\n",
      "\n",
      "Compiler    : GCC 7.5.0\n",
      "OS          : Linux\n",
      "Release     : 5.4.104+\n",
      "Machine     : x86_64\n",
      "Processor   : x86_64\n",
      "CPU cores   : 2\n",
      "Architecture: 64bit\n",
      "\n",
      "google : 2.0.3\n",
      "numpy  : 1.19.5\n",
      "IPython: 5.5.0\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#hide\n",
    "!pip install -q watermark\n",
    "%reload_ext watermark\n",
    "%watermark -a \"Sparsh A.\" -m -iv -u -t -d"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
