[BUG]: [Julia] Could not regenerate all hof's equations when using guesses
bug
### What happened?
Hi, I have post the issue on #https://github.com/MilesCranmer/PySR/discussions/1032.
SymbolicRegression package in Julia, which will generate equations and store as hall_of_fame.csv after training. I am trying to reload all h.o.f equations and do predictions on new dataset X. Working on reloading the equations, it seems that reloaded model will ignores several h.o.f's equations after fitting. Below is a very short example:
- There is a hall_of_frame.csv with equations: A, B, C, D, E
- tried to use those equations above to do prediction for another dataset X.
- load hof.csv file and regenerate the Machine
- new Machine only contains A, B, C and ignores D, E
Dataset are attached:
- `x.csv`: dataset x for first time training
- `y.csv`: dataset y for first time training
- `hof.csv`: first time training output's equations
The julia scripts are in extra info below(You might need to copy and paste to file):
- `operator.jl`: binary and unary operators using during training
- `loss_function.jl`: define loss function
- `script.jl`: main function to regenerate this situation. Including 2 parts: `first_time_train` and `reload_model_and_predict_on_new_data`
You could regenerate the case through running `julia script.jl` and it will print out the number of hof's equation after fitted.
If you need more information, please let me know
[hall_of_fame.csv](https://github.com/user-attachments/files/22399332/hall_of_fame.csv)
[x.csv](https://github.com/user-attachments/files/22399331/x.csv)
[y.csv](https://github.com/user-attachments/files/22399333/y.csv)
### Version
v2.0.0-alpha.8
### Operating System
Linux
### Interface
Script (i.e., `python my_script.py`)
### Relevant log output
```shell
```
### Extra Info
> loss_function.jl
```
using Statistics
using SymbolicRegression
function mse_loss(tree, dataset::SymbolicRegression.Dataset{T,L}, options)::L where {T,L}
function std(vec)
return (sum( (vec.-sum(vec)/length(vec)).^2 ) / length(vec))^0.5
end
prediction, flag = eval_tree_array(tree, dataset.X, options)
if (!flag) || (std(prediction)<1e-8)
prediction = nothing
return L(Inf)
end
loss = sum((prediction .- dataset.y) .^ 2) / dataset.n
prediction = nothing
return loss
end
```
> operator.jl
```
"""
Binary Operators
"""
my_mod(x, y) = y!=0 ? Base.mod(x,y) : 0.0
pow_abs(x, y) = abs(float(x))^abs(y)<prevfloat(typemax(Float64)) ? abs(float(x))^abs(y) : NaN
is_larger(x, y) = x > y ? 1.0 : -1.0
cond1(x, y) = x>0 ? y : -y
cond2(x, y) = x>0 ? y : 0.0
"""
Unary Operators
"""
my_inv(x) = x!=0 ? 1/x : 0.0
my_sqrt(x) = x>=0 ? sqrt(x) : NaN
abs_sqrt(x) = sqrt(abs(x))
abs_log(x) = x!=0 ? Base.log(abs(x)) : 0.0
my_abs(x) = abs(x)
my_neg(x) = -x
square(x) = x*x
cube(x) = x*x*x
```
> script.jl
```
include("loss_function.jl")
include("operator.jl")
using CSV
using DataFrames
using MLJ
using SymbolicRegression
function first_time_train()
nb_feature = 10
nb_data = 50000
X = Matrix( CSV.read("x.csv", DataFrame, header=false) ) # rand(Float64, nb_data, nb_feature) .* 2 .- 1
y = vec(Matrix(CSV.read("y.csv", DataFrame, header=false))) # rand(Float64, nb_data) .* 2 .- 1
model = SRRegressor(
binary_operators = [+, -, *, /, ^, max, min, pow_abs, is_larger, my_mod],
unary_operators = [sin, cos, exp, sign, square, cube, my_inv, my_sqrt, abs_sqrt, abs_log, my_abs, my_neg],
nested_constraints= [ sin=>[sin=>5, cos=>5], cos=>[sin=>5, cos=>5] ],
loss_function = mse_loss,
niterations = 5,
populations = 10,
population_size= 1000,
ncycles_per_iteration=1000,
maxsize=200,
maxdepth=200,
topn = 200,
save_to_file = true,
parallelism = :multiprocessing,
numprocs = 20,
runtests = false,
);
mach = machine(model, X, y)
fit!(mach)
end
function load_model_and_predict_on_new_data()
nb_feature = 10
nb_data = 50000
X = rand(Float64, nb_data, nb_feature) .* 2 .- 1
y = rand(Float64, nb_data) .* 2 .- 1
hof = CSV.read("hall_of_fame.csv", DataFrame)
guess = hof.Equation
@info "[File] Number of Hall of Fame: $(length(guess))"
model = SRRegressor(
binary_operators = [+, -, *, /, ^, max, min, pow_abs, is_larger, my_mod],
unary_operators = [sin, cos, exp, sign, square, cube, my_inv, my_sqrt, abs_sqrt, abs_log, my_abs, my_neg],
nested_constraints= [ sin=>[sin=>5, cos=>5], cos=>[sin=>5, cos=>5] ],
loss_function = mse_loss,
niterations = 5,
populations = 10,
population_size= 1000,
ncycles_per_iteration=1000,
maxsize=200,
maxdepth=200,
topn = 200,
save_to_file = false,
parallelism = :multiprocessing,
numprocs = 20,
runtests = false,
guesses = guess,
fraction_replaced_guesses = 0.0,
timeout_in_seconds=1,);
mach = machine(model, X, y)
fit!(mach)
res = report(mach)
@info "[Load] Number of Hall of Fame: $(length(res.equations))"
end
if abspath(PROGRAM_FILE) == @__FILE__
load_model_and_predict_on_new_data()
end
```
0 条评论