Spaces:
Running
Running
Merge pull request #28 from MilesCranmer/v0.5.0-rc1
Browse files- Project.toml +2 -2
- docs/options.md +9 -0
- example.py +3 -1
- pysr/sr.py +36 -7
- setup.py +1 -1
Project.toml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
| 2 |
SymbolicRegression = "8254be44-1295-4e6a-a16d-46603ac705cb"
|
| 3 |
|
| 4 |
[compat]
|
| 5 |
-
SymbolicRegression = "0.
|
| 6 |
-
julia = "1.
|
|
|
|
| 2 |
SymbolicRegression = "8254be44-1295-4e6a-a16d-46603ac705cb"
|
| 3 |
|
| 4 |
[compat]
|
| 5 |
+
SymbolicRegression = "0.5.0"
|
| 6 |
+
julia = "1.5"
|
docs/options.md
CHANGED
|
@@ -16,6 +16,7 @@ may find useful include:
|
|
| 16 |
- `variable_names` (or pandas input)
|
| 17 |
- Constraining operator complexity
|
| 18 |
- LaTeX, SymPy, and callable equation output
|
|
|
|
| 19 |
|
| 20 |
These are described below
|
| 21 |
|
|
@@ -158,3 +159,11 @@ for the best equation, using the `score` column to sort equations.
|
|
| 158 |
`best_latex()` returns the LaTeX form of this, and `best_callable()`
|
| 159 |
returns a callable function.
|
| 160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
- `variable_names` (or pandas input)
|
| 17 |
- Constraining operator complexity
|
| 18 |
- LaTeX, SymPy, and callable equation output
|
| 19 |
+
- `loss`
|
| 20 |
|
| 21 |
These are described below
|
| 22 |
|
|
|
|
| 159 |
`best_latex()` returns the LaTeX form of this, and `best_callable()`
|
| 160 |
returns a callable function.
|
| 161 |
|
| 162 |
+
## `loss`
|
| 163 |
+
|
| 164 |
+
The default loss is mean-square error, and weighted mean-square error.
|
| 165 |
+
One can pass an arbitrary Julia string to define a custom loss, using,
|
| 166 |
+
e.g., `loss="myloss(x, y) = abs(x - y)^1.5"`. For more details,
|
| 167 |
+
see the
|
| 168 |
+
[Losses](https://milescranmer.github.io/SymbolicRegression.jl/dev/losses/)
|
| 169 |
+
page for SymbolicRegression.jl.
|
example.py
CHANGED
|
@@ -10,7 +10,9 @@ equations = pysr(X, y, niterations=5,
|
|
| 10 |
binary_operators=["plus", "mult"],
|
| 11 |
unary_operators=[
|
| 12 |
"cos", "exp", "sin", #Pre-defined library of operators (see https://pysr.readthedocs.io/en/latest/docs/operators/)
|
| 13 |
-
"inv(x) = 1/x"]
|
|
|
|
|
|
|
| 14 |
|
| 15 |
...# (you can use ctl-c to exit early)
|
| 16 |
|
|
|
|
| 10 |
binary_operators=["plus", "mult"],
|
| 11 |
unary_operators=[
|
| 12 |
"cos", "exp", "sin", #Pre-defined library of operators (see https://pysr.readthedocs.io/en/latest/docs/operators/)
|
| 13 |
+
"inv(x) = 1/x"],
|
| 14 |
+
loss='L1DistLoss()',
|
| 15 |
+
julia_project="../SymbolicRegression.jl") # Define your own operator! (Julia syntax)
|
| 16 |
|
| 17 |
...# (you can use ctl-c to exit early)
|
| 18 |
|
pysr/sr.py
CHANGED
|
@@ -57,12 +57,13 @@ sympy_mappings = {
|
|
| 57 |
}
|
| 58 |
|
| 59 |
def pysr(X=None, y=None, weights=None,
|
|
|
|
|
|
|
| 60 |
procs=4,
|
|
|
|
| 61 |
populations=None,
|
| 62 |
niterations=100,
|
| 63 |
ncyclesperiteration=300,
|
| 64 |
-
binary_operators=["plus", "mult"],
|
| 65 |
-
unary_operators=["cos", "exp", "sin"],
|
| 66 |
alpha=0.1,
|
| 67 |
annealing=True,
|
| 68 |
fractionReplaced=0.10,
|
|
@@ -116,16 +117,42 @@ def pysr(X=None, y=None, weights=None,
|
|
| 116 |
:param y: np.ndarray, 1D array. Rows are examples.
|
| 117 |
:param weights: np.ndarray, 1D array. Each row is how to weight the
|
| 118 |
mean-square-error loss on weights.
|
|
|
|
|
|
|
|
|
|
| 119 |
:param procs: int, Number of processes (=number of populations running).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
:param populations: int, Number of populations running; by default=procs.
|
| 121 |
:param niterations: int, Number of iterations of the algorithm to run. The best
|
| 122 |
equations are printed, and migrate between populations, at the
|
| 123 |
end of each.
|
| 124 |
:param ncyclesperiteration: int, Number of total mutations to run, per 10
|
| 125 |
samples of the population, per iteration.
|
| 126 |
-
:param binary_operators: list, List of strings giving the binary operators
|
| 127 |
-
in Julia's Base, or in `operator.jl`.
|
| 128 |
-
:param unary_operators: list, Same but for operators taking a single `Float32`.
|
| 129 |
:param alpha: float, Initial temperature.
|
| 130 |
:param annealing: bool, Whether to use annealing. You should (and it is default).
|
| 131 |
:param fractionReplaced: float, How much of population to replace with migrating
|
|
@@ -262,7 +289,7 @@ def pysr(X=None, y=None, weights=None,
|
|
| 262 |
weightSimplify=weightSimplify,
|
| 263 |
constraints=constraints,
|
| 264 |
extra_sympy_mappings=extra_sympy_mappings,
|
| 265 |
-
julia_project=julia_project)
|
| 266 |
|
| 267 |
kwargs = {**_set_paths(tempdir), **kwargs}
|
| 268 |
|
|
@@ -383,7 +410,7 @@ def _make_hyperparams_julia_str(X, alpha, annealing, batchSize, batching, binary
|
|
| 383 |
parsimony, perturbationFactor, populations, procs, shouldOptimizeConstants,
|
| 384 |
unary_operators, useFrequency, use_custom_variable_names,
|
| 385 |
variable_names, warmupMaxsize, weightAddNode,
|
| 386 |
-
ncyclesperiteration, fractionReplaced, topn, verbosity,
|
| 387 |
weightDeleteNode, weightDoNothing, weightInsertNode, weightMutateConstant,
|
| 388 |
weightMutateOperator, weightRandomize, weightSimplify, weights, **kwargs):
|
| 389 |
def tuple_fix(ops):
|
|
@@ -411,11 +438,13 @@ greater=SymbolicRegression.greater
|
|
| 411 |
relu=SymbolicRegression.relu
|
| 412 |
logical_or=SymbolicRegression.logical_or
|
| 413 |
logical_and=SymbolicRegression.logical_and
|
|
|
|
| 414 |
|
| 415 |
options = SymbolicRegression.Options(binary_operators={'(' + tuple_fix(binary_operators) + ')'},
|
| 416 |
unary_operators={'(' + tuple_fix(unary_operators) + ')'},
|
| 417 |
{constraints_str}
|
| 418 |
parsimony={parsimony:f}f0,
|
|
|
|
| 419 |
alpha={alpha:f}f0,
|
| 420 |
maxsize={maxsize:d},
|
| 421 |
maxdepth={maxdepth:d},
|
|
|
|
| 57 |
}
|
| 58 |
|
| 59 |
def pysr(X=None, y=None, weights=None,
|
| 60 |
+
binary_operators=["plus", "mult"],
|
| 61 |
+
unary_operators=["cos", "exp", "sin"],
|
| 62 |
procs=4,
|
| 63 |
+
loss='L2DistLoss()',
|
| 64 |
populations=None,
|
| 65 |
niterations=100,
|
| 66 |
ncyclesperiteration=300,
|
|
|
|
|
|
|
| 67 |
alpha=0.1,
|
| 68 |
annealing=True,
|
| 69 |
fractionReplaced=0.10,
|
|
|
|
| 117 |
:param y: np.ndarray, 1D array. Rows are examples.
|
| 118 |
:param weights: np.ndarray, 1D array. Each row is how to weight the
|
| 119 |
mean-square-error loss on weights.
|
| 120 |
+
:param binary_operators: list, List of strings giving the binary operators
|
| 121 |
+
in Julia's Base.
|
| 122 |
+
:param unary_operators: list, Same but for operators taking a single scalar.
|
| 123 |
:param procs: int, Number of processes (=number of populations running).
|
| 124 |
+
:param loss: str, String of Julia code specifying the loss function.
|
| 125 |
+
Can either be a loss from LossFunctions.jl, or your own
|
| 126 |
+
loss written as a function. Examples of custom written losses
|
| 127 |
+
include: `myloss(x, y) = abs(x-y)` for non-weighted, or
|
| 128 |
+
`myloss(x, y, w) = w*abs(x-y)` for weighted.
|
| 129 |
+
Among the included losses, these are:
|
| 130 |
+
Regression:
|
| 131 |
+
- `LPDistLoss{P}()`,
|
| 132 |
+
- `L1DistLoss()`,
|
| 133 |
+
- `L2DistLoss()` (mean square),
|
| 134 |
+
- `LogitDistLoss()`,
|
| 135 |
+
- `HuberLoss(d)`,
|
| 136 |
+
- `L1EpsilonInsLoss(系)`,
|
| 137 |
+
- `L2EpsilonInsLoss(系)`,
|
| 138 |
+
- `PeriodicLoss(c)`,
|
| 139 |
+
- `QuantileLoss(蟿)`,
|
| 140 |
+
Classification:
|
| 141 |
+
- `ZeroOneLoss()`,
|
| 142 |
+
- `PerceptronLoss()`,
|
| 143 |
+
- `L1HingeLoss()`,
|
| 144 |
+
- `SmoothedL1HingeLoss(纬)`,
|
| 145 |
+
- `ModifiedHuberLoss()`,
|
| 146 |
+
- `L2MarginLoss()`,
|
| 147 |
+
- `ExpLoss()`,
|
| 148 |
+
- `SigmoidLoss()`,
|
| 149 |
+
- `DWDMarginLoss(q)`.
|
| 150 |
:param populations: int, Number of populations running; by default=procs.
|
| 151 |
:param niterations: int, Number of iterations of the algorithm to run. The best
|
| 152 |
equations are printed, and migrate between populations, at the
|
| 153 |
end of each.
|
| 154 |
:param ncyclesperiteration: int, Number of total mutations to run, per 10
|
| 155 |
samples of the population, per iteration.
|
|
|
|
|
|
|
|
|
|
| 156 |
:param alpha: float, Initial temperature.
|
| 157 |
:param annealing: bool, Whether to use annealing. You should (and it is default).
|
| 158 |
:param fractionReplaced: float, How much of population to replace with migrating
|
|
|
|
| 289 |
weightSimplify=weightSimplify,
|
| 290 |
constraints=constraints,
|
| 291 |
extra_sympy_mappings=extra_sympy_mappings,
|
| 292 |
+
julia_project=julia_project, loss=loss)
|
| 293 |
|
| 294 |
kwargs = {**_set_paths(tempdir), **kwargs}
|
| 295 |
|
|
|
|
| 410 |
parsimony, perturbationFactor, populations, procs, shouldOptimizeConstants,
|
| 411 |
unary_operators, useFrequency, use_custom_variable_names,
|
| 412 |
variable_names, warmupMaxsize, weightAddNode,
|
| 413 |
+
ncyclesperiteration, fractionReplaced, topn, verbosity, loss,
|
| 414 |
weightDeleteNode, weightDoNothing, weightInsertNode, weightMutateConstant,
|
| 415 |
weightMutateOperator, weightRandomize, weightSimplify, weights, **kwargs):
|
| 416 |
def tuple_fix(ops):
|
|
|
|
| 438 |
relu=SymbolicRegression.relu
|
| 439 |
logical_or=SymbolicRegression.logical_or
|
| 440 |
logical_and=SymbolicRegression.logical_and
|
| 441 |
+
_custom_loss = {loss}
|
| 442 |
|
| 443 |
options = SymbolicRegression.Options(binary_operators={'(' + tuple_fix(binary_operators) + ')'},
|
| 444 |
unary_operators={'(' + tuple_fix(unary_operators) + ')'},
|
| 445 |
{constraints_str}
|
| 446 |
parsimony={parsimony:f}f0,
|
| 447 |
+
loss=_custom_loss,
|
| 448 |
alpha={alpha:f}f0,
|
| 449 |
maxsize={maxsize:d},
|
| 450 |
maxdepth={maxdepth:d},
|
setup.py
CHANGED
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
| 5 |
|
| 6 |
setuptools.setup(
|
| 7 |
name="pysr", # Replace with your own username
|
| 8 |
-
version="0.
|
| 9 |
author="Miles Cranmer",
|
| 10 |
author_email="miles.cranmer@gmail.com",
|
| 11 |
description="Simple and efficient symbolic regression",
|
|
|
|
| 5 |
|
| 6 |
setuptools.setup(
|
| 7 |
name="pysr", # Replace with your own username
|
| 8 |
+
version="0.5.0",
|
| 9 |
author="Miles Cranmer",
|
| 10 |
author_email="miles.cranmer@gmail.com",
|
| 11 |
description="Simple and efficient symbolic regression",
|