Skip to content

Commit

Permalink
Release version 0.1.0
Browse files Browse the repository at this point in the history
### Changes
* Add refactored smab classes
* Add Poetry and Pre-Commit setup
* Refactor repository settings
* Add pyproject.toml for Poetry
* Add tox.ini
* Add .git* files
* Remove outdated setup files
* Update pre-commit hooks in .pre-commit-config.yaml
* CostControlBandit: Take action with the highest probability when multiple actions have the same cost
* Fix tests
* Fix test_select_action_logic_corner_cases
* Add Multi-Objective strategy merged with Cost-Control
* Add new strategy Multi-Objective with Cost-Control
* Add a new Beta model to support the MO-CC strategy
* Create SmabBernoulli with Strategy MO-CC
* Modify tests accordingly
* Add Bayesian Logistic Regression model
* Add class StudentT
* Add class BaseBayesianLogisticRegression
* Add class BayesianLogisticRegression
* Add unit tests accordingly
* Refactor BaseCmab and add CmabBernoulli
* Add BaseCmabBernoulli
* Add CmabBernoulli
* Add unit tests in test_cmab.py
* Add a new test in test_smab.py to reach 100% line coverage
* Add Sonar-related config
* Fix GitHub workflow
* Fix style with Pre-Commit
* Add deadline time in cmab tests
* Update continuous_integration.yml
* Add CI to develop branch

---------

Co-authored-by: Stefano Piazza <[email protected]>
  • Loading branch information
dariodandrea and spiaz authored Oct 16, 2023
1 parent a18a1c4 commit fd1aece
Show file tree
Hide file tree
Showing 45 changed files with 5,876 additions and 2,119 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.ipynb merge=nbdev-merge
11 changes: 11 additions & 0 deletions .gitconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Generated by nbdev_install_hooks
#
# If you need to disable this instrumentation do:
# git config --local --unset include.path
#
# To restore:
# git config --local include.path ../.gitconfig
#
[merge "nbdev-merge"]
name = resolve conflicts with nbdev_fix
driver = nbdev_merge %O %A %B %P
27 changes: 16 additions & 11 deletions .github/workflows/continuous_integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ name: CI

on:
push:
branches: [ master ]
branches:
- master
- develop # Add the develop branch here
pull_request:
branches: [ master ]
branches:
- master
- develop # Add the develop branch here

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
Expand All @@ -25,20 +29,21 @@ jobs:
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
- name: Install Poetry
run: |
conda install -c conda-forge pymc3
python -m pip install --upgrade pip
python -m pip install .[develop]
curl -sSL https://install.python-poetry.org | python3 -
export PATH="$HOME/.poetry/bin:$PATH"
- name: Install project dependencies with Poetry
run: |
poetry install
- name: Style check
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# run pre-commit hooks
pre-commit run --all-files
poetry run pre-commit run --all-files
- name: Run tests
run: |
cd tests
pytest -vv -k 'not time and not update_parallel'
poetry run pytest -vv -k 'not time and not update_parallel'
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,15 @@ MANIFEST

# Build and docs folder/files
*.csv

# VSCode
.vscode

# hypothesis
.hypothesis

# Jupyter notebooks
*checkpoint.ipynb

# poetry
poetry.lock
10 changes: 0 additions & 10 deletions .isort.cfg

This file was deleted.

61 changes: 35 additions & 26 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
exclude: '^docs/conf.py'

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.3
hooks:
- id: trailing-whitespace
- id: check-added-large-files
- id: check-ast
- id: check-json
- id: check-merge-conflict
- id: check-xml
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
- id: requirements-txt-fixer
- id: mixed-line-ending
args: ['--fix=no']
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: check-added-large-files
- id: check-added-large-files
- id: check-ast
- id: check-json
- id: check-merge-conflict
- id: check-xml
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
- id: end-of-file-fixer
- id: mixed-line-ending

- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
additional_dependencies: [Flake8-pyproject]

- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort

- repo: https://gitlab.com/pycqa/flake8
rev: 3.7.9
hooks:
- id: flake8
args: ['--append-config=setup.cfg']
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
- id: black-jupyter

- repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.4
hooks:
- id: isort
- repo: https://github.com/fastai/nbdev
rev: 2.3.11
hooks:
- id: nbdev_clean
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ Authors

* Dario d'Andrea, [email protected]
* Jerome Carayol, [email protected]
* Stefano Piazza, [email protected]
* Raphael Steinmann, [email protected]
* Armand Valsesia, [email protected]
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Playtika Ltd.
Copyright (c) 2023 Playtika Ltd.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
26 changes: 13 additions & 13 deletions docs/src/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
import os
import sys

sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath(".."))


# -- Project information -----------------------------------------------------

project = 'PyBandits'
copyright = 'MIT License'
author = ''
project = "PyBandits"
copyright = "MIT License"
author = ""

# The full version, including alpha/beta/rc tags
release = '1.0'
release = "1.0"


# -- General configuration ---------------------------------------------------
Expand All @@ -32,15 +32,15 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.todo',
'sphinx.ext.mathjax',
'nbsphinx',
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"sphinx.ext.todo",
"sphinx.ext.mathjax",
"nbsphinx",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
Expand All @@ -58,9 +58,9 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]

# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['pybandits.']
modindex_common_prefix = ["pybandits."]

nbsphinx_allow_errors = True
10 changes: 5 additions & 5 deletions docs/src/tutorials/cmab.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"n_samples = 1000\n",
"n_features = 5\n",
"X = 2 * np.random.random_sample((n_samples, n_features)) - 1 # random float in the interval (-1, 1)\n",
"print('X: context matrix of shape (n_samples, n_features)')\n",
"print(\"X: context matrix of shape (n_samples, n_features)\")\n",
"print(X[:10])"
]
},
Expand All @@ -97,7 +97,7 @@
"outputs": [],
"source": [
"# define actions\n",
"actions_ids= ['action A', 'action B', 'action C']"
"actions_ids = [\"action A\", \"action B\", \"action C\"]"
]
},
{
Expand Down Expand Up @@ -140,8 +140,8 @@
],
"source": [
"# predict action\n",
"pred_actions, _ = cmab.predict(X) \n",
"print('Recommended action: {}'.format(pred_actions[:10]))"
"pred_actions, _ = cmab.predict(X)\n",
"print(\"Recommended action: {}\".format(pred_actions[:10]))"
]
},
{
Expand All @@ -167,7 +167,7 @@
"source": [
"# simulate reward from environment\n",
"simulated_rewards = np.random.randint(2, size=n_samples)\n",
"print('Simulated rewards: {}'.format(simulated_rewards[:10]))"
"print(\"Simulated rewards: {}\".format(simulated_rewards[:10]))"
]
},
{
Expand Down
27 changes: 11 additions & 16 deletions docs/src/tutorials/simulation_cmab.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"n_groups = 3\n",
"n_updates = 5\n",
"n_jobs = 1\n",
"actions_ids = ['action A', 'action B', 'action C']\n",
"actions_ids = [\"action A\", \"action B\", \"action C\"]\n",
"n_features = 5\n",
"verbose = True"
]
Expand All @@ -66,11 +66,9 @@
"outputs": [],
"source": [
"# init context matrix and groups\n",
"X, group = make_classification(n_samples=batch_size*n_updates,\n",
" n_features=n_features, \n",
" n_informative=n_features,\n",
" n_redundant=0,\n",
" n_classes=n_groups)"
"X, group = make_classification(\n",
" n_samples=batch_size * n_updates, n_features=n_features, n_informative=n_features, n_redundant=0, n_classes=n_groups\n",
")"
]
},
{
Expand Down Expand Up @@ -155,10 +153,10 @@
],
"source": [
"# init probability of rewards from the environment\n",
"prob_rewards = pd.DataFrame([[0.05, 0.80, 0.05],\n",
" [0.80, 0.05, 0.05],\n",
" [0.80, 0.05, 0.80]], columns=actions_ids, index=range(n_groups))\n",
"print('Probability of positive reward for each group/action:') \n",
"prob_rewards = pd.DataFrame(\n",
" [[0.05, 0.80, 0.05], [0.80, 0.05, 0.05], [0.80, 0.05, 0.80]], columns=actions_ids, index=range(n_groups)\n",
")\n",
"print(\"Probability of positive reward for each group/action:\")\n",
"prob_rewards"
]
},
Expand Down Expand Up @@ -203,12 +201,9 @@
],
"source": [
"# init simulation\n",
"sim = SimulationCmab(cmab=cmab, X=X, \n",
" group=group, \n",
" batch_size=batch_size, \n",
" n_updates=n_updates,\n",
" prob_rewards=prob_rewards, \n",
" verbose=verbose)"
"sim = SimulationCmab(\n",
" cmab=cmab, X=X, group=group, batch_size=batch_size, n_updates=n_updates, prob_rewards=prob_rewards, verbose=verbose\n",
")"
]
},
{
Expand Down
14 changes: 8 additions & 6 deletions docs/src/tutorials/simulation_smab.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"outputs": [],
"source": [
"# define actions\n",
"action_ids = ['Action A', 'Action B', 'Action C']"
"action_ids = [\"Action A\", \"Action B\", \"Action C\"]"
]
},
{
Expand Down Expand Up @@ -70,11 +70,13 @@
"outputs": [],
"source": [
"# init simulation\n",
"sim = SimulationSmab(smab=smab,\n",
" n_updates=20,\n",
" batch_size=2000,\n",
" probs_reward={'Action A': 0.6, 'Action B': 0.5, 'Action C': 0.8},\n",
" verbose=True)"
"sim = SimulationSmab(\n",
" smab=smab,\n",
" n_updates=20,\n",
" batch_size=2000,\n",
" probs_reward={\"Action A\": 0.6, \"Action B\": 0.5, \"Action C\": 0.8},\n",
" verbose=True,\n",
")"
]
},
{
Expand Down
18 changes: 6 additions & 12 deletions docs/src/tutorials/smab.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"outputs": [],
"source": [
"# define actions\n",
"action_ids = ['Action A', 'Action B', 'Action C']"
"action_ids = [\"Action A\", \"Action B\", \"Action C\"]"
]
},
{
Expand All @@ -67,13 +67,9 @@
"outputs": [],
"source": [
"# define beta priors parameters\n",
"success_priors = {'Action A': 1,\n",
" 'Action B': 1,\n",
" 'Action C': 1}\n",
"success_priors = {\"Action A\": 1, \"Action B\": 1, \"Action C\": 1}\n",
"\n",
"failure_priors = {'Action A': 1,\n",
" 'Action B': 1,\n",
" 'Action C': 1}"
"failure_priors = {\"Action A\": 1, \"Action B\": 1, \"Action C\": 1}"
]
},
{
Expand All @@ -90,9 +86,7 @@
"outputs": [],
"source": [
"# init stochastic Multi-Armed Bandit model\n",
"smab = Smab(action_ids=action_ids, \n",
" success_priors=success_priors,\n",
" failure_priors=failure_priors)"
"smab = Smab(action_ids=action_ids, success_priors=success_priors, failure_priors=failure_priors)"
]
},
{
Expand All @@ -118,7 +112,7 @@
"source": [
"# predict actions\n",
"pred_actions, _ = smab.predict(n_samples=1000)\n",
"print('Recommended action: {}'.format(pred_actions[:10]))"
"print(\"Recommended action: {}\".format(pred_actions[:10]))"
]
},
{
Expand Down Expand Up @@ -149,7 +143,7 @@
"for a in action_ids:\n",
" n_successes[a] = random.randint(0, pred_actions.count(a))\n",
" n_failures[a] = pred_actions.count(a) - n_successes[a]\n",
" print('{}: n_successes={}, n_failures={}'.format(a, n_successes[a], n_failures[a]))"
" print(\"{}: n_successes={}, n_failures={}\".format(a, n_successes[a], n_failures[a]))"
]
},
{
Expand Down
Loading

0 comments on commit fd1aece

Please sign in to comment.