Cheat Sheet
This cheat sheet provides code snippets for key concepts and functionalities of AutoRA. You may use this as a resource for developing AutoRA workflows.
Installation
Installing the main package:
pip install "autora"
Installing Optional Packages
e.g., for autora-theorist-bms
package:
pip install -U "autora[theorist-bms]"
AutoRA Variables
Defining Variables
from autora.variable import VariableCollection, Variable
import numpy as np
variables = VariableCollection(
independent_variables=[
Variable(name="intensity", allowed_values[1, 2, 3, 4, 5]),
Variable(name="duration", allowed_values=np.linspace(1, 100, 100))
],
dependent_variables=[Variable(name="accuracy", value_range=(0, 1))]
)
Extracting Variable Names
ivs = [iv.name for iv in variables.independent_variables]
dvs = [dv.name for dv in variables.dependent_variables]
AutoRA Components
Theorists
Fit & Predict
from autora.theorist.bms import BMSRegressor
# declare theorist
theorist = BMSRegressor(epochs=100)
# fit theorist to data
model = theorist.fit(conditions, observations)
# predict new observations
observations = theorist.predict(conditions)
Write Custom Theorist
from sklearn.base import BaseEstimator
class LogisticRegressor(BaseEstimator):
def __init__(self, *args, **kwargs):
self.model = MyTheoristMethod(*args, **kwargs)
def fit(self, conditions, observations):
self.model.fit(conditions, observations)
return self
def predict(self, conditions):
return self.model.predict(observations)
conditions
should be a pandas DataFrame with columns corresponding to the independent variables.
observations
should be a pandas DataFrame with columns corresponding to the dependent variables.
Experimentalists
Generate Conditions
from autora.experimentalist.random import random_pool
conditions = random_pool(variables, num_samples=10)
Write Custom Experimentalist
def my_experimentalist(allowed_conditions, num_samples):
# ...
return selected_conditions
conditions
should be a pandas DataFrame with columns corresponding to the independent variables.
Experiment Runners
Run Experiment
experiment_runner = weber_fechner_law()
experiment_data = experiment_runner.run(conditions)
conditions
should be a pandas DataFrame with columns corresponding to the independent variables.
experiment_data
should be a pandas DataFrame with columns corresponding to the dependent variables.
Using Synthetic Experiment Runners
Equation Runner Example:
from autora.experiment_runner.synthetic.abstract.equation import equation_experiment
from sympy import symbols
import numpy as np
x, y = symbols("x y")
expr = x ** 2 - y ** 2
experiment = equation_experiment(expr)
test_input = np.array([[1, 1], [2 ,2], [2 ,3]])
experiment.experiment_runner(test_input)
Weber-Fechner Example:
# synthetic experiment from autora inventory
from autora.experiment_runner.synthetic.psychophysics.weber_fechner_law import weber_fechner_law
synthetic_runner = weber_fechner_law(constant=3)
variables = synthetic_runner.variables
conditions = synthetic_runner.domain()
experiment_data = synthetic_runner.run(conditions, added_noise=0.01)
Using Behavioral Experiment Runners
Initializing and Running Firebase Runner
firebase_credentials = {
"type": "service_account",
"project_id": "closed-loop-study",
"private_key_id": "YOURKEYID",
"private_key": "-----BEGIN PRIVATE KEY-----\nYOURCREDENTIALS\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-y7hnh@closed-loop-study.iam.gserviceaccount.com",
"client_id": "YOURLIENTID",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-y7hnh%40closed-loop-study.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}
experiment_runner = firebase_runner(
firebase_credentials=firebase_credentials,
time_out=5,
sleep_time=3)
data_raw = experiment_runner(conditions_to_send)
Initializing and Running Prolific Runner
sleep_time = 30
study_name = 'my autora experiment'
study_description= 'Psychophysics Study'
study_url = 'https://closed-loop-study.web.app/'
study_completion_time = 5
prolific_token = 'my prolific token'
completion_code = 'my completion code'
experiment_runner = firebase_prolific_runner(
firebase_credentials=firebase_credentials,
sleep_time=sleep_time,
study_name=study_name,
study_description=study_description,
study_url=study_url,
study_completion_time=study_completion_time,
prolific_token=prolific_token,
completion_code=completion_code,
)
State
Defining Standard State
from autora.state import StandardState
state = StandardState(
variables=variables,
)
Defining Custom State
from autora.state import StandardState
from dataclasses import dataclass, field
@dataclass(frozen=True)
class MyCustomState(StandardState):
additional_field: int = field(
default_factory=list,
metadata={"delta": "extend"},
)
# initialize the state:
state = MyCustomState(variables=variables)
Retrieving Data From State
Conditions
conditions = state.conditions
or
ivs = [iv.name for iv in variables.independent_variables]
conditions = state.experiment_data[ivs]
Experiment Data
experiment_data = state.experiment_data
Observations
experiment_data = state.experiment_data
dvs = [dv.name for dv in variables.dependent_variables]
observations = experiment_data[dvs]
Models
last_model = state.model[-1]
Defining State Wrappers
Theorist Wrapper
from autora.state import on_state, Delta
@on_state()
def theorist_on_state(experiment_data, variables):
ivs = [iv.name for iv in variables.independent_variables]
dvs = [dv.name for dv in variables.dependent_variables]
x = experiment_data[ivs]
y = experiment_data[dvs]
return Delta(models=[my_theorist.fit(x, y)])
Experimentalist Wrapper
from autora.state import on_state, Delta
@on_state()
def experimentalist_on_state(allowed_conditions, num_samples):
return Delta(conditions=my_experimentalist(allowed_conditions, num_samples))
Experiment Runner Wrapper
from autora.state import on_state, Delta
on_state()
def experiment_runner_on_state(conditions, added_noise):
return Delta(experiment_data=my_experiment_runner(conditions, added_noise))
Calling State Wrappers
state = runner_on_state(state)
Warning
When adding your own input arguments to the wrapper, be sure to call the wrapper with all arguments specified in the function signature, e.g., for
@on_state()
def experimentalist_on_state(conditions, num_samples):
return Delta(conditions=my_experimentalist(allowed_conditions, num_samples))
conditions
is a variable retrieved from the state and num_samples
is a custom argument. Thus, you must call the wrapper with
experimentalist_on_state(state, num_samples=num_samples)
experimentalist_on_state(state, num_samples)
will throw an error.
Running a Basic Workflow
Without State Wrappers
conditions = initial_experimentalist(state.variables)
for cycle in range(num_cycles):
observations = experiment_runner(conditions, added_noise=1.0)
model = theorist(conditions, observations)
conditions = experimentalist(model, conditions, observations, num_samples=10)
With State Wrappers
state = initial_experimentalist_on_state(state)
for cycle in range(num_cycles):
state = experiment_runner_on_state(state, num_samples=10)
state = theorist_on_state(state)
state = experimentalist_on_state(state, model=state.model[-1])