{"slug": "symbolic-learning-in-python-and-julia", "title": "Symbolic Learning in Python and Julia", "summary": "PySR, an open-source symbolic regression tool developed alongside the Julia library SymbolicRegression.jl, is installable via pip or conda and now offers a coding-agent skill installed with the command \"npx skills add astroautomata/PySR.\" PySR's algorithms are documented in arXiv paper 2305.01582, and the tool targets interpretable symbolic expressions for low-dimensional datasets, with symbolic distillation of neural networks (arXiv 2006.11287) extending it to higher-dimensional problems such as N-body equations. The package exposes a scikit-learn-style PySRRegressor interface and ships Docker and Apptainer build files for containerized or cluster use.", "body_md": "\n\n```\npip install pysr\n```\n\nIf you find PySR useful, please cite the paper [arXiv:2305.01582](https://arxiv.org/abs/2305.01582).\nIf you've finished a project with PySR, please submit a PR to showcase your work on the [research showcase page](https://pysr.ai/papers)!\n\n**Contents**:\n\nPySR is an open-source tool for *Symbolic Regression*: a machine learning\ntask where the goal is to find an interpretable symbolic expression that optimizes some objective.\n\nOver a period of several years, PySR has been engineered from the ground up\nto be (1) as high-performance as possible,\n(2) as configurable as possible, and (3) easy to use.\nPySR is developed alongside the Julia library [SymbolicRegression.jl](https://github.com/astroautomata/SymbolicRegression.jl),\nwhich forms the powerful search engine of PySR.\nThe details of these algorithms are described in the [PySR paper](https://arxiv.org/abs/2305.01582).\n\nSymbolic regression works best on low-dimensional datasets, but\none can also extend these approaches to higher-dimensional\nspaces by using \"*Symbolic Distillation*\" of Neural Networks, as explained in\n[2006.11287](https://arxiv.org/abs/2006.11287), where we apply\nit to N-body problems. Here, one essentially uses\nsymbolic regression to convert a neural net\nto an analytic equation. Thus, these tools simultaneously present\nan explicit and powerful way to interpret deep neural networks.\n\nYou can install PySR with pip or conda:\n\n```\npip install pysr\nconda install -c conda-forge pysr\n```\n\nJulia dependencies will be installed at first import.\n\nInstall the [PySR skill](https://github.com/astroautomata/PySR/blob/master/skills/pysr/SKILL.md) to provide your coding\nagents guidance using PySR as part of a larger agentic loop:\n\n```\nnpx skills add astroautomata/PySR\n```\n\nAdd `--global` to install the skill globally.\n\nYou can also use the `Dockerfile` to install PySR in a docker container\n\n1. Clone this repo.\n2. Within the repo's directory, build the docker container:\n\n```\ndocker build -t pysr .\n```\n\n1. You can then start the container with an IPython execution with:\n\n```\ndocker run -it --rm pysr ipython\n```\n\nFor more details, see the [docker section](#docker).\n\nIf you are using PySR on a cluster where you do not have root access,\nyou can use [Apptainer](https://apptainer.org/) to build a container\ninstead of Docker. The `Apptainer.def` file is analogous to the `Dockerfile`,\nand can be built with:\n\n```\napptainer build --notest pysr.sif Apptainer.def\n```\n\nand launched with\n\n```\napptainer run pysr.sif\n```\n\nOne issue you might run into can result in a hard crash at import with\na message like \"`GLIBCXX_...` not found\". This is due to another one of the Python dependencies\nloading an incorrect `libstdc++` library. To fix this, you should modify your\n`LD_LIBRARY_PATH` variable to reference the Julia libraries. For example, if the Julia\nversion of `libstdc++.so` is located in `$HOME/.julia/juliaup/julia-1.10.0+0.x64.linux.gnu/lib/julia/`\n(which likely differs on your system!), you could add:\n\n```\nexport LD_LIBRARY_PATH=$HOME/.julia/juliaup/julia-1.10.0+0.x64.linux.gnu/lib/julia/:$LD_LIBRARY_PATH\n```\n\nto your `.bashrc` or `.zshrc` file.\n\nYou might wish to try the interactive tutorial [here](https://colab.research.google.com/github/astroautomata/PySR/blob/master/examples/pysr_demo.ipynb), which uses the notebook in `examples/pysr_demo.ipynb`.\n\nIn practice, I highly recommend using IPython rather than Jupyter, as the printing is much nicer. Below is a quick demo here which you can paste into a Python runtime. First, let's import numpy to generate some test data:\n\n``` python\nimport numpy as np\n\nX = 2 * np.random.randn(100, 5)\ny = 2.5382 * np.cos(X[:, 3]) + X[:, 0] ** 2 - 0.5\n```\n\nWe have created a dataset with 100 datapoints, with 5 features each.\nThe relation we wish to model is \n\nNow, let's create a PySR model and train it. PySR's main interface is in the style of scikit-learn:\n\n``` python\nfrom pysr import PySRRegressor\n\nmodel = PySRRegressor(\n    maxsize=20,\n    niterations=40,  # < Increase me for better results\n    binary_operators=[\"+\", \"*\"],\n    unary_operators=[\n        \"cos\",\n        \"exp\",\n        \"sin\",\n        \"inv(x) = 1/x\",\n        # ^ Custom operator (julia syntax)\n    ],\n    extra_sympy_mappings={\"inv\": lambda x: 1 / x},\n    # ^ Define operator for SymPy as well\n    elementwise_loss=\"loss(prediction, target) = (prediction - target)^2\",\n    # ^ Custom loss function (julia syntax)\n)\n```\n\nThis will set up the model for 40 iterations of the search code, which contains hundreds of thousands of mutations and equation evaluations.\n\nLet's train this model on our dataset:\n\n```\nmodel.fit(X, y)\n```\n\nInternally, this launches a Julia process which will do a multithreaded search for equations to fit the dataset.\n\nEquations will be printed during training, and once you are satisfied, you may quit early by hitting 'q' and then <enter>.\n\nAfter the model has been fit, you can run `model.predict(X)`\nto see the predictions on a given dataset using the automatically-selected expression,\nor, for example, `model.predict(X, 3)` to see the predictions of the 3rd equation.\n\nYou may run:\n\n```\nprint(model)\n```\n\nto print the learned equations:\n\n```\nPySRRegressor.equations_ = [\n\t   pick     score                                           equation       loss  complexity\n\t0        0.000000                                          4.4324794  42.354317           1\n\t1        1.255691                                          (x0 * x0)   3.437307           3\n\t2        0.011629                          ((x0 * x0) + -0.28087974)   3.358285           5\n\t3        0.897855                              ((x0 * x0) + cos(x3))   1.368308           6\n\t4        0.857018                ((x0 * x0) + (cos(x3) * 2.4566472))   0.246483           8\n\t5  >>>>       inf  (((cos(x3) + -0.19699033) * 2.5382123) + (x0 *...   0.000000          10\n]\n```\n\nThis arrow in the `pick` column indicates which equation is currently selected by your\n`model_selection` strategy for prediction.\n(You may change `model_selection` after `.fit(X, y)` as well.)\n\n`model.equations_` is a pandas DataFrame containing all equations, including callable format\n(`lambda_format`),\nSymPy format (`sympy_format` - which you can also get with `model.sympy()`), and even JAX and PyTorch format\n(both of which are differentiable - which you can get with `model.jax()` and `model.pytorch()`).\n\nNote that `PySRRegressor` stores the state of the last search, and will restart from where you left off the next time you call `.fit()`, assuming you have set `warm_start=True`.\nThis will cause problems if significant changes are made to the search parameters (like changing the operators). You can run `model.reset()` to reset the state.\n\nYou will notice that PySR will save two files:\n`hall_of_fame...csv` and `hall_of_fame...pkl`.\nThe csv file is a list of equations and their losses, and the pkl file is a saved state of the model.\nYou may load the model from the `pkl` file with:\n\n```\nmodel = PySRRegressor.from_file(\"hall_of_fame.2022-08-10_100832.281.pkl\")\n```\n\nThere are several other useful features such as denoising (e.g., `denoise=True`),\nfeature selection (e.g., `select_k_features=3`).\nFor examples of these and other features, see the [examples page](https://pysr.ai/examples).\nFor a detailed look at more options, see the [options page](https://pysr.ai/options).\nYou can also see the full API at [this page](https://pysr.ai/api).\nThere are also tips for tuning PySR on [this page](https://pysr.ai/tuning).\n\nThe following code makes use of as many PySR features as possible.\nNote that is just a demonstration of features and you should not use this example as-is.\nFor details on what each parameter does, check out the [API page](https://pysr.ai/api).\n\n```\nmodel = PySRRegressor(\n    populations=8,\n    # ^ Assuming we have 4 cores, this means 2 populations per core, so one is always running.\n    population_size=50,\n    # ^ Slightly larger populations, for greater diversity.\n    ncycles_per_iteration=500,\n    # ^ Generations between migrations.\n    niterations=10000000,  # Run forever\n    early_stop_condition=(\n        \"stop_if(loss, complexity) = loss < 1e-6 && complexity < 10\"\n        # Stop early if we find a good and simple equation\n    ),\n    timeout_in_seconds=60 * 60 * 24,\n    # ^ Alternatively, stop after 24 hours have passed.\n    maxsize=50,\n    # ^ Allow greater complexity.\n    maxdepth=10,\n    # ^ But, avoid deep nesting.\n    binary_operators=[\"*\", \"+\", \"-\", \"/\"],\n    unary_operators=[\"square\", \"cube\", \"exp\", \"cos2(x)=cos(x)^2\"],\n    constraints={\n        \"/\": (-1, 9),\n        \"square\": 9,\n        \"cube\": 9,\n        \"exp\": 9,\n    },\n    # ^ Limit the complexity within each argument.\n    # \"inv\": (-1, 9) states that the numerator has no constraint,\n    # but the denominator has a max complexity of 9.\n    # \"exp\": 9 simply states that `exp` can only have\n    # an expression of complexity 9 as input.\n    nested_constraints={\n        \"square\": {\"square\": 1, \"cube\": 1, \"exp\": 0},\n        \"cube\": {\"square\": 1, \"cube\": 1, \"exp\": 0},\n        \"exp\": {\"square\": 1, \"cube\": 1, \"exp\": 0},\n    },\n    # ^ Nesting constraints on operators. For example,\n    # \"square(exp(x))\" is not allowed, since \"square\": {\"exp\": 0}.\n    complexity_of_operators={\"/\": 2, \"exp\": 3},\n    # ^ Custom complexity of particular operators.\n    complexity_of_constants=2,\n    # ^ Punish constants more than variables\n    select_k_features=4,\n    # ^ Train on only the 4 most important features\n    progress=True,\n    # ^ Can set to false if printing to a file.\n    weight_randomize=0.1,\n    # ^ Randomize the tree much more frequently\n    cluster_manager=None,\n    # ^ Can be set to, e.g., \"slurm\", to run a slurm\n    # cluster. Just launch one script from the head node.\n    precision=64,\n    # ^ Higher precision calculations.\n    warm_start=True,\n    # ^ Start from where left off.\n    turbo=True,\n    # ^ Faster evaluation (experimental)\n    extra_sympy_mappings={\"cos2\": lambda x: sympy.cos(x)**2},\n    # extra_torch_mappings={sympy.cos: torch.cos},\n    # ^ Not needed as cos already defined, but this\n    # is how you define custom torch operators.\n    # extra_jax_mappings={sympy.cos: \"jnp.cos\"},\n    # ^ For JAX, one passes a string.\n)\n```\n\nYou can also test out PySR in Docker, without installing it locally, by running the following command in the root directory of this repo:\n\n```\ndocker build -t pysr .\n```\n\nThis builds an image called `pysr` for your system's architecture,\nwhich also contains IPython. You can select a specific version\nof Python and Julia with:\n\n```\ndocker build -t pysr --build-arg JLVERSION=1.10.0 --build-arg PYVERSION=3.11.6 .\n```\n\nYou can then run with this dockerfile using:\n\n```\ndocker run -it --rm -v \"$PWD:/data\" pysr ipython\n```\n\nwhich will link the current directory to the container's `/data` directory\nand then launch ipython.\n\nIf you have issues building for your system's architecture,\nyou can emulate another architecture by including `--platform linux/amd64`,\nbefore the `build` and `run` commands.\n\nWe are eager to welcome new contributors! Check out our contributors [guide](https://github.com/astroautomata/PySR/blob/master/CONTRIBUTORS.md) for tips 🚀.\nIf you have an idea for a new feature, don't hesitate to share it on the [issues](https://github.com/astroautomata/PySR/issues) or [discussions](https://github.com/astroautomata/PySR/discussions) page.", "url": "https://wpnews.pro/news/symbolic-learning-in-python-and-julia", "canonical_source": "https://github.com/astroautomata/PySR", "published_at": "2026-10-20 20:07:35+00:00", "updated_at": "2026-10-24 18:17:00.450330+00:00", "lang": "en", "topics": ["machine-learning", "ai-research", "ai-tools", "ai-agents", "developer-tools"], "entities": ["PySR", "SymbolicRegression.jl", "Julia", "Python", "scikit-learn", "Apptainer", "Docker", "astroautomata"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/symbolic-learning-in-python-and-julia", "markdown": "https://wpnews.pro/news/symbolic-learning-in-python-and-julia.md", "text": "https://wpnews.pro/news/symbolic-learning-in-python-and-julia.txt", "jsonld": "https://wpnews.pro/news/symbolic-learning-in-python-and-julia.jsonld"}}