Skip to content

Releases: MilesCranmer/PySR

v1.5.2

05 Mar 14:17
871a710
Compare
Choose a tag to compare

What's Changed

Full Changelog: v1.5.1...v1.5.2

v1.5.1

01 Mar 18:46
7469250
Compare
Choose a tag to compare

What's Changed

Full Changelog: v1.5.0...v1.5.1

v1.5.0

25 Feb 07:21
5426ea0
Compare
Choose a tag to compare

Backend Changes

Major Changes

  • Change behavior of batching to resample only every iteration; not every eval in MilesCranmer/SymbolicRegression.jl#421
    • This result in a speed improvement for code with batching=true
    • It should also result in improved search results with batching, because comparison within a single population is more stable during evolution. In other words, there is no lucky batch phenomenon.
    • This also refactors the batching interface to be cleaner. There is a SubDataset <: Dataset rather than passing around an array idx explicitly.
    • Note that other than the slight behaviour change, this is otherwise backwards compatible - the old way to write custom loss functions that take idx will still be handled.

Other changes

Frontend Changes

Full Changelog: v1.4.0...v1.5.0

v1.4.0

13 Feb 22:06
227d70a
Compare
Choose a tag to compare

What's Changed

#823 adds support for parameters in template expressions, allowing you to learn expressions under a template, that have custom coefficients which can be optimized.

Along with this, the TemplateExpressionSpec API has changed. (The old API will continue to function, but will not have parametric expressions available).

spec = TemplateExpressionSpec(
    "fx = f(x); p[1] + p[2] * fx + p[3] * fx^2",
    expressions=["f"],
    variable_names=["x"],
    parameters={"p": 3},
)

This would learn three parameters, for the expression $y = p_1 + p_2 f(x) + p_3 f(x)^2.$

You can have multiple parameter vectors, and these parameter vectors can also be indexed by categorical features. For example:

# Learn different parameters for each class:
spec = TemplateExpressionSpec(
    "p1[category] * f(x1, x2) + p2[1] * g(x1^2)",
    expressions=["f", "g"],
    variable_names=["x1", "x2", "category"],
    parameters={"p1": 3, "p2": 1},
)

This will learn an equation of the form:
$$y = \alpha_c,f(x_1,x_2) + \beta g(x_1 ^2)$$
where $c$ is the category, $\alpha_c$ is a learned parameter specific to each category, and $\beta$ is a normal scalar category. Note that unlike ParametricExpressionSpec, this feature of TemplateExpressionSpec would have you pass the category variable in X rather than as a category keyword (floating point versions of the categories). This difference means that in a TemplateExpressionSpec, you can actually have multiple categories!

  • Added support for expression-level loss functions via loss_function_expression, which allows you to specify custom loss functions that operate on the full expression object rather than just its evaluated output. This is particularly useful when working with template expressions.

  • Note that the old template expression syntax using function-style definitions is deprecated. Use the new, cleaner syntax instead:

# # Old:
# spec = TemplateExpressionSpec(
#     function_symbols=["f", "g"],
#     combine="((; f, g), (x1, x2, x3)) -> sin(f(x1, x2)) + g(x3)"
# )

# New:
spec = TemplateExpressionSpec(
    "sin(f(x1, x2)) + g(x3)"
    expressions=["f", "g"], 
    variable_names=["x1", "x2", "x3"],
)

Full Changelog: v1.3.1...v1.4.0

v1.3.1

27 Dec 06:13
fc32e76
Compare
Choose a tag to compare

What's Changed

  • Automated update to backend: v1.5.1 by @github-actions in #790

Full Changelog: v1.3.0...v1.3.1

v1.3.0

15 Dec 04:58
5c0f26a
Compare
Choose a tag to compare

What's Changed

  • Expanded support for differential operators via backend 1.5.0 by @MilesCranmer in #782

e.g., say we wish to integrate $\frac{1}{x^2 \sqrt{x^2 - 1}}$ for $x &gt; 1$:

import numpy as np
from pysr import PySRRegressor, TemplateExpressionSpec

x = np.random.uniform(1, 10, (1000,))  # Integrand sampling points
y = 1 / (x**2 * np.sqrt(x**2 - 1))     # Evaluation of the integrand

expression_spec = TemplateExpressionSpec(
    ["f"], "((; f), (x,)) -> D(f, 1)(x)"
)

model = PySRRegressor(
    binary_operators=["+", "-", "*", "/"],
    unary_operators=["sqrt"],
    expression_spec=expression_spec,
    maxsize=20,
)
model.fit(x[:, np.newaxis], y)

which should correctly find $\frac{\sqrt{x^2 - 1}}{x}$.

Full Changelog: v1.2.0...v1.3.0

v1.2.0

14 Dec 06:04
dd2d0e2
Compare
Choose a tag to compare

What's Changed

  • Compatibility with new scikit-learn API and test suite by @MilesCranmer in #776
  • Add differential operators and input stream specification by @MilesCranmer in #780
    • (Note: the differential operators aren't yet in a stable state, and are not yet documented. However, they do work!)
    • This PR also adds various GC allocation improvements in the backend.

Frontend Changelog: v1.1.0...v1.2.0

Backend Changelog: MilesCranmer/SymbolicRegression.jl@v1.2.0...v1.4.0

v1.1.0

09 Dec 00:45
89b5a89
Compare
Choose a tag to compare

What's Changed

  • Automated update to backend: v1.2.0 by @github-actions in #770

Full Changelog: v1.0.2...v1.1.0

v1.0.2

07 Dec 00:42
3433e5d
Compare
Choose a tag to compare

What's Changed

  • logger fixes: close streams and persist during warm start by @BrotherHa in #763
  • Let sympy use log2(x) instead of log(x)/log(2) by @nerai in #712

New Contributors

Full Changelog: v1.0.1...v1.0.2

v1.0.1

06 Dec 18:59
2b00ada
Compare
Choose a tag to compare

What's Changed

  • Automated update to backend: v1.1.0 by @github-actions in #762
  • Fall back to eager registry when needed by @DilumAluthge in #765

New Contributors

Full Changelog: v1.0.0...v1.0.1