Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH add Lasso.jl julia solver #89

Open
wants to merge 49 commits into
base: main
Choose a base branch
from
Open

Conversation

jolars
Copy link
Contributor

@jolars jolars commented May 11, 2022

This PR adds support for the Lasso.jl Julia package. One problem with the solver is that it has no setting for maximum number of iterations, so when tolerance is low it may fail to converge. I've filed an issue at the repo about this and plan to file a PR eventually to get this fixed.

image

Copy link
Member

@tomMoral tomMoral left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this looks super nice!! Thx @jolars

A few comments along the way.

solvers/lasso_jl.py Outdated Show resolved Hide resolved
solvers/lasso_jl.py Outdated Show resolved Hide resolved
solvers/lasso_jl.jl Outdated Show resolved Hide resolved
solvers/lasso_jl.py Outdated Show resolved Hide resolved
intercept=fit_intercept,
randomize=false,
stopearly=false,
maxncoef=max(size(X, 1), size(X, 2)) * 100,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you comment on what this is?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

randomize shuffles indices before cd loops (sometimes or always, I don't know), stopearly is for stopping the path (change in deviance, saturation), maxncoef is also related to stopping the path early (maximum number of nonzero coefficients). I ran into a bug in the package when these were at their defaults, but I think only the maxncoef setting is actually necessary to work around it. I'll experiment a bit. randomize should really be true I think, but the others do not really matter.

@tomMoral
Copy link
Member

For the broken test, we need to skip the julia solver for OSX as this causes a segfault in this case.

Copy link
Member

@tomMoral tomMoral left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! thx @jolars

Copy link
Contributor

@agramfort agramfort left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mathurinm merge if happy

@mathurinm
Copy link
Collaborator

mathurinm commented May 17, 2022

It's running fine on simulated on my machine.:
image

I only get a lot of

/home/mathurin/anaconda3/envs/benchopt_lasso/lib/python3.9/site-packages/julia/core.py:703: FutureWarning: Accessing `Julia().<name>` to obtain Julia objects is deprecated.  Use `from julia import Main; Main.<name>` or `jl = Julia(); jl.eval('<name>')`.
  warnings.warn(

can we fix it of silence it ? sorry if this has been discussed already

@jt2gtwci
Copy link

I only get a lot of

/home/mathurin/anaconda3/envs/benchopt_lasso/lib/python3.9/site-packages/julia/core.py:703: FutureWarning: Accessing `Julia().<name>` to obtain Julia objects is deprecated.  Use `from julia import Main; Main.<name>` or `jl = Julia(); jl.eval('<name>')`.
  warnings.warn(

can we fix it of silence it ? sorry if this has been discussed already

We talked about this a bit in benchopt/benchopt#372. I actually think the warning might be a bug: JuliaPy/pyjulia#497

@mathurinm
Copy link
Collaborator

So we silence the warning in the solver for now ?

@jolars
Copy link
Contributor Author

jolars commented May 18, 2022

my setup is segfaulting for some reason right now, but I submitted a patch to ignore the warnings somewhat blindly. Can anybody please check that it works?

@mathurinm
Copy link
Collaborator

can you send me the command that causes the segfault ?

@jolars
Copy link
Contributor Author

jolars commented May 18, 2022

can you send me the command that causes the segfault ?

I just tried to call benchopt run -e . -s lasso_jl -d simulated, but I'm sure it's not related to benchopt in any way, just some annoying result of version/compilation problems from the pyenv, conda, and julia mix.

@mathurinm
Copy link
Collaborator

It works but:

  • it takes around 1 min for the solver to start
  • I still get the warnings
  • for some runs it outputs error

@jolars
Copy link
Contributor Author

jolars commented May 18, 2022

it takes around 1 min for the solver to start

that sounds like JIT compiliation

I still get the warnings

Hm, strange. I can silence the same warning in a small script just by doing the same thing:

from julia import Julia
import warnings

warnings.filterwarnings("ignore", category=FutureWarning)
jl = Julia(compiled_modules=False)
jl.eval("1 + 1")

for some runs it outputs error

What kind of errors? I used to receive errors previously due to convergence issues but I thought I had fixed them with a try catch statement.

Are you sure that you don't have results cached or something?

@mathurinm
Copy link
Collaborator

mathurinm commented May 19, 2022

There seems to be something wrong with sparse datasets:

(benchopt_lasso) ➜  lasso git:(bench) ✗ benchopt run . -s lasso_jl -d "libsvm[rcv1.binary]" -r1
WARNING: astropy not found, will default to scipy for convolution
Benchopt is running
libsvm[dataset=rcv1.binary]                                                                      
  |--Lasso Regression[fit_intercept=True,reg=0.5]                                                
/home/mathurin/anaconda3/envs/benchopt_lasso/lib/python3.9/site-packages/julia/core.py:703: FutureWarning: Accessing `Julia().<name>` to obtain Julia objects is deprecated.  Use `from julia import Main; Main.<name>` or `jl = Julia(); jl.eval('<name>')`.
  warnings.warn(
  |--Lasso Regression[fit_intercept=True,reg=0.1]                                                
  |--Lasso Regression[fit_intercept=True,reg=0.05]                                               
  |--Lasso Regression[fit_intercept=True,reg=0.01]                                               
  |--Lasso Regression[fit_intercept=True,reg=0.001]                                              
  |--Lasso Regression[fit_intercept=False,reg=0.5]                                               
  |--Lasso Regression[fit_intercept=False,reg=0.1]                                               
  |--Lasso Regression[fit_intercept=False,reg=0.05]                                              
  |--Lasso Regression[fit_intercept=False,reg=0.01]                                              
  |--Lasso Regression[fit_intercept=False,reg=0.001]                                             
No output produced.                                                                              
Saving result in: None                                                                           

It's because sparse datasets are skipped by benchopt for julia, I remove this in
benchopt/benchopt#404

@mathurinm
Copy link
Collaborator

I don't get it to converge on rcv1.binary, for fit_intercept=False or True:
image

Same behavior for smaller reg (0.01, 0.001)

@jolars
Copy link
Contributor Author

jolars commented May 20, 2022

I am getting the following error when trying to run this now:

signal (11): Segmentation fault
in expression starting at /home/gerd-jln/.conda/envs/benchopt_benchmark_lasso/lib/python3.8/site-packages
/julia/install.jl:34
PyVectorcall_Function at /tmp/python-build.20220215103121.191136/Python-3.9.10/./Include/cpython/abstract
.h:73 [inlined]
_PyObject_Call at /tmp/python-build.20220215103121.191136/Python-3.9.10/Objects/call.c:265
unknown function (ip: 0x7ffcf9909daf)
Allocations: 5608687 (Pool: 5606149; Big: 2538); GC: 6

I am guessing that this has something to do with the mismatch in versions between conda and whatever this other python 3.9.10 version is doing there

@jolars
Copy link
Contributor Author

jolars commented May 20, 2022

I don't get it to converge on rcv1.binary, for fit_intercept=False or True: image

Same behavior for smaller reg (0.01, 0.001)

Hm, could it be that the iteration limit is not sufficiently large?

@mathurinm
Copy link
Collaborator

Ah, because it behaves like glmnet and returns a vector of 0s if it does not converge for the desired lambda ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants