PyAutoFit: Classy Probabilistic Programming
===========================================
.. |binder| image:: https://mybinder.org/badge_logo.svg
:target: https://mybinder.org/v2/gh/Jammy2211/autofit_workspace/HEAD
.. |RTD| image:: https://readthedocs.org/projects/pyautofit/badge/?version=latest
:target: https://pyautofit.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. |Tests| image:: https://github.com/rhayes777/PyAutoFit/actions/workflows/main.yml/badge.svg
:target: https://github.com/rhayes777/PyAutoFit/actions
.. |Build| image:: https://github.com/rhayes777/PyAutoBuild/actions/workflows/release.yml/badge.svg
:target: https://github.com/rhayes777/PyAutoBuild/actions
.. |JOSS| image:: https://joss.theoj.org/papers/10.21105/joss.02550/status.svg
:target: https://doi.org/10.21105/joss.02550
|binder| |Tests| |Build| |RTD| |JOSS|
`Installation Guide <https://pyautofit.readthedocs.io/en/latest/installation/overview.html>`_ |
`readthedocs <https://pyautofit.readthedocs.io/en/latest/index.html>`_ |
`Introduction on Binder <https://mybinder.org/v2/gh/Jammy2211/autofit_workspace/release?filepath=notebooks/overview/overview_1_the_basics.ipynb>`_ |
`HowToFit <https://pyautofit.readthedocs.io/en/latest/howtofit/howtofit.html>`_
**PyAutoFit** is a Python based probabilistic programming language for model fitting and Bayesian inference
of large datasets.
The basic **PyAutoFit** API allows us a user to quickly compose a probabilistic model and fit it to data via a
log likelihood function, using a range of non-linear search algorithms (e.g. MCMC, nested sampling).
Users can then set up **PyAutoFit** scientific workflow, which enables streamlined modeling of small
datasets with tools to scale up to large datasets.
**PyAutoFit** supports advanced statistical methods, most
notably `a big data framework for Bayesian hierarchical analysis <https://pyautofit.readthedocs.io/en/latest/features/graphical.html>`_.
Getting Started
---------------
The following links are useful for new starters:
- `The PyAutoFit readthedocs <https://pyautofit.readthedocs.io/en/latest>`_, which includes an `installation guide <https://pyautofit.readthedocs.io/en/latest/installation/overview.html>`_ and an overview of **PyAutoFit**'s core features.
- `The introduction Jupyter Notebook on Binder <https://mybinder.org/v2/gh/Jammy2211/autofit_workspace/release?filepath=notebooks/overview/overview_1_the_basics.ipynb>`_, where you can try **PyAutoFit** in a web browser (without installation).
- `The autofit_workspace GitHub repository <https://github.com/Jammy2211/autofit_workspace>`_, which includes example scripts and the `HowToFit Jupyter notebook lectures <https://github.com/Jammy2211/autofit_workspace/tree/main/notebooks/howtofit>`_ which give new users a step-by-step introduction to **PyAutoFit**.
Support
-------
Support for installation issues, help with Fit modeling and using **PyAutoFit** is available by
`raising an issue on the GitHub issues page <https://github.com/rhayes777/PyAutoFit/issues>`_.
We also offer support on the **PyAutoFit** `Slack channel <https://pyautoFit.slack.com/>`_, where we also provide the
latest updates on **PyAutoFit**. Slack is invitation-only, so if you'd like to join send
an `email <https://github.com/Jammy2211>`_ requesting an invite.
HowToFit
--------
For users less familiar with Bayesian inference and scientific analysis you may wish to read through
the **HowToFits** lectures. These teach you the basic principles of Bayesian inference, with the
content pitched at undergraduate level and above.
A complete overview of the lectures `is provided on the HowToFit readthedocs page <https://pyautofit.readthedocs.io/en/latest/howtofit/howtofit.htmll>`_
API Overview
------------
To illustrate the **PyAutoFit** API, we use an illustrative toy model of fitting a one-dimensional Gaussian to
noisy 1D data. Here's the ``data`` (black) and the model (red) we'll fit:
.. image:: https://raw.githubusercontent.com/rhayes777/PyAutoFit/main/files/toy_model_fit.png
:width: 400
We define our model, a 1D Gaussian by writing a Python class using the format below:
.. code-block:: python
class Gaussian:
def __init__(
self,
centre=0.0, # <- PyAutoFit recognises these
normalization=0.1, # <- constructor arguments are
sigma=0.01, # <- the Gaussian's parameters.
):
self.centre = centre
self.normalization = normalization
self.sigma = sigma
"""
An instance of the Gaussian class will be available during model fitting.
This method will be used to fit the model to data and compute a likelihood.
"""
def model_data_from(self, xvalues):
transformed_xvalues = xvalues - self.centre
return (self.normalization / (self.sigma * (2.0 * np.pi) ** 0.5)) * \
np.exp(-0.5 * (transformed_xvalues / self.sigma) ** 2.0)
**PyAutoFit** recognises that this Gaussian may be treated as a model component whose parameters can be fitted for via
a non-linear search like `emcee <https://github.com/dfm/emcee>`_.
To fit this Gaussian to the ``data`` we create an Analysis object, which gives **PyAutoFit** the ``data`` and a
``log_likelihood_function`` describing how to fit the ``data`` with the model:
.. code-block:: python
class Analysis(af.Analysis):
def __init__(self, data, noise_map):
self.data = data
self.noise_map = noise_map
def log_likelihood_function(self, instance):
"""
The 'instance' that comes into this method is an instance of the Gaussian class
above, with the parameters set to values chosen by the non-linear search.
"""
print("Gaussian Instance:")
print("Centre = ", instance.centre)
print("normalization = ", instance.normalization)
print("Sigma = ", instance.sigma)
"""
We fit the ``data`` with the Gaussian instance, using its
"model_data_from" function to create the model data.
"""
xvalues = np.arange(self.data.shape[0])
model_data = instance.model_data_from(xvalues=xvalues)
residual_map = self.data - model_data
chi_squared_map = (residual_map / self.noise_map) ** 2.0
log_likelihood = -0.5 * sum(chi_squared_map)
return log_likelihood
We can now fit our model to the ``data`` using a non-linear search:
.. code-block:: python
model = af.Model(Gaussian)
analysis = Analysis(data=data, noise_map=noise_map)
emcee = af.Emcee(nwalkers=50, nsteps=2000)
result = emcee.fit(model=model, analysis=analysis)
The ``result`` contains information on the model-fit, for example the parameter samples, maximum log likelihood
model and marginalized probability density functions.
Raw data
{
"_id": null,
"home_page": "https://github.com/rhayes777/PyAutoFit",
"name": "autofit",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "cli",
"author": "James Nightingale and Richard Hayes",
"author_email": "richard@rghsoftware.co.uk",
"download_url": "https://files.pythonhosted.org/packages/08/3b/27f684372f31c702e1b9c2a88e902425c5c0de3d087958ce02caddb69fe4/autofit-2025.1.18.7.tar.gz",
"platform": null,
"description": "PyAutoFit: Classy Probabilistic Programming\r\n===========================================\r\n\r\n.. |binder| image:: https://mybinder.org/badge_logo.svg\r\n :target: https://mybinder.org/v2/gh/Jammy2211/autofit_workspace/HEAD\r\n\r\n.. |RTD| image:: https://readthedocs.org/projects/pyautofit/badge/?version=latest\r\n :target: https://pyautofit.readthedocs.io/en/latest/?badge=latest\r\n :alt: Documentation Status\r\n\r\n.. |Tests| image:: https://github.com/rhayes777/PyAutoFit/actions/workflows/main.yml/badge.svg\r\n :target: https://github.com/rhayes777/PyAutoFit/actions\r\n\r\n.. |Build| image:: https://github.com/rhayes777/PyAutoBuild/actions/workflows/release.yml/badge.svg\r\n :target: https://github.com/rhayes777/PyAutoBuild/actions\r\n\r\n.. |JOSS| image:: https://joss.theoj.org/papers/10.21105/joss.02550/status.svg\r\n :target: https://doi.org/10.21105/joss.02550\r\n\r\n|binder| |Tests| |Build| |RTD| |JOSS|\r\n\r\n`Installation Guide <https://pyautofit.readthedocs.io/en/latest/installation/overview.html>`_ |\r\n`readthedocs <https://pyautofit.readthedocs.io/en/latest/index.html>`_ |\r\n`Introduction on Binder <https://mybinder.org/v2/gh/Jammy2211/autofit_workspace/release?filepath=notebooks/overview/overview_1_the_basics.ipynb>`_ |\r\n`HowToFit <https://pyautofit.readthedocs.io/en/latest/howtofit/howtofit.html>`_\r\n\r\n**PyAutoFit** is a Python based probabilistic programming language for model fitting and Bayesian inference\r\nof large datasets.\r\n\r\nThe basic **PyAutoFit** API allows us a user to quickly compose a probabilistic model and fit it to data via a\r\nlog likelihood function, using a range of non-linear search algorithms (e.g. MCMC, nested sampling).\r\n\r\nUsers can then set up **PyAutoFit** scientific workflow, which enables streamlined modeling of small\r\ndatasets with tools to scale up to large datasets.\r\n\r\n**PyAutoFit** supports advanced statistical methods, most\r\nnotably `a big data framework for Bayesian hierarchical analysis <https://pyautofit.readthedocs.io/en/latest/features/graphical.html>`_.\r\n\r\nGetting Started\r\n---------------\r\n\r\nThe following links are useful for new starters:\r\n\r\n- `The PyAutoFit readthedocs <https://pyautofit.readthedocs.io/en/latest>`_, which includes an `installation guide <https://pyautofit.readthedocs.io/en/latest/installation/overview.html>`_ and an overview of **PyAutoFit**'s core features.\r\n\r\n- `The introduction Jupyter Notebook on Binder <https://mybinder.org/v2/gh/Jammy2211/autofit_workspace/release?filepath=notebooks/overview/overview_1_the_basics.ipynb>`_, where you can try **PyAutoFit** in a web browser (without installation).\r\n\r\n- `The autofit_workspace GitHub repository <https://github.com/Jammy2211/autofit_workspace>`_, which includes example scripts and the `HowToFit Jupyter notebook lectures <https://github.com/Jammy2211/autofit_workspace/tree/main/notebooks/howtofit>`_ which give new users a step-by-step introduction to **PyAutoFit**.\r\n\r\nSupport\r\n-------\r\n\r\nSupport for installation issues, help with Fit modeling and using **PyAutoFit** is available by\r\n`raising an issue on the GitHub issues page <https://github.com/rhayes777/PyAutoFit/issues>`_.\r\n\r\nWe also offer support on the **PyAutoFit** `Slack channel <https://pyautoFit.slack.com/>`_, where we also provide the\r\nlatest updates on **PyAutoFit**. Slack is invitation-only, so if you'd like to join send\r\nan `email <https://github.com/Jammy2211>`_ requesting an invite.\r\n\r\nHowToFit\r\n--------\r\n\r\nFor users less familiar with Bayesian inference and scientific analysis you may wish to read through\r\nthe **HowToFits** lectures. These teach you the basic principles of Bayesian inference, with the\r\ncontent pitched at undergraduate level and above.\r\n\r\nA complete overview of the lectures `is provided on the HowToFit readthedocs page <https://pyautofit.readthedocs.io/en/latest/howtofit/howtofit.htmll>`_\r\n\r\nAPI Overview\r\n------------\r\n\r\nTo illustrate the **PyAutoFit** API, we use an illustrative toy model of fitting a one-dimensional Gaussian to\r\nnoisy 1D data. Here's the ``data`` (black) and the model (red) we'll fit:\r\n\r\n.. image:: https://raw.githubusercontent.com/rhayes777/PyAutoFit/main/files/toy_model_fit.png\r\n :width: 400\r\n\r\nWe define our model, a 1D Gaussian by writing a Python class using the format below:\r\n\r\n.. code-block:: python\r\n\r\n class Gaussian:\r\n\r\n def __init__(\r\n self,\r\n centre=0.0, # <- PyAutoFit recognises these\r\n normalization=0.1, # <- constructor arguments are\r\n sigma=0.01, # <- the Gaussian's parameters.\r\n ):\r\n self.centre = centre\r\n self.normalization = normalization\r\n self.sigma = sigma\r\n\r\n \"\"\"\r\n An instance of the Gaussian class will be available during model fitting.\r\n\r\n This method will be used to fit the model to data and compute a likelihood.\r\n \"\"\"\r\n\r\n def model_data_from(self, xvalues):\r\n\r\n transformed_xvalues = xvalues - self.centre\r\n\r\n return (self.normalization / (self.sigma * (2.0 * np.pi) ** 0.5)) * \\\r\n np.exp(-0.5 * (transformed_xvalues / self.sigma) ** 2.0)\r\n\r\n**PyAutoFit** recognises that this Gaussian may be treated as a model component whose parameters can be fitted for via\r\na non-linear search like `emcee <https://github.com/dfm/emcee>`_.\r\n\r\nTo fit this Gaussian to the ``data`` we create an Analysis object, which gives **PyAutoFit** the ``data`` and a\r\n``log_likelihood_function`` describing how to fit the ``data`` with the model:\r\n\r\n.. code-block:: python\r\n\r\n class Analysis(af.Analysis):\r\n\r\n def __init__(self, data, noise_map):\r\n\r\n self.data = data\r\n self.noise_map = noise_map\r\n\r\n def log_likelihood_function(self, instance):\r\n\r\n \"\"\"\r\n The 'instance' that comes into this method is an instance of the Gaussian class\r\n above, with the parameters set to values chosen by the non-linear search.\r\n \"\"\"\r\n\r\n print(\"Gaussian Instance:\")\r\n print(\"Centre = \", instance.centre)\r\n print(\"normalization = \", instance.normalization)\r\n print(\"Sigma = \", instance.sigma)\r\n\r\n \"\"\"\r\n We fit the ``data`` with the Gaussian instance, using its\r\n \"model_data_from\" function to create the model data.\r\n \"\"\"\r\n\r\n xvalues = np.arange(self.data.shape[0])\r\n\r\n model_data = instance.model_data_from(xvalues=xvalues)\r\n residual_map = self.data - model_data\r\n chi_squared_map = (residual_map / self.noise_map) ** 2.0\r\n log_likelihood = -0.5 * sum(chi_squared_map)\r\n\r\n return log_likelihood\r\n\r\nWe can now fit our model to the ``data`` using a non-linear search:\r\n\r\n.. code-block:: python\r\n\r\n model = af.Model(Gaussian)\r\n\r\n analysis = Analysis(data=data, noise_map=noise_map)\r\n\r\n emcee = af.Emcee(nwalkers=50, nsteps=2000)\r\n\r\n result = emcee.fit(model=model, analysis=analysis)\r\n\r\nThe ``result`` contains information on the model-fit, for example the parameter samples, maximum log likelihood\r\nmodel and marginalized probability density functions.\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "Classy Probabilistic Programming",
"version": "2025.1.18.7",
"project_urls": {
"Homepage": "https://github.com/rhayes777/PyAutoFit"
},
"split_keywords": [
"cli"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1cd9c16c03d72311365f0876ec13b183e669e645cbe5851b79b9e85baec8fbd0",
"md5": "c29da083e78215cff49f9f59b689a6c7",
"sha256": "9a13deab2e48ebb12330a88e041cf73e02c3f5a537a4b883dd453a41fe0cae8e"
},
"downloads": -1,
"filename": "autofit-2025.1.18.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c29da083e78215cff49f9f59b689a6c7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 390952,
"upload_time": "2025-01-18T12:26:24",
"upload_time_iso_8601": "2025-01-18T12:26:24.735572Z",
"url": "https://files.pythonhosted.org/packages/1c/d9/c16c03d72311365f0876ec13b183e669e645cbe5851b79b9e85baec8fbd0/autofit-2025.1.18.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "083b27f684372f31c702e1b9c2a88e902425c5c0de3d087958ce02caddb69fe4",
"md5": "287e6495d45630c2a42316ef4cc0a8a3",
"sha256": "7148a3c730364d6d87b99e17b23d41e6e568ef1c694ed9aec9c637f90f7a60b9"
},
"downloads": -1,
"filename": "autofit-2025.1.18.7.tar.gz",
"has_sig": false,
"md5_digest": "287e6495d45630c2a42316ef4cc0a8a3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 279257,
"upload_time": "2025-01-18T12:26:28",
"upload_time_iso_8601": "2025-01-18T12:26:28.306792Z",
"url": "https://files.pythonhosted.org/packages/08/3b/27f684372f31c702e1b9c2a88e902425c5c0de3d087958ce02caddb69fe4/autofit-2025.1.18.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-18 12:26:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rhayes777",
"github_project": "PyAutoFit",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "anesthetic",
"specs": [
[
"==",
"2.8.14"
]
]
},
{
"name": "corner",
"specs": [
[
"==",
"2.2.2"
]
]
},
{
"name": "decorator",
"specs": [
[
">=",
"4.2.1"
]
]
},
{
"name": "dill",
"specs": [
[
">=",
"0.3.1.1"
]
]
},
{
"name": "dynesty",
"specs": [
[
"==",
"2.1.4"
]
]
},
{
"name": "typing-inspect",
"specs": [
[
">=",
"0.4.0"
]
]
},
{
"name": "emcee",
"specs": [
[
">=",
"3.1.6"
]
]
},
{
"name": "gprof2dot",
"specs": [
[
"==",
"2021.2.21"
]
]
},
{
"name": "matplotlib",
"specs": []
},
{
"name": "numpydoc",
"specs": [
[
">=",
"1.0.0"
]
]
},
{
"name": "pyprojroot",
"specs": [
[
"==",
"0.2.0"
]
]
},
{
"name": "pyswarms",
"specs": [
[
"==",
"1.3.0"
]
]
},
{
"name": "h5py",
"specs": [
[
">=",
"3.11.0"
]
]
},
{
"name": "SQLAlchemy",
"specs": [
[
"==",
"2.0.32"
]
]
},
{
"name": "scipy",
"specs": [
[
"<=",
"1.14.0"
]
]
},
{
"name": "astunparse",
"specs": [
[
"==",
"1.6.3"
]
]
},
{
"name": "threadpoolctl",
"specs": [
[
">=",
"3.1.0"
],
[
"<=",
"3.2.0"
]
]
},
{
"name": "timeout-decorator",
"specs": [
[
"==",
"0.5.0"
]
]
},
{
"name": "xxhash",
"specs": [
[
"<=",
"3.4.1"
]
]
},
{
"name": "networkx",
"specs": [
[
"==",
"3.1"
]
]
},
{
"name": "pyvis",
"specs": [
[
"==",
"0.3.2"
]
]
},
{
"name": "psutil",
"specs": [
[
"==",
"6.1.0"
]
]
}
],
"lcname": "autofit"
}