Skip to content

Commit 48c728e

Browse files
author
Kevin
committed
merge with upstream.
2 parents 2d46101 + e3ec00d commit 48c728e

File tree

5 files changed

+175
-13
lines changed

5 files changed

+175
-13
lines changed

hpsklearn/components.py

+140-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
import xgboost
2424
except ImportError:
2525
xgboost = None
26+
try:
27+
import lightgbm
28+
except ImportError:
29+
lightgbm = None
2630

2731
##########################################
2832
##==== Wrappers for sklearn modules ====##
@@ -123,6 +127,19 @@ def sklearn_XGBRegressor(*args, **kwargs):
123127
raise ImportError('No module named xgboost')
124128
return xgboost.XGBRegressor(*args, **kwargs)
125129

130+
@scope.define
131+
def sklearn_LGBMClassifier(*args, **kwargs):
132+
if lightgbm is None:
133+
raise ImportError('No module named lightgbm')
134+
return lightgbm.LGBMClassifier(*args, **kwargs)
135+
136+
@scope.define
137+
def sklearn_LGBMRegressor(*args, **kwargs):
138+
if lightgbm is None:
139+
raise ImportError('No module named lightgbm')
140+
return lightgbm.LGBMRegressor(*args, **kwargs)
141+
142+
126143
@scope.define
127144
def sklearn_GPRegressor(*args, **kwargs):
128145
return sklearn.gaussian_process.GaussianProcessRegressor(*args, **kwargs)
@@ -1157,7 +1174,7 @@ def _name(msg):
11571174
max_depth=max_depth,
11581175
min_samples_split=scope.int(hp.quniform(
11591176
_name('min_samples_split'),
1160-
1, 10, 1)) if min_samples_split is None else min_samples_split,
1177+
2, 10, 1)) if min_samples_split is None else min_samples_split,
11611178
min_samples_leaf=scope.int(hp.quniform(
11621179
_name('min_samples_leaf'),
11631180
1, 5, 1)) if min_samples_leaf is None else min_samples_leaf,
@@ -1448,7 +1465,6 @@ def _xgboost_hp_space(
14481465
)
14491466
return hp_space
14501467

1451-
14521468
########################################################
14531469
##==== XGBoost classifier/regressor constructors ====##
14541470
########################################################
@@ -1495,6 +1511,128 @@ def _name(msg):
14951511
return scope.sklearn_XGBRegressor(**hp_space)
14961512

14971513

1514+
###################################################
1515+
##==== LightGBM hyperparameters search space ====##
1516+
###################################################
1517+
1518+
def _lightgbm_max_depth(name):
1519+
return scope.int(hp.uniform(name, 1, 11))
1520+
1521+
def _lightgbm_num_leaves(name):
1522+
return scope.int(hp.uniform(name, 2, 121))
1523+
1524+
def _lightgbm_learning_rate(name):
1525+
return hp.loguniform(name, np.log(0.0001), np.log(0.5)) - 0.0001
1526+
1527+
def _lightgbm_n_estimators(name):
1528+
return scope.int(hp.quniform(name, 100, 6000, 200))
1529+
1530+
def _lightgbm_gamma(name):
1531+
return hp.loguniform(name, np.log(0.0001), np.log(5)) - 0.0001
1532+
1533+
def _lightgbm_min_child_weight(name):
1534+
return scope.int(hp.loguniform(name, np.log(1), np.log(100)))
1535+
1536+
def _lightgbm_subsample(name):
1537+
return hp.uniform(name, 0.5, 1)
1538+
1539+
def _lightgbm_colsample_bytree(name):
1540+
return hp.uniform(name, 0.5, 1)
1541+
1542+
def _lightgbm_colsample_bylevel(name):
1543+
return hp.uniform(name, 0.5, 1)
1544+
1545+
def _lightgbm_reg_alpha(name):
1546+
return hp.loguniform(name, np.log(0.0001), np.log(1)) - 0.0001
1547+
1548+
def _lightgbm_reg_lambda(name):
1549+
return hp.loguniform(name, np.log(1), np.log(4))
1550+
1551+
def _lightgbm_boosting_type(name):
1552+
return hp.choice(name, ['gbdt', 'dart', 'goss'])
1553+
1554+
def _lightgbm_hp_space(
1555+
name_func,
1556+
max_depth=None,
1557+
num_leaves=None,
1558+
learning_rate=None,
1559+
n_estimators=None,
1560+
min_child_weight=None,
1561+
max_delta_step=0,
1562+
subsample=None,
1563+
colsample_bytree=None,
1564+
reg_alpha=None,
1565+
reg_lambda=None,
1566+
boosting_type=None,
1567+
scale_pos_weight=1,
1568+
random_state=None):
1569+
'''Generate LightGBM hyperparameters search space
1570+
'''
1571+
hp_space = dict(
1572+
max_depth=(_lightgbm_max_depth(name_func('max_depth'))
1573+
if max_depth is None else max_depth),
1574+
num_leaves=(_lightgbm_num_leaves(name_func('num_leaves'))
1575+
if num_leaves is None else num_leaves),
1576+
learning_rate=(_lightgbm_learning_rate(name_func('learning_rate'))
1577+
if learning_rate is None else learning_rate),
1578+
n_estimators=(_lightgbm_n_estimators(name_func('n_estimators'))
1579+
if n_estimators is None else n_estimators),
1580+
min_child_weight=(_lightgbm_min_child_weight(name_func('min_child_weight'))
1581+
if min_child_weight is None else min_child_weight),
1582+
max_delta_step=max_delta_step,
1583+
subsample=(_lightgbm_subsample(name_func('subsample'))
1584+
if subsample is None else subsample),
1585+
colsample_bytree=(_lightgbm_colsample_bytree(name_func('colsample_bytree'))
1586+
if colsample_bytree is None else colsample_bytree),
1587+
reg_alpha=(_lightgbm_reg_alpha(name_func('reg_alpha'))
1588+
if reg_alpha is None else reg_alpha),
1589+
reg_lambda=(_lightgbm_reg_lambda(name_func('reg_lambda'))
1590+
if reg_lambda is None else reg_lambda),
1591+
boosting_type=(_lightgbm_boosting_type(name_func('boosting_type'))
1592+
if boosting_type is None else boosting_type),
1593+
scale_pos_weight=scale_pos_weight,
1594+
seed=_random_state(name_func('rstate'), random_state)
1595+
)
1596+
return hp_space
1597+
1598+
########################################################
1599+
##==== LightGBM classifier/regressor constructors ====##
1600+
########################################################
1601+
def lightgbm_classification(name, objective='binary', **kwargs):
1602+
'''
1603+
Return a pyll graph with hyperparameters that will construct
1604+
a lightgbm.LGBMClassifier model.
1605+
1606+
Args:
1607+
objective([str]): choose from ['binary', 'multiclass']
1608+
or provide an hp.choice pyll node
1609+
1610+
See help(hpsklearn.components._lightgbm_hp_space) for info on
1611+
additional available LightGBM arguments.
1612+
'''
1613+
def _name(msg):
1614+
return '%s.%s_%s' % (name, 'lightgbm', msg)
1615+
1616+
hp_space = _lightgbm_hp_space(_name, **kwargs)
1617+
hp_space['objective'] = objective
1618+
return scope.sklearn_LGBMClassifier(**hp_space)
1619+
1620+
1621+
def lightgbm_regression(name, **kwargs):
1622+
'''
1623+
Return a pyll graph with hyperparameters that will construct
1624+
a lightgbm.LightGBMRegressor model.
1625+
1626+
See help(hpsklearn.components._lightgbm_hp_space) for info on
1627+
additional available LightGBM arguments.
1628+
'''
1629+
def _name(msg):
1630+
return '%s.%s_%s' % (name, 'lightgbm_reg', msg)
1631+
1632+
hp_space = _lightgbm_hp_space(_name, **kwargs)
1633+
return scope.sklearn_LGBMRegressor(objective='regression', **hp_space)
1634+
1635+
14981636
#################################################
14991637
##==== Naive Bayes classifiers constructor ====##
15001638
#################################################

