11# License: BSD 3 clause
22
3- # -*- coding: utf8 -*-
4-
53from tick .optim .prox .base import Prox
64import numpy as np
75
8- from tick .optim .prox .build .prox import ProxSortedL1 as _ProxSortedL1
9- from tick .optim .prox .build .prox import WeightsType_bh , \
10- WeightsType_oscar
11-
12-
13- # TODO: put also the OSCAR weights
14- # TODO: we should be able to put any weights we want...
6+ from tick .optim .prox .build .prox import ProxOscar as _ProxOscar
157
168
17- class ProxSortedL1 (Prox ):
18- """Proximal operator of sorted L1 penalization
9+ class ProxOscar (Prox ):
10+ """Proximal operator the oscar penalization.
11+ This penalization is particularly relevant for feature selection, in
12+ generalized linear models, when features correlation is not too high.
1913
2014 Parameters
2115 ----------
2216 strength : `float`
2317 Level of penalization
2418
25- fdr : `float`, default=0.6
26- Desired False Discovery Rate for detection of non-zeros in
27- the coefficients
28-
29- weights_type : "bh" | "oscar", default="bh"
30-
31- * If "bh", we use Benjamini-Hochberg weights, under a Gaussian
32- error assumption, and expect a FDR control
33- * If "oscar", there is no FDR control, and we get the OSCAR
34- penalization, see notes below for references
19+ # TODO: clean this docstring
20+ ratio : `float`, default=0
21+ The Oscar mixing parameter, with 0 <= ratio <= 1.
22+ For ratio = 0 this is ridge (L2) regularization
23+ For ratio = 1 this is lasso (L1) regularization
24+ For 0 < ratio < 1, the regularization is a linear combination
25+ of L1 and L2.
3526
3627 range : `tuple` of two `int`, default=`None`
3728 Range on which the prox is applied. If `None` then the prox is
3829 applied on the whole vector
3930
40- Attributes
41- ----------
42- weights : `np.array`, shape=(n_coeffs,)
43- The weights used in the penalization. They are automatically
44- setted, depending on the ``weights_type`` and ``fdr``
45- parameters.
31+ positive : `bool`, default=`False`
32+ If True, apply an extra projection onto the set of vectors with
33+ non-negative entries
4634
4735 Notes
4836 -----
@@ -58,59 +46,27 @@ class ProxSortedL1(Prox):
5846 "writable" : True ,
5947 "cpp_setter" : "set_strength"
6048 },
61- "fdr " : {
49+ "ratio " : {
6250 "writable" : True ,
63- "cpp_setter" : "set_fdr"
64- },
65- "_weights_type" : {
66- "writable" : False ,
67- "cpp_setter" : "set_weights_type"
51+ "cpp_setter" : "set_ratio"
6852 },
6953 "positive" : {
7054 "writable" : True ,
7155 "cpp_setter" : "set_positive"
72- },
73- "weights" : {
74- "writable" : False ,
7556 }
7657 }
7758
78- def __init__ (self , strength : float , fdr : float = 0.6 ,
79- weights_type : str = "bh" , range : tuple = None ,
59+ def __init__ (self , strength : float , range : tuple = None ,
8060 positive : bool = False ):
8161 Prox .__init__ (self , range )
8262 self .strength = strength
83- self .fdr = fdr
84- self .weights_type = weights_type
8563 self .positive = positive
8664 self .weights = None
8765 if range is None :
88- self ._prox = _ProxSortedL1 (self .strength , self .fdr ,
89- self ._weights_type ,
90- self .positive )
66+ self ._prox = _ProxOscar (self .strength , self .positive )
9167 else :
92- self ._prox = _ProxSortedL1 (self .strength , self .fdr ,
93- self ._weights_type ,
94- self .range [0 ], self .range [1 ],
95- self .positive )
96-
97- @property
98- def weights_type (self ):
99- if self ._weights_type == WeightsType_bh :
100- return "bh"
101- elif self ._weights_type == WeightsType_oscar :
102- return "oscar"
103-
104- @weights_type .setter
105- def weights_type (self , val ):
106- if val == "bh" :
107- self ._set ("_weights_type" , WeightsType_bh )
108- elif val == "oscar" :
109- self ._set ("_weights_type" , WeightsType_oscar )
110- raise NotImplementedError ("``oscar`` weights." )
111- else :
112- raise ValueError ("``weights_type`` must be either 'bh' "
113- "or 'oscar'" )
68+ self ._prox = _ProxOscar (self .strength , self .range [0 ], self .range [1 ],
69+ self .positive )
11470
11571 def _call (self , coeffs : np .ndarray , t : float , out : np .ndarray ):
11672 self ._prox .call (coeffs , t , out )
@@ -130,8 +86,3 @@ def value(self, coeffs: np.ndarray) -> float:
13086 Value of the penalization at ``coeffs``
13187 """
13288 return self ._prox .value (coeffs )
133-
134- def _as_dict (self ):
135- dd = Prox ._as_dict (self )
136- del dd ["weights" ]
137- return dd
0 commit comments