statrl 1.2609__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- statrl-1.2609/LICENSE +21 -0
- statrl-1.2609/PKG-INFO +129 -0
- statrl-1.2609/README.md +104 -0
- statrl-1.2609/pyproject.toml +73 -0
- statrl-1.2609/setup.cfg +4 -0
- statrl-1.2609/src/statrl/__init__.py +0 -0
- statrl-1.2609/src/statrl/experiments/__init__.py +0 -0
- statrl-1.2609/src/statrl/experiments/analyzeruns.py +95 -0
- statrl-1.2609/src/statrl/experiments/massiveruns.py +124 -0
- statrl-1.2609/src/statrl/experiments/onerun.py +111 -0
- statrl-1.2609/src/statrl/experiments/parallelruns.py +60 -0
- statrl-1.2609/src/statrl/experiments/plotruns.py +144 -0
- statrl-1.2609/src/statrl/experiments/utils.py +140 -0
- statrl-1.2609/src/statrl/settings/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/lipschitz/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/lipschitz/agent.py +53 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/lipschitz/agents/ALF.py +202 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/lipschitz/agents/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/lipschitz/environment.py +117 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/lipschitz/envs/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/lipschitz/interaction.py +62 -0
- statrl-1.2609/src/statrl/settings/bandits/adversarial/lipschitz/wrappers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/_test.py +74 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/agent.py +76 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/agents/IMED.py +156 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/agents/NPTS.py +136 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/agents/TS.py +119 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/agents/UCB.py +112 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/agents/_Oracle.py +66 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/agents/_Random.py +54 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/agents/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/environment.py +161 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/envs/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/envs/distributions.py +126 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/envs/parametric.py +145 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/interaction.py +110 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/renderers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/renderers/textrenderer.py +69 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/anytime/wrappers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/_test.py +60 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/agent.py +110 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/agents/BABA.py +687 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/agents/BCB.py +255 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/agents/BIMED.py +235 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/agents/_Oracle.py +89 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/agents/_Random.py +80 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/agents/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/agents/baba_schedule.py +246 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/environment.py +121 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/envs/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/envs/parametric.py +206 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/envs/renderers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/batch/interaction.py +102 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/_test.py +27 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/agent.py +83 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/agents/_Oracle.py +62 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/agents/_Random.py +39 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/agents/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/environment.py +237 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/envs/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/envs/kernels.py +175 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/interaction.py +105 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/renderers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/renderers/plotrenderer.py +256 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/kernel/renderers/textrenderer.py +100 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/knownhorizon/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/knownhorizon/agent.py +71 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/knownhorizon/agents/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/knownhorizon/environment.py +13 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/knownhorizon/envs/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/knownhorizon/interaction.py +141 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/knownhorizon/wrappers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/bandits/stochastic/knownhorizon/wrappers/wrapper_anytime_knownhorizon.py +143 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/_test.py +68 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/agent.py +82 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/agents/Human.py +87 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/agents/IMED_RL.py +411 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/agents/PSRL.py +356 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/agents/PSRL_original.py +306 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/agents/_Oracle.py +260 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/agents/_Random.py +56 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/agents/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/environment.py +250 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/envs/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/envs/randomMDP.py +174 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/envs/riverswim.py +207 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/interaction.py +101 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/renderers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/renderers/htmlRenderer.py +1744 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/renderers/textRenderer.py +89 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/discrete_nostructure/wrappers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/_test.py +62 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/agent.py +3 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/agents/_Oracle.py +168 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/agents/_Random.py +1 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/agents/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/environment.py +4 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/envs/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/envs/gridworlds.py +905 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/interaction.py +102 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/renderers/__init__.py +0 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/renderers/htmlrenderer.py +114 -0
- statrl-1.2609/src/statrl/settings/markovdecisionprocess/gridworld/renderers/textRenderer.py +184 -0
- statrl-1.2609/src/statrl/settings/utils.py +366 -0
- statrl-1.2609/src/statrl/settings/validator.py +307 -0
- statrl-1.2609/src/statrl.egg-info/PKG-INFO +129 -0
- statrl-1.2609/src/statrl.egg-info/SOURCES.txt +121 -0
- statrl-1.2609/src/statrl.egg-info/dependency_links.txt +1 -0
- statrl-1.2609/src/statrl.egg-info/requires.txt +13 -0
- statrl-1.2609/src/statrl.egg-info/top_level.txt +1 -0
- statrl-1.2609/tests/test_batch.py +18 -0
- statrl-1.2609/tests/test_environment.py +20 -0
- statrl-1.2609/tests/test_experiments.py +93 -0
- statrl-1.2609/tests/test_utils.py +26 -0
statrl-1.2609/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 statrl contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
statrl-1.2609/PKG-INFO
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: statrl
|
|
3
|
+
Version: 1.2609
|
|
4
|
+
Summary: The Statistical Reinforcement Learning Toolkit Library
|
|
5
|
+
Author-email: Odalric-Ambrym Maillard <odalricambrym.maillard@inria.fr>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/StatisticalRL/statrl
|
|
8
|
+
Project-URL: Repository, https://github.com/StatisticalRL/statrl
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: gymnasium>=1.0
|
|
14
|
+
Requires-Dist: numpy>=2.5
|
|
15
|
+
Requires-Dist: joblib>=1.5
|
|
16
|
+
Requires-Dist: matplotlib>=3.9
|
|
17
|
+
Requires-Dist: scipy>=1.17
|
|
18
|
+
Requires-Dist: pyyaml>=6.0
|
|
19
|
+
Provides-Extra: test
|
|
20
|
+
Requires-Dist: pytest; extra == "test"
|
|
21
|
+
Provides-Extra: lint
|
|
22
|
+
Requires-Dist: ruff; extra == "lint"
|
|
23
|
+
Requires-Dist: mypy; extra == "lint"
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# statrl
|
|
27
|
+
|
|
28
|
+
[](https://github.com/StatisticalRL/statrl/actions/workflows/tests.yml)
|
|
29
|
+
[](https://github.com/StatisticalRL/statrl/actions/workflows/lint.yml)
|
|
30
|
+
[](https://github.com/StatisticalRL/statrl/actions/workflows/docs.yml)
|
|
31
|
+
[](pyproject.toml)
|
|
32
|
+
[](LICENSE)
|
|
33
|
+
|
|
34
|
+
The Statistical Reinforcement Learning Toolkit is a research library organised as a
|
|
35
|
+
taxonomy of *settings*, each with a matching environment, agent, and interaction loop.
|
|
36
|
+
|
|
37
|
+
📖 **[Documentation](https://statisticalrl.github.io/statrl/)**
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
Requires Python 3.9+. Not yet on PyPI (install from source):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/StatisticalRL/statrl.git
|
|
45
|
+
cd statrl
|
|
46
|
+
pip install -e . # editable install for development
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Quickstart
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from statrl.settings.bandits.stochastic.anytime.envs.parametric import BernoulliBandit
|
|
53
|
+
from statrl.settings.bandits.stochastic.anytime.agents.IMED import IMED
|
|
54
|
+
from statrl.settings.bandits.stochastic.anytime.agents._Oracle import Oracle
|
|
55
|
+
from statrl.settings.bandits.stochastic.anytime.interaction import BanditInteraction
|
|
56
|
+
from statrl.settings.utils import klBern
|
|
57
|
+
|
|
58
|
+
env = BernoulliBandit([0.2, 0.9, 0.5])
|
|
59
|
+
interaction = BanditInteraction()
|
|
60
|
+
|
|
61
|
+
scores = interaction.run(env, IMED(env.number_arms, klBern), horizon=2000)
|
|
62
|
+
oracle_scores = interaction.run(env, Oracle(env), horizon=2000)
|
|
63
|
+
|
|
64
|
+
print(f"regret after 2000 rounds: {oracle_scores[-1] - scores[-1]:.1f}")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## The protocol
|
|
68
|
+
|
|
69
|
+
Every setting shares the same protocol:
|
|
70
|
+
|
|
71
|
+
| Component | Responsibility |
|
|
72
|
+
| ----------- | ------------------------------------------------------------------------------------ |
|
|
73
|
+
| Environment | Holds the reward distributions; `step(arm)` samples a reward. |
|
|
74
|
+
| Agent | `reset()` starts a run; `select_arm()` chooses an arm; `update(arm, reward)` learns. |
|
|
75
|
+
| Interaction | `run(env, learner, horizon)` runs the loop and returns cumulative expected scores. |
|
|
76
|
+
|
|
77
|
+
## Implemented settings
|
|
78
|
+
|
|
79
|
+
Under `statrl.settings`:
|
|
80
|
+
|
|
81
|
+
BANDITS:
|
|
82
|
+
- **`stochastic.anytime`**
|
|
83
|
+
- **`stochastic.knownhorizon`** : horizon-aware wrapper over the anytime setting.
|
|
84
|
+
- **`stochastic.batch`** : when considering batch schedule.
|
|
85
|
+
- **`stochastic.kernel`** : RKHS structure on arms.
|
|
86
|
+
- **`adversarial.lipschitz`** : an adversarial Lipschitz forecaster.
|
|
87
|
+
|
|
88
|
+
MARKOV DECISION PROCESSES:
|
|
89
|
+
- **`discrete_nostructure`**: Abstract discrete MDPs.
|
|
90
|
+
- **`gridworld`**: Gridworld MDPs.
|
|
91
|
+
|
|
92
|
+
## Running experiments
|
|
93
|
+
|
|
94
|
+
`statrl.experiments` benchmarks agents: many replicates in parallel, regret against an
|
|
95
|
+
oracle, and plots.
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from statrl.experiments.massiveruns import runLargeMulticoreExperiment
|
|
99
|
+
|
|
100
|
+
runLargeMulticoreExperiment(
|
|
101
|
+
env, agents, oracle, interact,
|
|
102
|
+
timeHorizon=1000, nbReplicates=100, root_folder="results/",
|
|
103
|
+
)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Results (per-replicate dumps, a logfile, regret plots) are written under `root_folder`.
|
|
107
|
+
See [`examples/`](examples/) for complete runnable scripts.
|
|
108
|
+
|
|
109
|
+
## Development
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pip install -e ".[test,lint]"
|
|
113
|
+
pytest # tests
|
|
114
|
+
pytest --doctest-modules src/statrl \
|
|
115
|
+
--ignore-glob='*_test.py' # docstring examples
|
|
116
|
+
ruff check src tests # lint
|
|
117
|
+
mypy # type-check
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Documentation
|
|
121
|
+
|
|
122
|
+
Full docs (quickstart, user guide, API reference) live under `docs/`:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pip install -r docs/requirements.txt
|
|
126
|
+
sphinx-build -b html -W --keep-going docs/source docs/_build/html
|
|
127
|
+
sphinx-build -b doctest docs/source docs/_build/doctest
|
|
128
|
+
xdg-open docs/_build/html/index.html
|
|
129
|
+
```
|
statrl-1.2609/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# statrl
|
|
2
|
+
|
|
3
|
+
[](https://github.com/StatisticalRL/statrl/actions/workflows/tests.yml)
|
|
4
|
+
[](https://github.com/StatisticalRL/statrl/actions/workflows/lint.yml)
|
|
5
|
+
[](https://github.com/StatisticalRL/statrl/actions/workflows/docs.yml)
|
|
6
|
+
[](pyproject.toml)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
The Statistical Reinforcement Learning Toolkit is a research library organised as a
|
|
10
|
+
taxonomy of *settings*, each with a matching environment, agent, and interaction loop.
|
|
11
|
+
|
|
12
|
+
📖 **[Documentation](https://statisticalrl.github.io/statrl/)**
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
Requires Python 3.9+. Not yet on PyPI (install from source):
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone https://github.com/StatisticalRL/statrl.git
|
|
20
|
+
cd statrl
|
|
21
|
+
pip install -e . # editable install for development
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quickstart
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from statrl.settings.bandits.stochastic.anytime.envs.parametric import BernoulliBandit
|
|
28
|
+
from statrl.settings.bandits.stochastic.anytime.agents.IMED import IMED
|
|
29
|
+
from statrl.settings.bandits.stochastic.anytime.agents._Oracle import Oracle
|
|
30
|
+
from statrl.settings.bandits.stochastic.anytime.interaction import BanditInteraction
|
|
31
|
+
from statrl.settings.utils import klBern
|
|
32
|
+
|
|
33
|
+
env = BernoulliBandit([0.2, 0.9, 0.5])
|
|
34
|
+
interaction = BanditInteraction()
|
|
35
|
+
|
|
36
|
+
scores = interaction.run(env, IMED(env.number_arms, klBern), horizon=2000)
|
|
37
|
+
oracle_scores = interaction.run(env, Oracle(env), horizon=2000)
|
|
38
|
+
|
|
39
|
+
print(f"regret after 2000 rounds: {oracle_scores[-1] - scores[-1]:.1f}")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## The protocol
|
|
43
|
+
|
|
44
|
+
Every setting shares the same protocol:
|
|
45
|
+
|
|
46
|
+
| Component | Responsibility |
|
|
47
|
+
| ----------- | ------------------------------------------------------------------------------------ |
|
|
48
|
+
| Environment | Holds the reward distributions; `step(arm)` samples a reward. |
|
|
49
|
+
| Agent | `reset()` starts a run; `select_arm()` chooses an arm; `update(arm, reward)` learns. |
|
|
50
|
+
| Interaction | `run(env, learner, horizon)` runs the loop and returns cumulative expected scores. |
|
|
51
|
+
|
|
52
|
+
## Implemented settings
|
|
53
|
+
|
|
54
|
+
Under `statrl.settings`:
|
|
55
|
+
|
|
56
|
+
BANDITS:
|
|
57
|
+
- **`stochastic.anytime`**
|
|
58
|
+
- **`stochastic.knownhorizon`** : horizon-aware wrapper over the anytime setting.
|
|
59
|
+
- **`stochastic.batch`** : when considering batch schedule.
|
|
60
|
+
- **`stochastic.kernel`** : RKHS structure on arms.
|
|
61
|
+
- **`adversarial.lipschitz`** : an adversarial Lipschitz forecaster.
|
|
62
|
+
|
|
63
|
+
MARKOV DECISION PROCESSES:
|
|
64
|
+
- **`discrete_nostructure`**: Abstract discrete MDPs.
|
|
65
|
+
- **`gridworld`**: Gridworld MDPs.
|
|
66
|
+
|
|
67
|
+
## Running experiments
|
|
68
|
+
|
|
69
|
+
`statrl.experiments` benchmarks agents: many replicates in parallel, regret against an
|
|
70
|
+
oracle, and plots.
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from statrl.experiments.massiveruns import runLargeMulticoreExperiment
|
|
74
|
+
|
|
75
|
+
runLargeMulticoreExperiment(
|
|
76
|
+
env, agents, oracle, interact,
|
|
77
|
+
timeHorizon=1000, nbReplicates=100, root_folder="results/",
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Results (per-replicate dumps, a logfile, regret plots) are written under `root_folder`.
|
|
82
|
+
See [`examples/`](examples/) for complete runnable scripts.
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install -e ".[test,lint]"
|
|
88
|
+
pytest # tests
|
|
89
|
+
pytest --doctest-modules src/statrl \
|
|
90
|
+
--ignore-glob='*_test.py' # docstring examples
|
|
91
|
+
ruff check src tests # lint
|
|
92
|
+
mypy # type-check
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
Full docs (quickstart, user guide, API reference) live under `docs/`:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pip install -r docs/requirements.txt
|
|
101
|
+
sphinx-build -b html -W --keep-going docs/source docs/_build/html
|
|
102
|
+
sphinx-build -b doctest docs/source docs/_build/doctest
|
|
103
|
+
xdg-open docs/_build/html/index.html
|
|
104
|
+
```
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "statrl"
|
|
7
|
+
version = "1.2609"
|
|
8
|
+
description = "The Statistical Reinforcement Learning Toolkit Library"
|
|
9
|
+
authors = [{ name = "Odalric-Ambrym Maillard", email = "odalricambrym.maillard@inria.fr" }]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
classifiers = ["License :: OSI Approved :: MIT License"]
|
|
13
|
+
requires-python = ">=3.9"
|
|
14
|
+
dependencies = [
|
|
15
|
+
"gymnasium>=1.0",
|
|
16
|
+
"numpy>=2.5",
|
|
17
|
+
"joblib>=1.5",
|
|
18
|
+
"matplotlib>=3.9",
|
|
19
|
+
"scipy>=1.17",
|
|
20
|
+
"pyyaml>=6.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.optional-dependencies]
|
|
24
|
+
test = ["pytest"]
|
|
25
|
+
lint = ["ruff", "mypy"]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/StatisticalRL/statrl"
|
|
29
|
+
Repository = "https://github.com/StatisticalRL/statrl"
|
|
30
|
+
|
|
31
|
+
[tool.setuptools]
|
|
32
|
+
package-dir = { "" = "src" }
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.packages.find]
|
|
35
|
+
where = ["src"]
|
|
36
|
+
|
|
37
|
+
[tool.pytest.ini_options]
|
|
38
|
+
pythonpath = ["src"]
|
|
39
|
+
testpaths = ["tests"]
|
|
40
|
+
|
|
41
|
+
[tool.mypy]
|
|
42
|
+
files = ["src"]
|
|
43
|
+
# Newer numpy stubs use PEP 695 `type` aliases, which need python_version >=
|
|
44
|
+
# 3.12 to parse, even though the package itself still targets
|
|
45
|
+
# requires-python = ">=3.9".
|
|
46
|
+
python_version = "3.12"
|
|
47
|
+
# gymnasium/scipy/joblib lack stubs, so don't error on their missing imports.
|
|
48
|
+
ignore_missing_imports = true
|
|
49
|
+
|
|
50
|
+
[tool.ruff]
|
|
51
|
+
# src layout, so ruff resolves `settings`/`experiments` as first-party.
|
|
52
|
+
src = ["src"]
|
|
53
|
+
# target-version is inferred from project.requires-python.
|
|
54
|
+
#packages = [
|
|
55
|
+
# "statrl",
|
|
56
|
+
# "statrl.experiments",
|
|
57
|
+
# "statrl.settings",
|
|
58
|
+
# "statrl.settings.bandits",
|
|
59
|
+
# "statrl.settings.bandits.stochastic",
|
|
60
|
+
# "statrl.settings.bandits.stochastic.anytime",
|
|
61
|
+
# "statrl.settings.bandits.stochastic.anytime.agents",
|
|
62
|
+
# "statrl.settings.bandits.stochastic.knownhorizon",
|
|
63
|
+
# "statrl.settings.bandits.stochastic.knownhorizon.wrappers",
|
|
64
|
+
# "statrl.settings.bandits.adversarial",
|
|
65
|
+
# "statrl.settings.bandits.adversarial.lipschitz",
|
|
66
|
+
# "statrl.settings.bandits.adversarial.lipschitz.agents",
|
|
67
|
+
#]
|
|
68
|
+
|
|
69
|
+
[tool.ruff.lint]
|
|
70
|
+
# Pinned explicitly: ruff's own default rule set has grown well past this
|
|
71
|
+
# selection in recent releases, and this project only wants pyflakes (F) plus
|
|
72
|
+
# the pycodestyle error subset (E4/E7/E9).
|
|
73
|
+
select = ["E4", "E7", "E9", "F"]
|
statrl-1.2609/setup.cfg
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
|
|
2
|
+
import pickle
|
|
3
|
+
import time
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
def computeScoreDiffs(names: list[str], dump_scores: list[list[str]], timeHorizon: int, envName: str, root_folder: str) -> tuple[list[np.ndarray], list[np.ndarray], list[np.ndarray],list[np.ndarray],list[np.ndarray], list[np.ndarray], list[int]]:
|
|
7
|
+
"""Turn per-replicate score dumps into regret statistics over time.
|
|
8
|
+
|
|
9
|
+
Loads every dump, subtracts each agent's cumulative score from the
|
|
10
|
+
oracle's averaged one to obtain regret, and summarizes the replicates by
|
|
11
|
+
their mean, median, and four quantiles.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
names : list of str
|
|
16
|
+
Agent names, in the same order as ``dump_scores``. Used to name the
|
|
17
|
+
per-agent regret pickles.
|
|
18
|
+
dump_scores : list of list of str
|
|
19
|
+
One list of dump filenames per agent. **The last entry must be the
|
|
20
|
+
oracle's**, and it is what every other entry is compared against — the
|
|
21
|
+
function has no other way to tell which agent is the reference.
|
|
22
|
+
timeHorizon : int
|
|
23
|
+
Number of rounds each run played.
|
|
24
|
+
envName : str
|
|
25
|
+
Environment name, used in the output filenames.
|
|
26
|
+
root_folder : str
|
|
27
|
+
Directory the regret pickles are written to.
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
mean, median : list of ndarray
|
|
32
|
+
Per-agent mean and median regret at each sampled time.
|
|
33
|
+
quantile1, quantile2, quantile3, quantile4 : list of ndarray
|
|
34
|
+
Per-agent regret quantiles at levels 0.1, 0.25, 0.75, and 0.9. The
|
|
35
|
+
plots shade 0.1-0.9 and 0.25-0.75 as nested bands.
|
|
36
|
+
times : list of int
|
|
37
|
+
Sampled time steps, shared by every returned series.
|
|
38
|
+
|
|
39
|
+
Notes
|
|
40
|
+
-----
|
|
41
|
+
Long runs are downsampled to at most ~1000 points
|
|
42
|
+
(``skip = timeHorizon // 1000``), which bounds both plot size and memory.
|
|
43
|
+
Each returned series therefore has ``len(times)`` entries, not
|
|
44
|
+
``timeHorizon``.
|
|
45
|
+
|
|
46
|
+
The oracle's score is averaged across its replicates *before* the
|
|
47
|
+
subtraction, so the result is regret against mean oracle performance
|
|
48
|
+
rather than a paired difference per replicate.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
median = []
|
|
52
|
+
mean = []
|
|
53
|
+
quantile1 = []
|
|
54
|
+
quantile2 = []
|
|
55
|
+
quantile3 = []
|
|
56
|
+
quantile4 = []
|
|
57
|
+
nbAlgs = len(dump_scores) - 1
|
|
58
|
+
|
|
59
|
+
#Downsample the times, especially in case timeHorizon is huge.
|
|
60
|
+
skip = max(1, (timeHorizon // 1000))
|
|
61
|
+
times = [t for t in range(0,timeHorizon,skip)]
|
|
62
|
+
|
|
63
|
+
#file_oracle = open(dump_scores[-1], 'rb')
|
|
64
|
+
#scores_oracle = pickle.load(file_oracle)
|
|
65
|
+
# Comment the following line for BatchMabs:
|
|
66
|
+
#scores_oracle = scores_oracle[0]
|
|
67
|
+
#file_oracle.close()
|
|
68
|
+
|
|
69
|
+
data_o = []
|
|
70
|
+
for oracle_file in dump_scores[-1]:
|
|
71
|
+
with open(oracle_file, 'rb') as file:
|
|
72
|
+
scores_oi = pickle.load(file)
|
|
73
|
+
data_o.append([scores_oi[t] for t in times])
|
|
74
|
+
scores_oracle = np.mean(data_o, axis=0)
|
|
75
|
+
|
|
76
|
+
for j in range(nbAlgs):
|
|
77
|
+
data_j = []
|
|
78
|
+
for alg_file in dump_scores[j]:
|
|
79
|
+
with open(alg_file, 'rb') as file:
|
|
80
|
+
scores_ij = pickle.load(file)
|
|
81
|
+
data_j.append([scores_oracle[k] - scores_ij[t] for k, t in enumerate(times)])
|
|
82
|
+
|
|
83
|
+
filename = f"{root_folder}regret_{envName}_{names[j]}_{timeHorizon}_{j}_{time.time()}"
|
|
84
|
+
with open(filename, 'wb') as out_file:
|
|
85
|
+
pickle.dump(data_j, out_file)
|
|
86
|
+
|
|
87
|
+
mean.append(np.mean(data_j, axis=0))
|
|
88
|
+
median.append(np.quantile(data_j, 0.5, axis=0))
|
|
89
|
+
quantile1.append(np.quantile(data_j, 0.1, axis=0))
|
|
90
|
+
quantile2.append(np.quantile(data_j, 0.25, axis=0))
|
|
91
|
+
quantile3.append(np.quantile(data_j, 0.75, axis=0))
|
|
92
|
+
quantile4.append(np.quantile(data_j, 0.9, axis=0))
|
|
93
|
+
|
|
94
|
+
return mean,median,quantile1,quantile2, quantile3, quantile4,times
|
|
95
|
+
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import statrl.experiments.onerun as oR
|
|
4
|
+
import statrl.experiments.parallelruns as pR
|
|
5
|
+
import statrl.experiments.analyzeruns as aR
|
|
6
|
+
import statrl.experiments.plotruns as plR
|
|
7
|
+
from statrl.experiments.utils import clear_auxiliaryfiles
|
|
8
|
+
|
|
9
|
+
import time
|
|
10
|
+
import os
|
|
11
|
+
from typing import Any
|
|
12
|
+
ROOT="results/"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def runLargeMulticoreExperiment(env: Any, agents: list[Any], oracle: Any, interact: Any, timeHorizon: int=1000, nbReplicates: int=100, root_folder: str=ROOT) -> None:
|
|
16
|
+
"""Benchmark several agents on one environment and plot their regret.
|
|
17
|
+
|
|
18
|
+
For each agent it runs ``nbReplicates`` independent interactions in parallel, runs the oracle for
|
|
19
|
+
the same number, computes regret as the oracle's cumulative score minus each agent's, and writes
|
|
20
|
+
a logfile and regret figures under ``root_folder``.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
env : object
|
|
25
|
+
Environment to benchmark on. Must expose ``name``; an optional
|
|
26
|
+
``displayname`` is used as the figure title when present.
|
|
27
|
+
agents : list of object
|
|
28
|
+
Agents to compare. Their ``name`` attributes must be distinct — dump
|
|
29
|
+
filenames and plot legends are keyed on them, so duplicates silently
|
|
30
|
+
merge two agents' results.
|
|
31
|
+
oracle : object
|
|
32
|
+
Reference agent defining zero regret, and the only one required to
|
|
33
|
+
expose a ``policy`` (it is written to the logfile). Must belong to the
|
|
34
|
+
same setting as ``agents``.
|
|
35
|
+
interact : statrl.experiments.onerun.Interaction
|
|
36
|
+
Interaction loop of the setting, shared by every agent in the run.
|
|
37
|
+
timeHorizon : int, default=1000
|
|
38
|
+
Number of rounds per interaction.
|
|
39
|
+
nbReplicates : int, default=100
|
|
40
|
+
Number of independent runs per agent. Regret quantiles are taken
|
|
41
|
+
across these, so a handful of replicates gives a very rough band.
|
|
42
|
+
root_folder : str, default='results/'
|
|
43
|
+
Output directory, created if absent. Must end with a separator.
|
|
44
|
+
|
|
45
|
+
Returns
|
|
46
|
+
-------
|
|
47
|
+
None
|
|
48
|
+
Everything is written to disk. ``root_folder`` receives a
|
|
49
|
+
``logfile_*.txt``, one ``regret_*`` pickle per agent, and the figures
|
|
50
|
+
``Regrets_*.png`` / ``.pdf`` in linear and log-y scale. The
|
|
51
|
+
intermediate ``aux_*`` dumps are deleted on the way out.
|
|
52
|
+
|
|
53
|
+
See Also
|
|
54
|
+
--------
|
|
55
|
+
statrl.experiments.parallelruns.multicoreRuns : The parallel layer underneath.
|
|
56
|
+
statrl.experiments.analyzeruns.computeScoreDiffs : Turns the dumps into regret statistics.
|
|
57
|
+
statrl.experiments.plotruns.plotScoreDiffs : Draws the figures.
|
|
58
|
+
|
|
59
|
+
Notes
|
|
60
|
+
-----
|
|
61
|
+
Cost grows as ``(len(agents) + 1) * nbReplicates * timeHorizon``. Start
|
|
62
|
+
small — the defaults already amount to 100 000 rounds per agent.
|
|
63
|
+
|
|
64
|
+
Examples
|
|
65
|
+
--------
|
|
66
|
+
>>> from statrl.settings.bandits.stochastic.anytime.envs.parametric import BernoulliBandit
|
|
67
|
+
>>> from statrl.settings.bandits.stochastic.anytime.agents.IMED import IMED
|
|
68
|
+
>>> from statrl.settings.bandits.stochastic.anytime.agents._Oracle import Oracle
|
|
69
|
+
>>> from statrl.settings.bandits.stochastic.anytime.agents._Random import Random
|
|
70
|
+
>>> from statrl.settings.bandits.stochastic.anytime.interaction import BanditInteraction
|
|
71
|
+
>>> from statrl.settings.utils import klBern
|
|
72
|
+
>>> env = BernoulliBandit([0.2, 0.9, 0.5]) # doctest: +SKIP
|
|
73
|
+
>>> runLargeMulticoreExperiment( # doctest: +SKIP
|
|
74
|
+
... env,
|
|
75
|
+
... agents=[IMED(env.number_arms, klBern), Random(env)],
|
|
76
|
+
... oracle=Oracle(env),
|
|
77
|
+
... interact=BanditInteraction(),
|
|
78
|
+
... timeHorizon=1000, nbReplicates=50,
|
|
79
|
+
... )
|
|
80
|
+
"""
|
|
81
|
+
os.makedirs(root_folder, exist_ok=True)
|
|
82
|
+
|
|
83
|
+
envName = env.name
|
|
84
|
+
learners = agents
|
|
85
|
+
|
|
86
|
+
print("-"*30+"Massive Multicore Experiment"+"-"*30)
|
|
87
|
+
print(f'Environment: {envName}')
|
|
88
|
+
print(f'Learners: {[learner.name for learner in learners]}')
|
|
89
|
+
print(f'[INFO] Run {nbReplicates} many interactions of length {timeHorizon} for each learner:')
|
|
90
|
+
dump_scores = []
|
|
91
|
+
names = []
|
|
92
|
+
meanelapsedtimes = []
|
|
93
|
+
|
|
94
|
+
for learner in learners:
|
|
95
|
+
names.append(learner.name)
|
|
96
|
+
dump_scores_learner, meanelapsedtime_learner = pR.multicoreRuns(env, learner, interact, nbReplicates, timeHorizon, oR.oneRunWithDump, root_folder=root_folder)
|
|
97
|
+
dump_scores.append(dump_scores_learner)
|
|
98
|
+
meanelapsedtimes.append(meanelapsedtime_learner)
|
|
99
|
+
|
|
100
|
+
dump_scoresopt, meanelapsedtime = pR.multicoreRuns(env, oracle, interact, nbReplicates, timeHorizon,
|
|
101
|
+
oR.oneRunWithDump, root_folder=root_folder)
|
|
102
|
+
dump_scores.append(dump_scoresopt)
|
|
103
|
+
|
|
104
|
+
## Report statistics and compute regret:
|
|
105
|
+
timestamp = str(time.time())
|
|
106
|
+
logfilename = f"{root_folder}logfile_{envName}_{timestamp}.txt"
|
|
107
|
+
with open(logfilename, 'w') as logfile:
|
|
108
|
+
logfile.write("Environment " + envName + "\n")
|
|
109
|
+
logfile.write("Optimal policy is: " + str(oracle.policy) + "\n")
|
|
110
|
+
logfile.write("Learners " + str([learner.name for learner in learners]) + "\n")
|
|
111
|
+
logfile.write("Time horizon is " + str(timeHorizon) + ", nb of replicates is " + str(nbReplicates) + "\n")
|
|
112
|
+
for name, meanelapsedtime in zip(names, meanelapsedtimes):
|
|
113
|
+
logfile.write(f"{name} average runtime is {meanelapsedtime}\n")
|
|
114
|
+
print("[INFO] A log-file has been generated in ", logfilename)
|
|
115
|
+
print("[INFO] Compute Statistics...")
|
|
116
|
+
mean, median, quantile1, quantile2,quantile3,quantile4, times = aR.computeScoreDiffs(names, dump_scores, timeHorizon, envName, root_folder=root_folder)
|
|
117
|
+
print("[INFO] Plot results...")
|
|
118
|
+
|
|
119
|
+
title = env.displayname if hasattr(env, "displayname") else envName
|
|
120
|
+
labelx,labely = interact.plotlabels
|
|
121
|
+
plR.plotScoreDiffs(names, envName, (title,labelx,labely), mean, median, quantile1, quantile2,quantile3,quantile4, times, timeHorizon, logfile=logfile, timestamp=timestamp, root_folder=root_folder)
|
|
122
|
+
print("[INFO] Clean Auxiliary files...")
|
|
123
|
+
clear_auxiliaryfiles(env, root_folder)
|
|
124
|
+
print("[INFO] Massive multicore experiment successfully completed.")
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
|
|
2
|
+
from statrl.experiments.utils import dump
|
|
3
|
+
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
from abc import ABC, abstractmethod
|
|
7
|
+
from typing import Any
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
class Interaction(ABC):
|
|
11
|
+
"""Base class for the interaction loop of a setting.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def run(self, env: Any, learner: Any, horizon: int)-> np.ndarray:
|
|
16
|
+
"""Run one interaction and return its cumulative expected score.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
env : object
|
|
21
|
+
Environment of the setting. Reset by the implementation.
|
|
22
|
+
learner : object
|
|
23
|
+
Agent of the setting. Reset by the implementation, so one instance
|
|
24
|
+
can serve many replicates.
|
|
25
|
+
horizon : int
|
|
26
|
+
Number of rounds to play.
|
|
27
|
+
|
|
28
|
+
Returns
|
|
29
|
+
-------
|
|
30
|
+
ndarray of shape (horizon,)
|
|
31
|
+
Cumulative *expected* reward. Implementations must return exactly
|
|
32
|
+
``horizon`` entries — :func:`oneRunWithDump` asserts it.
|
|
33
|
+
"""
|
|
34
|
+
return np.array([])
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@abstractmethod
|
|
38
|
+
def renderrun(self, env: Any, learner: Any, horizon: int) -> None:
|
|
39
|
+
"""Run one interaction with rendering enabled, returning no score.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
env : object
|
|
44
|
+
Environment of the setting; the implementation attaches renderers.
|
|
45
|
+
learner : object
|
|
46
|
+
Agent of the setting.
|
|
47
|
+
horizon : int
|
|
48
|
+
Number of rounds to play.
|
|
49
|
+
"""
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
@abstractmethod
|
|
54
|
+
def plotlabels(self) -> tuple[str, str]:
|
|
55
|
+
"""tuple of (str, str): Axis labels ``(x, y)`` for the regret plots.
|
|
56
|
+
|
|
57
|
+
Read by
|
|
58
|
+
:func:`~statrl.experiments.massiveruns.runLargeMulticoreExperiment`
|
|
59
|
+
and forwarded to
|
|
60
|
+
:func:`~statrl.experiments.plotruns.plotScoreDiffs`. Settings whose
|
|
61
|
+
rounds are not time steps override it — the batch setting labels its
|
|
62
|
+
x-axis by episode.
|
|
63
|
+
"""
|
|
64
|
+
raise NotImplementedError
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def oneRunWithDump(env: Any, learner: Any, interact: Any, timeHorizon: int, root_folder: str) -> str:
|
|
70
|
+
"""Run one replicate and pickle its score series to disk.
|
|
71
|
+
|
|
72
|
+
The unit of work handed to :mod:`joblib` by
|
|
73
|
+
:func:`~statrl.experiments.parallelruns.multicoreRuns`. Results travel
|
|
74
|
+
back through the filesystem rather than through the return value, because
|
|
75
|
+
returning full score series from every worker would serialize
|
|
76
|
+
``nbReplicates x timeHorizon`` floats through the process pool.
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
env : object
|
|
81
|
+
Environment for this replicate; already a private deep copy.
|
|
82
|
+
learner : object
|
|
83
|
+
Agent for this replicate; already a private deep copy.
|
|
84
|
+
interact : Interaction
|
|
85
|
+
The interaction loop of the setting.
|
|
86
|
+
timeHorizon : int
|
|
87
|
+
Number of rounds to play.
|
|
88
|
+
root_folder : str
|
|
89
|
+
Directory the dump is written to. Must end with a separator, and must
|
|
90
|
+
already exist.
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
str
|
|
95
|
+
Path of the pickle written, of the form
|
|
96
|
+
``{root_folder}aux_{env}_scores_{agent}_{horizon}_{timestamp}``. The
|
|
97
|
+
``aux_`` prefix is what
|
|
98
|
+
:func:`~statrl.experiments.utils.clear_auxiliaryfiles` deletes once
|
|
99
|
+
the statistics have been computed.
|
|
100
|
+
|
|
101
|
+
Raises
|
|
102
|
+
------
|
|
103
|
+
AssertionError
|
|
104
|
+
If the interaction returned fewer or more than ``timeHorizon`` scores.
|
|
105
|
+
"""
|
|
106
|
+
scoretimeseries=interact.run(env,learner,timeHorizon)
|
|
107
|
+
assert len(scoretimeseries) == timeHorizon
|
|
108
|
+
|
|
109
|
+
tag = f"{env.name}_scores_{learner.name}_{timeHorizon}_{time.time()}"
|
|
110
|
+
filename = dump(scoretimeseries,"aux",tag,root_folder)
|
|
111
|
+
return filename
|