hpsklearn/estimator.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -614,15 +614,12 @@ def fit_iter(self, X, y, EX_list=None, valid_size=.2, n_folds=None,
614614
assert weights is None
615615
increment = self.fit_increment if increment is None else increment
616616

617-
# len does not work on sparse matrices, so using shape[0] instead
618-
# shape[0] does not work on lists, so using len() for those
619-
if scipy.sparse.issparse(X):
620-
data_length = X.shape[0]
621-
else:
622-
data_length = len(X)
623-
if type(X) is list:
617+
# Convert list, pandas series, or other array-like to ndarray
618+
# do not convert sparse matrices
619+
if not scipy.sparse.issparse(X) and not isinstance(X, np.ndarray):
624620
X = np.array(X)
625-
if type(y) is list:
621+
622+
if not scipy.sparse.issparse(y) and not isinstance(y, np.ndarray):
626623
y = np.array(y)
627624

628625
if not warm_start:

hpsklearn/tests/test_classification.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,23 @@ def test_classifier(self):
115115
if xgboost is not None:
116116
setattr(
117117
TestClassification,
118-
'test_{0}'.format(clf.__name__),
118+
'test_xgboost_classification',
119119
create_function(components.xgboost_classification)
120120
)
121121

122+
# Only test the lightgbm classifier if the optional dependency is installed
123+
try:
124+
import lightgbm
125+
except ImportError:
126+
lightgbm = None
127+
128+
if lightgbm is not None:
129+
setattr(
130+
TestClassification,
131+
'test_lightgbm_classification',
132+
create_function(components.lightgbm_classification)
133+
)
134+
122135
if __name__ == '__main__':
123136
unittest.main()
124137

hpsklearn/tests/test_regression.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,23 @@ def test_regressor(self):
7171
if xgboost is not None:
7272
setattr(
7373
TestRegression,
74-
'test_{0}'.format(clf.__name__),
74+
'test_xgboost_regression',
7575
create_function(components.xgboost_regression)
7676
)
7777

78+
# Only test the lightgbm regressor if the optional dependency is installed
79+
try:
80+
import lightgbm
81+
except ImportError:
82+
lightgbm = None
83+
84+
if lightgbm is not None:
85+
setattr(
86+
TestRegression,
87+
'test_lightgmb_regression',
88+
create_function(components.lightgbm_regression)
89+
)
90+
7891
if __name__ == '__main__':
7992
unittest.main()
8093

setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
'scipy',
4949
],
5050
extras_require = {
51-
'xgboost': ['xgboost==0.6a2']
51+
'xgboost': ['xgboost==0.6a2'],
52+
'lightgbm': ['lightgbm==2.3.1']
5253
}
5354
)

0 commit comments

Comments
 (0)