# SymbolicRegression: Python -\> Julia?

**URL:** <https://discourse.julialang.org/t/symbolicregression-python-julia/119463>\
**Category:** Modelling & Simulations\
**Created:** [September 16, 2024, 2:05pm UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463 "2024-09-16T14:05:05Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [September 16, 2024, 2:05pm UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/1 "2024-09-16T14:05:05Z")

</div>

I’m trying to use `SymbolicRegression` from Julia, based on some [`SRRegressor`] model in Python. Here is the Python model:

```python
model_SK = PySRRegressor(
    batching=True,
    niterations=400,
    model_selection="accuracy",
    binary_operators=["+", "-", "*", "/", "^"],
    unary_operators=["log", "tan"],
    nested_constraints={'tan': {'tan': 0}, 'log': {'log': 0}},
    maxsize=30,
    timeout_in_seconds=60 * 5,
)

```

The following Julia code works – but I’ve had to skip 2 keywords…:

```julia
model_SK = SRRegressor(
    batching=true,
    niterations=400,
    #model_selection=:accuracy,
    binary_operators=[+,-,*,/,^],
    unary_operators=[log, tan],
    #nested_constraints={tan: {tan: 0}, log: {log: 0}},
    maxsize=30,
    timeout_in_seconds=60.0 * 5, 
)

```

I don’t find (Julia) documentation for the (Python) keywords `model_selection` and `nested_constraints`…, nor what the right-hand side means :-o.

_Questions_:  
A. What are the keyword names in Julia for `model_selection` and `nested_constraints`?  
B. What would be the Julia equivalence of their RHS values (i.e., `"accuracy"` and `{tan: {tan: 0}, log: {log: 0}}`, respectively)?

Without these two keywords, the data vs. prediction is still pretty good:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/5/2/523f82af5255b9d0f5f6d57759313daaea7cb5bd.png)

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [September 16, 2024, 4:38pm UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/2 "2024-09-16T16:38:23Z")

</div>

@MilesCranmer this one’s for you

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [September 16, 2024, 7:29pm UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/3 "2024-09-16T19:29:01Z")

</div>

For `nested_constraints`:

```julia
nested_constraints=[tan => [tan => 0], log => [log => 0]]

```

For `model_selection`, there is instead the parameter `selection_method::Function`. You pass a function that takes kwargs `trees, losses, scores, complexities`, and returns an integer for the chosen equation.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [September 16, 2024, 7:50pm UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/4 "2024-09-16T19:50:42Z")

</div>

Clear answer – I’ll figure out the `selection_method` thing.

When I fit the model, I get an “ugly” expression:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/6/d6d7f5d4b41c52306be34f07f482c21bf614d17f.png)

I can get out the function by:

```julia
r.equations[r.best_idx]

```

which gives the function with variable names equal to the names in the named tuple of the “X”-data,

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/e/7e51d0fe6a24584c35fcaf283b244a9d0b5b66a4.png)

How can I create a function out of this?

```julia
yhat(p_r,T_r) = r.equations[r.best_idx]

```

doesn’t work.

I’m sure there is a simpler way of making this into a function than typing it manually…

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [September 17, 2024, 2:59am UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/5 "2024-09-17T02:59:49Z")

</div>

`r.equations[i]` is a callable object although you need to manually format the inputs into a single array (and transpose it). Also, once [BREAKING: Change expression types to `DynamicExpressions.Expression` (from `DynamicExpressions.Node`) by MilesCranmer · Pull Request #326 · MilesCranmer/SymbolicRegression.jl · GitHub](https://github.com/MilesCranmer/SymbolicRegression.jl/pull/326) merges, life will be much simpler. (Just working out some weird performance changes with that PR which have been tedious to track down.)

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [September 17, 2024, 7:28am UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/6 "2024-09-17T07:28:10Z")

</div>

OK… my input data are:

```julia
# Data 
X = (X1 = x1, X2 = x2)

```

where `x1` is a vector of values typically lying in the interval `[0,30]`, while `x2` is a vector of values typically lying in the interval `[1.5,2.5]`.

I next want to try with some data point `[x1, x2]`, say `[15, 1.5]`, which was not used in the model fit. I try with:

```julia
julia> r.equations[r.best_idx]([15,1.5]')
2-element Vector{Float64}:
 NaN
 NaN

```

So obviously, I misunderstood something.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [September 17, 2024, 4:56pm UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/7 "2024-09-17T16:56:29Z")

</div>

OK: this may not be a recommended method, but it seems to work…

```julia
julia> eval(Meta.parse("yhat(p_r,T_r) = "*r.equation_strings[r.best_idx] ))
julia> yhat(0.8,1.5)
0.9015511099442255

```

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [September 17, 2024, 5:16pm UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/8 "2024-09-17T17:16:59Z")

</div>

Can you share the specific equation where it is outputting NaNs? There are specific situations where it will choose to output NaN rather than propagate Inf (which might result in a finite value in a regular calculation).

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [September 18, 2024, 7:17am UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/9 "2024-09-18T07:17:42Z")

</div>

> [@MilesCranmer](#):
>
> Can you share the specific equation where it is outputting NaNs?

Sorry for delay. Here it is:

```julia
julia> r.equations[r.best_idx]
log((((1.394181306920604 ^ p_r) - p_r) / (T_r / 0.27927367339196735)) + (T_r / 0.8914537841077675)) ^ 0.3399461332361616

julia> r.equations[r.best_idx]([15,1.5]')
2-element Vector{Float64}:
 NaN
 NaN

julia> eval(Meta.parse("sym_reg(p_r,T_r) = "*r.equation_strings[r.best_idx] ))

julia> sym_reg(15,1.5)
1.4946988237609764

```

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [September 18, 2024, 8:13am UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/10 "2024-09-18T08:13:50Z")

</div>

Oh, the callable version you pass in as a batched array. So it should be like

```julia
num_rows = 1
num_features = 2
X = ones(num_features, num_rows)
X[1, 1] = 15
X[2, 1] = 1.5

```

And then pass that `X` in.

The reason it is returning NaN is because it is accessing undefined memory.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [September 18, 2024, 10:41am UTC](https://discourse.julialang.org/t/symbolicregression-python-julia/119463/11 "2024-09-18T10:41:15Z")

</div>

Aha. OK.

I’ll probably stick with the `eval(Meta.parse...`version, as it is simple to use :-o.
