MilesCranmer / PySR

High-Performance Symbolic Regression in Python and Julia
https://astroautomata.com/PySR
Apache License 2.0
2.32k stars 211 forks source link

[WIP] experimental way to access expression methods #430

Open MilesCranmer opened 1 year ago

MilesCranmer commented 1 year ago

This creates an Expression class that wraps SymbolicRegression.Node. This would make it easier to access various internal methods of SymbolicRegression.

However, this is very experimental and I'm not sure what the best way forward is. There are a few options:

  1. Have this wrapper class and forward methods.
  2. Attach a few methods to PySRRegressor. Cleaner because we don't need the user to pass model and variable_names manually. However I'm worried the number of methods to PySRRegressor could explode.....
  3. Only create a method to convert from string to Node. Then, expect the user to call SymbolicRegression.<method> themselves, using model.sr_options_ when needed.

I think (3) would make the maintenance job the easiest was we wouldn't have to write a Python equivalent for everything..... However, one downside is that the printing functionality for manually-created expressions does not seem to use variable_names. Maybe for that we need to set define_helper_functions=True when creating the Options.

Fixes #339 and probably a few other issues which want an easier way to access backend internals.

Current version is an attempt at (1):

import numpy as np
from pysr import PySRRegressor, Expression

X = 2 * np.random.randn(100, 5)
y = 2.5382 * np.cos(X[:, 3]) + X[:, 0] ** 2 - 0.5

model = PySRRegressor(unary_operators=["cos"])
model.fit(X, y)

ex = Expression.from_string("cos(x0)", model=model)
ex.compute_complexity()  # = 2