A model of your own · step 1 of 5
When the kernels run out
What if the shape you need is not one of the ones on offer?
SurfaceSpec takes a kernel per treatment — Hill, spline, polynomial, Gaussian process — and covers most dose-response work between them. Sometimes it does not. You have a mechanism, it has a form, and the form is not on the menu.
Then you write the mean yourself. A ModelSpec is four things and no more: the mean as an expression, the outcome column it predicts, the likelihood around it, and every parameter with a prior. Nothing about it is a lower tier of the library — SurfaceSpec builds one of these and hands it to the same backends.
from axiom.core import ModelSpec
print(ModelSpec.__doc__.strip().splitlines()[0])
print()
for name, field in ModelSpec.model_fields.items():
required = "required" if field.is_required() else "optional"
print(f" {name:14s} {required}")
print()
print("the response we need is an exponential approach to a ceiling:")
print()
print(" footfall = alpha + beta * (1 - exp(-spend / k))")
print()
print("alpha is the baseline, beta the most the leaflets can ever add,")
print("and k the spend at which about 63% of that has arrived.")
Mean expression + outcome column + likelihood + every parameter's prior.
name required
mean required
outcome required
likelihood required
parameters required
constraints optional
the response we need is an exponential approach to a ceiling:
footfall = alpha + beta * (1 - exp(-spend / k))
alpha is the baseline, beta the most the leaflets can ever add,
and k the spend at which about 63% of that has arrived.
Every line above was captured by running this code at build time. The steps share one namespace, so the code on this page is the code you would type after the steps before it.