6
6
7
7
from skglm .datafits import Quadratic , QuadraticMultiTask
8
8
from skglm .penalties import (
9
- L1 , L1_plus_L2 , WeightedL1 , MCPenalty , SCAD , IndicatorBox , L0_5 , L2_3 ,
9
+ L1 , L1_plus_L2 , WeightedL1 , MCPenalty , SCAD , IndicatorBox , L0_5 , L2_3 , SLOPE ,
10
10
L2_1 , L2_05 , BlockMCPenalty , BlockSCAD )
11
- from skglm import GeneralizedLinearEstimator
12
- from skglm .solvers import AndersonCD , MultiTaskBCD
11
+ from skglm import GeneralizedLinearEstimator , Lasso
12
+ from skglm .solvers import AndersonCD , MultiTaskBCD , FISTA
13
13
from skglm .utils import make_correlated_data
14
14
15
15
25
25
alpha_max = norm (X .T @ y , ord = np .inf ) / n_samples
26
26
alpha = alpha_max / 1000
27
27
28
+ tol = 1e-10
29
+
28
30
penalties = [
29
31
L1 (alpha = alpha ),
30
32
L1_plus_L2 (alpha = alpha , l1_ratio = 0.5 ),
44
46
45
47
@pytest .mark .parametrize ('penalty' , penalties )
46
48
def test_subdiff_diff (penalty ):
47
- tol = 1e-10
48
49
# tol=1e-14 is too low when coefs are of order 1. square roots are computed in
49
50
# some penalties and precision is lost
50
51
est = GeneralizedLinearEstimator (
@@ -58,7 +59,6 @@ def test_subdiff_diff(penalty):
58
59
59
60
@pytest .mark .parametrize ('block_penalty' , block_penalties )
60
61
def test_subdiff_diff_block (block_penalty ):
61
- tol = 1e-10 # see test_subdiff_dist
62
62
est = GeneralizedLinearEstimator (
63
63
datafit = QuadraticMultiTask (),
64
64
penalty = block_penalty ,
@@ -68,5 +68,38 @@ def test_subdiff_diff_block(block_penalty):
68
68
assert_array_less (est .stop_crit_ , est .solver .tol )
69
69
70
70
71
+ def test_slope_lasso ():
72
+ # check that when alphas = [alpha, ..., alpha], SLOPE and L1 solutions are equal
73
+ alphas = np .full (n_features , alpha )
74
+ est = GeneralizedLinearEstimator (
75
+ penalty = SLOPE (alphas ),
76
+ solver = FISTA (max_iter = 1000 , tol = tol , opt_strategy = "fixpoint" ),
77
+ ).fit (X , y )
78
+ lasso = Lasso (alpha , fit_intercept = False , tol = tol ).fit (X , y )
79
+ np .testing .assert_allclose (est .coef_ , lasso .coef_ , rtol = 1e-5 )
80
+
81
+
82
+ def test_slope ():
83
+ # compare solutions with `pyslope`: https://github.com/jolars/pyslope
84
+ try :
85
+ from slope .solvers import pgd_slope # noqa
86
+ from slope .utils import lambda_sequence # noqa
87
+ except ImportError :
88
+ pytest .xfail (
89
+ "This test requires slope to run.\n "
90
+ "https://github.com/jolars/pyslope" )
91
+
92
+ q = 0.1
93
+ alphas = lambda_sequence (
94
+ X , y , fit_intercept = False , reg = alpha / alpha_max , q = q )
95
+ ours = GeneralizedLinearEstimator (
96
+ penalty = SLOPE (alphas ),
97
+ solver = FISTA (max_iter = 1000 , tol = tol , opt_strategy = "fixpoint" ),
98
+ ).fit (X , y )
99
+ pyslope_out = pgd_slope (
100
+ X , y , alphas , fit_intercept = False , max_it = 1000 , gap_tol = tol )
101
+ np .testing .assert_allclose (ours .coef_ , pyslope_out ["beta" ], rtol = 1e-5 )
102
+
103
+
71
104
if __name__ == "__main__" :
72
105
pass
0 commit comments