@@ -512,8 +512,12 @@ def test_lasso_lars_vs_lasso_cd_positive(verbose=False):
512512 # Test that LassoLars and Lasso using coordinate descent give the
513513 # same results when using the positive option
514514
515- # this test is basically a copy of the above plus the positive option
515+ # This test is basically a copy of the above with additional positive
516+ # option. However for the middle part, the comparison of coefficient values
517+ # for a range of alphas, we had to make an adaptations. See below.
516518
519+
520+ # not normalized data
517521 X = 3 * diabetes .data
518522
519523 alphas , _ , lasso_path = linear_model .lars_path (X , y , method = 'lasso' ,
@@ -527,7 +531,28 @@ def test_lasso_lars_vs_lasso_cd_positive(verbose=False):
527531 error = linalg .norm (c - lasso_cd .coef_ )
528532 assert_less (error , 0.01 )
529533
530- # same test, with normalized data
534+
535+ # The range of alphas chosen for coefficient comparison here is restricted
536+ # as compared with the above test without the positive option. This is due
537+ # to the circumstance that the Lars-Lasso algorithm does not converge to
538+ # the least-squares-solution for small alphas, see 'Least Angle Regression'
539+ # by Efron et al 2004. The coefficients are typically in congruence up to
540+ # the smallest alpha reached by the Lars-Lasso algorithm and start to
541+ # diverge thereafter. See
542+ # https://gist.github.com/michigraber/7e7d7c75eca694c7a6ff
543+
544+ for alpha in np .linspace (6e-1 , 1 - 1e-2 , 20 ):
545+ clf1 = linear_model .LassoLars (
546+ fit_intercept = False , alpha = alpha , normalize = False ,
547+ positive = True ).fit (X , y )
548+ clf2 = linear_model .Lasso (
549+ fit_intercept = False , alpha = alpha , tol = 1e-8 ,
550+ normalize = False , positive = True ).fit (X , y )
551+ err = linalg .norm (clf1 .coef_ - clf2 .coef_ )
552+ assert_less (err , 1e-3 )
553+
554+
555+ # normalized data
531556 X = diabetes .data
532557 alphas , _ , lasso_path = linear_model .lars_path (X , y , method = 'lasso' ,
533558 positive = True )
@@ -540,66 +565,3 @@ def test_lasso_lars_vs_lasso_cd_positive(verbose=False):
540565 lasso_cd .fit (X , y )
541566 error = linalg .norm (c - lasso_cd .coef_ )
542567 assert_less (error , 0.01 )
543-
544-
545-
546- def evaluate_lasso_lars_vs_lasso_cd_positive_middle_part ():
547- # this part of the above tests does not confirm equality of results.
548- # but i'm not entirely sure whether this is necessarily to be expected ..
549- # see comments and results below
550-
551- # similar test, with the classifiers
552-
553- for alpha in np .linspace (1e-2 , 1 - 1e-2 , 20 ):
554- clf1 = linear_model .LassoLars (
555- fit_intercept = False , alpha = alpha , normalize = False ,
556- positive = True ).fit (X , y )
557- clf2 = linear_model .Lasso (
558- fit_intercept = False , alpha = alpha , tol = 1e-8 ,
559- normalize = False , positive = True ).fit (X , y )
560- err = linalg .norm (clf1 .coef_ - clf2 .coef_ )
561- mess = 'alpha={} \t err={} \t num_coeffs=({}/{}) (LassoLars / Lasso)'
562- print (mess .format (
563- alpha ,
564- err ,
565- sum (clf1 .coef_ > 0 ),
566- sum (clf2 .coef_ > 0 ),
567- ))
568- #assert_less(err, 1e-3)
569-
570-
571- '''
572- Results produced:
573-
574- In [19]: test_least_angle.evaluate_lasso_lars_vs_lasso_cd_positive_middle_part()
575- alpha=0.01 err=25.7243223179 num_coeffs=(5/5) (LassoLars / Lasso)
576- alpha=0.0615789473684 err=18.2545548874 num_coeffs=(5/5) (LassoLars / Lasso)
577- alpha=0.113157894737 err=10.7847873501 num_coeffs=(5/5) (LassoLars / Lasso)
578- alpha=0.164736842105 err=3.31501982266 num_coeffs=(5/5) (LassoLars / Lasso)
579- alpha=0.216315789474 err=3.69727628935e-06 num_coeffs=(4/4) (LassoLars / Lasso)
580- alpha=0.267894736842 err=3.56502617927e-06 num_coeffs=(4/4) (LassoLars / Lasso)
581- alpha=0.319473684211 err=3.43302342569e-06 num_coeffs=(4/4) (LassoLars / Lasso)
582- alpha=0.371052631579 err=1.05509699804e-06 num_coeffs=(3/3) (LassoLars / Lasso)
583- alpha=0.422631578947 err=5.9269674114e-07 num_coeffs=(3/3) (LassoLars / Lasso)
584- alpha=0.474210526316 err=1.56511823248e-06 num_coeffs=(3/3) (LassoLars / Lasso)
585- alpha=0.525789473684 err=1.28253471214e-06 num_coeffs=(3/3) (LassoLars / Lasso)
586- alpha=0.577368421053 err=1.00002954531e-06 num_coeffs=(3/3) (LassoLars / Lasso)
587- alpha=0.628947368421 err=7.38618104242e-07 num_coeffs=(3/3) (LassoLars / Lasso)
588- alpha=0.680526315789 err=6.78234533087e-07 num_coeffs=(3/3) (LassoLars / Lasso)
589- alpha=0.732105263158 err=2.25315273789e-06 num_coeffs=(3/3) (LassoLars / Lasso)
590- alpha=0.783684210526 err=1.98825668767e-06 num_coeffs=(3/3) (LassoLars / Lasso)
591- alpha=0.835263157895 err=1.72877180183e-06 num_coeffs=(3/3) (LassoLars / Lasso)
592- alpha=0.886842105263 err=1.58242049123e-06 num_coeffs=(3/3) (LassoLars / Lasso)
593- alpha=0.938421052632 err=1.50923193078e-06 num_coeffs=(3/3) (LassoLars / Lasso)
594- alpha=0.99 err=1.43604831986e-06 num_coeffs=(3/3) (LassoLars / Lasso)
595-
596-
597- We see that the 'equality of results' is violated for 'small' alphas.
598- This is mentioned in the original paper by Efron et al. 2004:
599-
600- `The positive Lasso usually does not converge to the full OLS solution
601- beta_{m}, even fro very large choices of t.`
602-
603-
604- '''
605-
0 commit comments