forked from benchopt/benchmark_lasso
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobjective.py
45 lines (36 loc) · 1.39 KB
/
objective.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import numpy as np
from numpy.linalg import norm
from benchopt import BaseObjective
class Objective(BaseObjective):
name = "Lasso Regression"
parameters = {
'fit_intercept': [True, False],
'reg': [.5, .1, .05],
}
def __init__(self, reg=.1, fit_intercept=False):
self.reg = reg
self.fit_intercept = fit_intercept
def set_data(self, X, y):
self.X, self.y = X, y
self.lmbd = self.reg * self._get_lambda_max()
self.n_features = self.X.shape[1]
def compute(self, beta):
# compute residuals
if self.fit_intercept:
beta, intercept = beta[:self.n_features], beta[self.n_features:]
diff = self.y - self.X.dot(beta)
if self.fit_intercept:
diff -= intercept
# compute primal objective and duality gap
p_obj = .5 * diff.dot(diff) + self.lmbd * abs(beta).sum()
scaling = max(1, norm(self.X.T @ diff, ord=np.inf) / self.lmbd)
d_obj = (norm(self.y) ** 2 / 2.
- norm(self.y - diff / scaling) ** 2 / 2)
return dict(value=p_obj,
support_size=(beta != 0).sum(),
duality_gap=p_obj - d_obj,)
def _get_lambda_max(self):
return abs(self.X.T.dot(self.y)).max()
def to_dict(self):
return dict(X=self.X, y=self.y, lmbd=self.lmbd,
fit_intercept=self.fit_intercept)