ITADN

[BUG]: [Julia] Could not regenerate all hof's equations when using guesses

#509Openqizzhao 创建于 2025-09-18
bug
Q
qizzhaocommented
### 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 条评论