Spaces:
Running
Running
MilesCranmer
commited on
Commit
•
c8dffac
1
Parent(s):
eb96ede
Enable custom complexities
Browse files- pysr/sr.py +30 -1
- pysr/version.py +2 -2
pysr/sr.py
CHANGED
@@ -357,6 +357,9 @@ class PySRRegressor(BaseEstimator, RegressorMixin):
|
|
357 |
unary_operators=None,
|
358 |
procs=cpu_count(),
|
359 |
loss="L2DistLoss()",
|
|
|
|
|
|
|
360 |
populations=15,
|
361 |
niterations=40,
|
362 |
ncyclesperiteration=550,
|
@@ -444,6 +447,17 @@ class PySRRegressor(BaseEstimator, RegressorMixin):
|
|
444 |
:type populations: int
|
445 |
:param loss: String of Julia code specifying the loss function. Can either be a loss from LossFunctions.jl, or your own loss written as a function. Examples of custom written losses include: `myloss(x, y) = abs(x-y)` for non-weighted, or `myloss(x, y, w) = w*abs(x-y)` for weighted. Among the included losses, these are as follows. Regression: `LPDistLoss{P}()`, `L1DistLoss()`, `L2DistLoss()` (mean square), `LogitDistLoss()`, `HuberLoss(d)`, `L1EpsilonInsLoss(ϵ)`, `L2EpsilonInsLoss(ϵ)`, `PeriodicLoss(c)`, `QuantileLoss(τ)`. Classification: `ZeroOneLoss()`, `PerceptronLoss()`, `L1HingeLoss()`, `SmoothedL1HingeLoss(γ)`, `ModifiedHuberLoss()`, `L2MarginLoss()`, `ExpLoss()`, `SigmoidLoss()`, `DWDMarginLoss(q)`.
|
446 |
:type loss: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
447 |
:param denoise: Whether to use a Gaussian Process to denoise the data before inputting to PySR. Can help PySR fit noisy data.
|
448 |
:type denoise: bool
|
449 |
:param select_k_features: whether to run feature selection in Python using random forests, before passing to the symbolic regression code. None means no feature selection; an int means select that many features.
|
@@ -697,6 +711,9 @@ class PySRRegressor(BaseEstimator, RegressorMixin):
|
|
697 |
unary_operators=unary_operators,
|
698 |
procs=procs,
|
699 |
loss=loss,
|
|
|
|
|
|
|
700 |
populations=populations,
|
701 |
niterations=niterations,
|
702 |
ncyclesperiteration=ncyclesperiteration,
|
@@ -1227,8 +1244,8 @@ class PySRRegressor(BaseEstimator, RegressorMixin):
|
|
1227 |
Main.div = Main.eval("(/)")
|
1228 |
|
1229 |
nested_constraints = self.params["nested_constraints"]
|
|
|
1230 |
if nested_constraints is not None:
|
1231 |
-
# Parse dict into Julia Dict:
|
1232 |
nested_constraints_str = "Dict("
|
1233 |
for outer_k, outer_v in nested_constraints.items():
|
1234 |
nested_constraints_str += f"({outer_k}) => Dict("
|
@@ -1238,6 +1255,15 @@ class PySRRegressor(BaseEstimator, RegressorMixin):
|
|
1238 |
nested_constraints_str += ")"
|
1239 |
nested_constraints = Main.eval(nested_constraints_str)
|
1240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1241 |
Main.custom_loss = Main.eval(loss)
|
1242 |
|
1243 |
mutationWeights = [
|
@@ -1288,6 +1314,9 @@ class PySRRegressor(BaseEstimator, RegressorMixin):
|
|
1288 |
unary_operators=Main.eval(str(tuple(unary_operators)).replace("'", "")),
|
1289 |
bin_constraints=bin_constraints,
|
1290 |
una_constraints=una_constraints,
|
|
|
|
|
|
|
1291 |
nested_constraints=nested_constraints,
|
1292 |
loss=Main.custom_loss,
|
1293 |
maxsize=int(maxsize),
|
|
|
357 |
unary_operators=None,
|
358 |
procs=cpu_count(),
|
359 |
loss="L2DistLoss()",
|
360 |
+
complexity_of_operators=None,
|
361 |
+
complexity_of_constants=None,
|
362 |
+
complexity_of_variables=None,
|
363 |
populations=15,
|
364 |
niterations=40,
|
365 |
ncyclesperiteration=550,
|
|
|
447 |
:type populations: int
|
448 |
:param loss: String of Julia code specifying the loss function. Can either be a loss from LossFunctions.jl, or your own loss written as a function. Examples of custom written losses include: `myloss(x, y) = abs(x-y)` for non-weighted, or `myloss(x, y, w) = w*abs(x-y)` for weighted. Among the included losses, these are as follows. Regression: `LPDistLoss{P}()`, `L1DistLoss()`, `L2DistLoss()` (mean square), `LogitDistLoss()`, `HuberLoss(d)`, `L1EpsilonInsLoss(ϵ)`, `L2EpsilonInsLoss(ϵ)`, `PeriodicLoss(c)`, `QuantileLoss(τ)`. Classification: `ZeroOneLoss()`, `PerceptronLoss()`, `L1HingeLoss()`, `SmoothedL1HingeLoss(γ)`, `ModifiedHuberLoss()`, `L2MarginLoss()`, `ExpLoss()`, `SigmoidLoss()`, `DWDMarginLoss(q)`.
|
449 |
:type loss: str
|
450 |
+
:param complexity_of_operators: If you would like to use a complexity other than 1 for
|
451 |
+
an operator, specify the complexity here. For example, `{"sin": 2, "+": 1}` would give
|
452 |
+
a complexity of 2 for each use of the `sin` operator, and a complexity of 1
|
453 |
+
for each use of the `+` operator (which is the default). You may specify
|
454 |
+
real numbers for a complexity, and the total complexity of a tree will be rounded
|
455 |
+
to the nearest integer after computing.
|
456 |
+
:type complexity_of_operators: dict
|
457 |
+
:param complexity_of_constants: Complexity of constants. Default is 1.
|
458 |
+
:type complexity_of_constants: int/float
|
459 |
+
:param complexity_of_variables: Complexity of variables. Default is 1.
|
460 |
+
:type complexity_of_variables: int/float
|
461 |
:param denoise: Whether to use a Gaussian Process to denoise the data before inputting to PySR. Can help PySR fit noisy data.
|
462 |
:type denoise: bool
|
463 |
:param select_k_features: whether to run feature selection in Python using random forests, before passing to the symbolic regression code. None means no feature selection; an int means select that many features.
|
|
|
711 |
unary_operators=unary_operators,
|
712 |
procs=procs,
|
713 |
loss=loss,
|
714 |
+
complexity_of_operators=complexity_of_operators,
|
715 |
+
complexity_of_constants=complexity_of_constants,
|
716 |
+
complexity_of_variables=complexity_of_variables,
|
717 |
populations=populations,
|
718 |
niterations=niterations,
|
719 |
ncyclesperiteration=ncyclesperiteration,
|
|
|
1244 |
Main.div = Main.eval("(/)")
|
1245 |
|
1246 |
nested_constraints = self.params["nested_constraints"]
|
1247 |
+
# Parse dict into Julia Dict for nested constraints::
|
1248 |
if nested_constraints is not None:
|
|
|
1249 |
nested_constraints_str = "Dict("
|
1250 |
for outer_k, outer_v in nested_constraints.items():
|
1251 |
nested_constraints_str += f"({outer_k}) => Dict("
|
|
|
1255 |
nested_constraints_str += ")"
|
1256 |
nested_constraints = Main.eval(nested_constraints_str)
|
1257 |
|
1258 |
+
# Parse dict into Julia Dict for complexities:
|
1259 |
+
complexity_of_operators = self.params["complexity_of_operators"]
|
1260 |
+
if complexity_of_operators is not None:
|
1261 |
+
complexity_of_operators_str = "Dict("
|
1262 |
+
for k, v in complexity_of_operators.items():
|
1263 |
+
complexity_of_operators_str += f"({k}) => {v}, "
|
1264 |
+
complexity_of_operators_str += ")"
|
1265 |
+
complexity_of_operators = Main.eval(complexity_of_operators_str)
|
1266 |
+
|
1267 |
Main.custom_loss = Main.eval(loss)
|
1268 |
|
1269 |
mutationWeights = [
|
|
|
1314 |
unary_operators=Main.eval(str(tuple(unary_operators)).replace("'", "")),
|
1315 |
bin_constraints=bin_constraints,
|
1316 |
una_constraints=una_constraints,
|
1317 |
+
complexity_of_operators=complexity_of_operators,
|
1318 |
+
complexity_of_constants=self.params["complexity_of_constants"],
|
1319 |
+
complexity_of_variables=self.params["complexity_of_variables"],
|
1320 |
nested_constraints=nested_constraints,
|
1321 |
loss=Main.custom_loss,
|
1322 |
maxsize=int(maxsize),
|
pysr/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
__version__ = "0.8.
|
2 |
-
__symbolic_regression_jl_version__ = "0.9.
|
|
|
1 |
+
__version__ = "0.8.5"
|
2 |
+
__symbolic_regression_jl_version__ = "0.9.2"
|