Skip to content

Commit 0db66ba

Browse files
committed
Merge pull request scikit-learn#3778 from MechCoder/expose_positive
[MRG] Expose positive option in elasticnet and lasso path
2 parents b698d9f + 13c2b00 commit 0db66ba

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

doc/whats_new.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ API changes summary
154154
``precompute="auto"`` is now deprecated and will be removed in 0.18
155155
By `Manoj Kumar`_.
156156

157+
- Expose ``positive`` option in :func:`linear_model.enet_path` and
158+
:func:`linear_model.enet_path` which constrains coefficients to be
159+
positive. By `Manoj Kumar`_.
160+
157161
.. _changes_0_15_2:
158162

159163
0.15.2

sklearn/linear_model/coordinate_descent.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def lasso_path(X, y, eps=1e-3, n_alphas=100, alphas=None,
107107
precompute='auto', Xy=None, fit_intercept=None,
108108
normalize=None, copy_X=True, coef_init=None,
109109
verbose=False, return_models=False, return_n_iter=False,
110-
**params):
110+
positive=False, **params):
111111
"""Compute Lasso path with coordinate descent
112112
113113
The Lasso optimization function varies for mono and multi-outputs.
@@ -182,6 +182,9 @@ def lasso_path(X, y, eps=1e-3, n_alphas=100, alphas=None,
182182
params : kwargs
183183
keyword arguments passed to the coordinate descent solver.
184184
185+
positive : bool, default False
186+
If set to True, forces coefficients to be positive.
187+
185188
Returns
186189
-------
187190
models : a list of models along the regularization path
@@ -266,14 +269,15 @@ def lasso_path(X, y, eps=1e-3, n_alphas=100, alphas=None,
266269
alphas=alphas, precompute=precompute, Xy=Xy,
267270
fit_intercept=fit_intercept, normalize=normalize,
268271
copy_X=copy_X, coef_init=coef_init, verbose=verbose,
269-
return_models=return_models, **params)
272+
return_models=return_models, positive=positive,
273+
**params)
270274

271275

272276
def enet_path(X, y, l1_ratio=0.5, eps=1e-3, n_alphas=100, alphas=None,
273277
precompute='auto', Xy=None, fit_intercept=True,
274278
normalize=False, copy_X=True, coef_init=None,
275279
verbose=False, return_models=False, return_n_iter=False,
276-
**params):
280+
positive=False, **params):
277281
"""Compute elastic net path with coordinate descent
278282
279283
The elastic net optimization function varies for mono and multi-outputs.
@@ -359,6 +363,9 @@ def enet_path(X, y, l1_ratio=0.5, eps=1e-3, n_alphas=100, alphas=None,
359363
return_n_iter : bool
360364
whether to return the number of iterations or not.
361365
366+
positive : bool, default False
367+
If set to True, forces coefficients to be positive.
368+
362369
Returns
363370
-------
364371
models : a list of models along the regularization path
@@ -459,7 +466,6 @@ def enet_path(X, y, l1_ratio=0.5, eps=1e-3, n_alphas=100, alphas=None,
459466

460467
n_alphas = len(alphas)
461468
tol = params.get('tol', 1e-4)
462-
positive = params.get('positive', False)
463469
max_iter = params.get('max_iter', 1000)
464470
dual_gaps = np.empty(n_alphas)
465471
n_iters = []

sklearn/linear_model/tests/test_coordinate_descent.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from sklearn.linear_model.coordinate_descent import Lasso, \
2323
LassoCV, ElasticNet, ElasticNetCV, MultiTaskLasso, MultiTaskElasticNet, \
24-
MultiTaskElasticNetCV, MultiTaskLassoCV, lasso_path
24+
MultiTaskElasticNetCV, MultiTaskLassoCV, lasso_path, enet_path
2525
from sklearn.linear_model import LassoLarsCV, lars_path
2626

2727

@@ -574,6 +574,17 @@ def test_deprection_precompute_enet():
574574
assert_warns(DeprecationWarning, clf.fit, X, y)
575575

576576

577+
def test_enet_path_positive():
578+
"""
579+
Test that the coefs returned by positive=True in enet_path are positive
580+
"""
581+
582+
X, y, _, _ = build_dataset(n_samples=50, n_features=50)
583+
for path in [enet_path, lasso_path]:
584+
pos_path_coef = path(X, y, positive=True)[1]
585+
assert_true(np.all(pos_path_coef >= 0))
586+
587+
577588
if __name__ == '__main__':
578589
import nose
579590
nose.runmodule()

0 commit comments

Comments
 (0)