@@ -424,27 +424,22 @@ def hessp(v):
424
424
return grad , hessp
425
425
426
426
427
- def _check_solver_option (solver , multi_class , penalty , dual ,
428
- previous_default_solver = 'liblinear' ):
427
+ def _check_solver_option (solver , multi_class , penalty , dual ):
429
428
430
- # default values raises a future warning
429
+ # Default values raises a future warning
431
430
if solver == 'warn' :
432
- # previous_default_solver is used since LogisticRegression and
433
- # LogisticRegressionCV don't have the same default in 0.19.
434
- solver = previous_default_solver
435
-
436
- # Do not warn if the 'auto' solver selects the previous default solver
437
- if previous_default_solver != 'lbfgs' :
438
- warnings .warn ("Default solver will be changed to 'lbfgs' in 0.22. "
439
- "Use a specific solver to silence this warning." ,
440
- FutureWarning )
431
+ solver = 'liblinear'
432
+ warnings .warn ("Default solver will be changed to 'lbfgs' in 0.22. "
433
+ "Use a specific solver to silence this warning." ,
434
+ FutureWarning )
441
435
442
436
if multi_class == 'warn' :
443
437
multi_class = 'ovr'
444
438
warnings .warn ("Default multi_class will be changed to 'multinomial' in"
445
439
" 0.22. Use a specific option to silence this warning." ,
446
440
FutureWarning )
447
441
442
+ # Check the string parameters
448
443
if multi_class not in ['multinomial' , 'ovr' ]:
449
444
raise ValueError ("multi_class should be either multinomial or "
450
445
"ovr, got %s." % multi_class )
@@ -477,7 +472,7 @@ def _check_solver_option(solver, multi_class, penalty, dual,
477
472
478
473
def logistic_regression_path (X , y , pos_class = None , Cs = 10 , fit_intercept = True ,
479
474
max_iter = 100 , tol = 1e-4 , verbose = 0 ,
480
- solver = 'warn ' , coef = None ,
475
+ solver = 'lbfgs ' , coef = None ,
481
476
class_weight = None , dual = False , penalty = 'l2' ,
482
477
intercept_scaling = 1. , multi_class = 'warn' ,
483
478
random_state = None , check_input = True ,
@@ -527,7 +522,7 @@ def logistic_regression_path(X, y, pos_class=None, Cs=10, fit_intercept=True,
527
522
For the liblinear and lbfgs solvers set verbose to any positive
528
523
number for verbosity.
529
524
530
- solver : {'lbfgs', 'newton-cg', 'liblinear', 'sag', 'saga', 'auto' }
525
+ solver : {'lbfgs', 'newton-cg', 'liblinear', 'sag', 'saga'}
531
526
Numerical solver to use.
532
527
533
528
coef : array-like, shape (n_features,), default None
@@ -618,16 +613,16 @@ def logistic_regression_path(X, y, pos_class=None, Cs=10, fit_intercept=True,
618
613
if isinstance (Cs , numbers .Integral ):
619
614
Cs = np .logspace (- 4 , 4 , Cs )
620
615
616
+ solver , multi_class = _check_solver_option (
617
+ solver , multi_class , penalty , dual )
618
+
621
619
# Preprocessing.
622
620
if check_input :
623
621
X = check_array (X , accept_sparse = 'csr' , dtype = np .float64 ,
624
622
accept_large_sparse = solver != 'liblinear' )
625
623
y = check_array (y , ensure_2d = False , dtype = None )
626
624
check_consistent_length (X , y )
627
-
628
- n_samples , n_features = X .shape
629
- solver , multi_class = _check_solver_option (
630
- solver , multi_class , penalty , dual , 'lbfgs' )
625
+ _ , n_features = X .shape
631
626
632
627
classes = np .unique (y )
633
628
random_state = check_random_state (random_state )
@@ -805,7 +800,7 @@ def logistic_regression_path(X, y, pos_class=None, Cs=10, fit_intercept=True,
805
800
def _log_reg_scoring_path (X , y , train , test , pos_class = None , Cs = 10 ,
806
801
scoring = None , fit_intercept = False ,
807
802
max_iter = 100 , tol = 1e-4 , class_weight = None ,
808
- verbose = 0 , solver = 'warn ' , penalty = 'l2' ,
803
+ verbose = 0 , solver = 'lbfgs ' , penalty = 'l2' ,
809
804
dual = False , intercept_scaling = 1. ,
810
805
multi_class = 'warn' , random_state = None ,
811
806
max_squared_sum = None , sample_weight = None ):
@@ -867,7 +862,7 @@ def _log_reg_scoring_path(X, y, train, test, pos_class=None, Cs=10,
867
862
For the liblinear and lbfgs solvers set verbose to any positive
868
863
number for verbosity.
869
864
870
- solver : {'lbfgs', 'newton-cg', 'liblinear', 'sag', 'saga', 'auto' }
865
+ solver : {'lbfgs', 'newton-cg', 'liblinear', 'sag', 'saga'}
871
866
Decides which solver to use.
872
867
873
868
penalty : str, 'l1' or 'l2'
@@ -931,9 +926,8 @@ def _log_reg_scoring_path(X, y, train, test, pos_class=None, Cs=10,
931
926
n_iter : array, shape(n_cs,)
932
927
Actual number of iteration for each Cs.
933
928
"""
934
- n_samples , n_features = X .shape
935
929
solver , multi_class = _check_solver_option (
936
- solver , multi_class , penalty , dual , 'lbfgs' )
930
+ solver , multi_class , penalty , dual )
937
931
938
932
X_train = X [train ]
939
933
X_test = X [test ]
@@ -1075,8 +1069,8 @@ class LogisticRegression(BaseEstimator, LinearClassifierMixin,
1075
1069
instance used by `np.random`. Used when ``solver`` == 'sag' or
1076
1070
'liblinear'.
1077
1071
1078
- solver : str, {'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga', 'auto' },
1079
- default: 'liblinear'. Will be changed to 'auto ' solver in 0.22.
1072
+ solver : str, {'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'},
1073
+ default: 'liblinear'. Will be changed to 'lbfgs ' solver in 0.22.
1080
1074
Algorithm to use in the optimization problem.
1081
1075
1082
1076
- For small datasets, 'liblinear' is a good choice, whereas 'sag' and
@@ -1086,8 +1080,6 @@ class LogisticRegression(BaseEstimator, LinearClassifierMixin,
1086
1080
schemes.
1087
1081
- 'newton-cg', 'lbfgs' and 'sag' only handle L2 penalty, whereas
1088
1082
'liblinear' and 'saga' handle L1 penalty.
1089
- - 'auto' automatically chooses a solver based on the penalty
1090
- parameter.
1091
1083
1092
1084
Note that 'sag' and 'saga' fast convergence is only guaranteed on
1093
1085
features with approximately the same scale. You can
@@ -1097,8 +1089,8 @@ class LogisticRegression(BaseEstimator, LinearClassifierMixin,
1097
1089
Stochastic Average Gradient descent solver.
1098
1090
.. versionadded:: 0.19
1099
1091
SAGA solver.
1100
- .. versionadded :: 0.20
1101
- 'auto' solver .
1092
+ .. versionchanged :: 0.20
1093
+ Default will change from 'liblinear' to 'lbfgs' in 0.22 .
1102
1094
1103
1095
max_iter : int, default: 100
1104
1096
Useful only for the newton-cg, sag and lbfgs solvers.
@@ -1114,6 +1106,8 @@ class LogisticRegression(BaseEstimator, LinearClassifierMixin,
1114
1106
1115
1107
.. versionadded:: 0.18
1116
1108
Stochastic Average Gradient descent solver for 'multinomial' case.
1109
+ .. versionchanged:: 0.20
1110
+ Default will change from 'ovr' to 'multinomial' in 0.22.
1117
1111
1118
1112
verbose : int, default: 0
1119
1113
For the liblinear and lbfgs solvers set verbose to any positive
@@ -1254,8 +1248,7 @@ def fit(self, X, y, sample_weight=None):
1254
1248
"positive; got (tol=%r)" % self .tol )
1255
1249
1256
1250
solver , multi_class = _check_solver_option (
1257
- self .solver , self .multi_class , self .penalty , self .dual ,
1258
- 'liblinear' )
1251
+ self .solver , self .multi_class , self .penalty , self .dual )
1259
1252
1260
1253
if solver in ['newton-cg' ]:
1261
1254
_dtype = [np .float64 , np .float32 ]
@@ -1282,7 +1275,7 @@ def fit(self, X, y, sample_weight=None):
1282
1275
return self
1283
1276
1284
1277
if solver in ['sag' , 'saga' ]:
1285
- max_squared_sum = np . percentile ( row_norms (X , squared = True ), 90 )
1278
+ max_squared_sum = row_norms (X , squared = True ). max ( )
1286
1279
else :
1287
1280
max_squared_sum = None
1288
1281
@@ -1379,11 +1372,7 @@ def predict_proba(self, X):
1379
1372
if not hasattr (self , "coef_" ):
1380
1373
raise NotFittedError ("Call fit before prediction" )
1381
1374
1382
- # This check can be removed in 0.22, changing back to self.multi_class
1383
- _ , multi_class = _check_solver_option (
1384
- self .solver , self .multi_class , self .penalty , self .dual , 'lbfgs' )
1385
-
1386
- if multi_class == "ovr" :
1375
+ if self .multi_class == "ovr" or self .multi_class == "warn" :
1387
1376
return super (LogisticRegression , self )._predict_proba_lr (X )
1388
1377
else :
1389
1378
decision = self .decision_function (X )
@@ -1476,8 +1465,8 @@ class LogisticRegressionCV(LogisticRegression, BaseEstimator,
1476
1465
that can be used, look at :mod:`sklearn.metrics`. The
1477
1466
default scoring option used is 'accuracy'.
1478
1467
1479
- solver : str, {'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga', 'auto' },
1480
- default: 'lbfgs'. Will be changed to 'auto' solver in 0.22.
1468
+ solver : str, {'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'},
1469
+ default: 'lbfgs'.
1481
1470
Algorithm to use in the optimization problem.
1482
1471
1483
1472
- For small datasets, 'liblinear' is a good choice, whereas 'sag' and
@@ -1489,8 +1478,6 @@ class LogisticRegressionCV(LogisticRegression, BaseEstimator,
1489
1478
'liblinear' and 'saga' handle L1 penalty.
1490
1479
- 'liblinear' might be slower in LogisticRegressionCV because it does
1491
1480
not handle warm-starting.
1492
- - 'auto' automatically chooses a solver based on the penalty
1493
- parameter.
1494
1481
1495
1482
Note that 'sag' and 'saga' fast convergence is only guaranteed on
1496
1483
features with approximately the same scale. You can preprocess the data
@@ -1500,8 +1487,6 @@ class LogisticRegressionCV(LogisticRegression, BaseEstimator,
1500
1487
Stochastic Average Gradient descent solver.
1501
1488
.. versionadded:: 0.19
1502
1489
SAGA solver.
1503
- .. versionadded:: 0.20
1504
- 'auto' solver.
1505
1490
1506
1491
tol : float, optional
1507
1492
Tolerance for stopping criteria.
@@ -1561,6 +1546,8 @@ class LogisticRegressionCV(LogisticRegression, BaseEstimator,
1561
1546
1562
1547
.. versionadded:: 0.18
1563
1548
Stochastic Average Gradient descent solver for 'multinomial' case.
1549
+ .. versionchanged:: 0.20
1550
+ Default will change from 'ovr' to 'multinomial' in 0.22.
1564
1551
1565
1552
random_state : int, RandomState instance or None, optional, default None
1566
1553
If int, random_state is the seed used by the random number generator;
@@ -1621,7 +1608,7 @@ class LogisticRegressionCV(LogisticRegression, BaseEstimator,
1621
1608
1622
1609
"""
1623
1610
def __init__ (self , Cs = 10 , fit_intercept = True , cv = 'warn' , dual = False ,
1624
- penalty = 'l2' , scoring = None , solver = 'warn ' , tol = 1e-4 ,
1611
+ penalty = 'l2' , scoring = None , solver = 'lbfgs ' , tol = 1e-4 ,
1625
1612
max_iter = 100 , class_weight = None , n_jobs = 1 , verbose = 0 ,
1626
1613
refit = True , intercept_scaling = 1. , multi_class = 'warn' ,
1627
1614
random_state = None ):
@@ -1663,7 +1650,7 @@ def fit(self, X, y, sample_weight=None):
1663
1650
self : object
1664
1651
"""
1665
1652
solver , multi_class = _check_solver_option (
1666
- self .solver , self .multi_class , self .penalty , self .dual , 'lbfgs' )
1653
+ self .solver , self .multi_class , self .penalty , self .dual )
1667
1654
1668
1655
if not isinstance (self .max_iter , numbers .Number ) or self .max_iter < 0 :
1669
1656
raise ValueError ("Maximum number of iteration must be positive;"
@@ -1691,7 +1678,7 @@ def fit(self, X, y, sample_weight=None):
1691
1678
encoded_labels = label_encoder .transform (label_encoder .classes_ )
1692
1679
1693
1680
if solver in ['sag' , 'saga' ]:
1694
- max_squared_sum = np . percentile ( row_norms (X , squared = True ), 90 )
1681
+ max_squared_sum = row_norms (X , squared = True ). max ( )
1695
1682
else :
1696
1683
max_squared_sum = None
1697
1684
0 commit comments