yngvem / group-lasso

Group Lasso implementation following the scikit-learn API
MIT License
105 stars 32 forks source link

DOC: what is the objective function for GroupLasso? #23

Closed mathurinm closed 3 years ago

mathurinm commented 3 years ago

I am having a hard time getting the same results as sklearn or other Lasso/GroupLasso solvers.

Running the following snippet, I get 0 coefficients for clf:

import numpy as np

from numpy.linalg import norm
import group_lasso
from sklearn.datasets import fetch_openml

dataset = fetch_openml('leukemia')
X = np.asfortranarray(dataset.data)
y = np.array([-1 if lab == "ALL" else 1 for lab in dataset.target])
X = X[:, :500]

X -= X.mean(axis=0)
X /= norm(X, axis=0)

grp_size = 1  # amounts to a Lasso
alpha_max = np.max(np.abs(X.T @ y)) / len(y)

groups_yngvem = np.arange(1, X.shape[1] + 1)
alpha = alpha_max / 2

clf2 = group_lasso.GroupLasso(
    groups=groups_yngvem, group_reg=alpha, fit_intercept=False,
    l1_reg=0, supress_warning=True, tol=1e-10, n_iter=10000)
clf2.fit(X, y[:, None])

w = clf2.coef_[:, 0]
print("obj:", np.sum((y - X @ w) ** 2) / 2 + alpha * norm(w, ord=1))

Is it normal ? Since alpha < alpha_max (= norm(X.T @ y, ord="inf") / len(y)), I would expect the results to be non-zero.

Writing the objective in the docstring as it is done e.g. in sklearn.linear_model.Lasso would help, what do you think ?

mathurinm commented 3 years ago

I think I found it: in your implementation, there is no 1/2 in front of the quadratic datafitting term (so dividing alpha by 2 gives the same results as sklearn)

The formula I found in the doc does not have the 1 / n_samples scaling that seems to be used in the code. I believe it would be helpful to have the formula used in practice included in the docstring of the GroupLasso class

yngvem commented 3 years ago

Thank you, I have added this to the documentation now!