Skip to content

Commit 7ae4e85

Browse files
author
Sergey Feldman
committed
lightgbm now with hyperopt
1 parent 2a18688 commit 7ae4e85

File tree

2 files changed

+53
-30
lines changed

2 files changed

+53
-30
lines changed

02_lightgbm.py

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,35 @@
66
import pickle
77
import numpy as np
88
import lightgbm as lgb
9+
from functools import partial
910
from sklearn.model_selection import RandomizedSearchCV
11+
from sklearn.metrics import roc_auc_score
1012
from sklearn.model_selection import cross_val_score, StratifiedKFold
13+
from hyperopt import hp, fmin, tpe, Trials, space_eval
14+
from hyperopt.pyll import scope
1115
from utils import load_data
1216

1317
N_JOBS = 4 * 4 * 9
1418
N_ITER = 25 # budget for hyperparam search
1519

1620

17-
def evaluate_pipeline_helper(X, y, pipeline, param_grid, random_state=0):
18-
inner_cv = StratifiedKFold(n_splits=4, shuffle=True, random_state=random_state)
19-
outer_cv = StratifiedKFold(n_splits=4, shuffle=True, random_state=random_state)
20-
clf = RandomizedSearchCV(
21-
estimator=pipeline,
22-
param_distributions=param_grid,
23-
n_iter=N_ITER,
24-
cv=inner_cv,
25-
scoring="roc_auc_ovr_weighted",
26-
n_jobs=N_JOBS,
27-
random_state=random_state,
28-
verbose=-1,
29-
)
30-
nested_score = cross_val_score(clf, X=X, y=y, cv=outer_cv, scoring="roc_auc_ovr_weighted", n_jobs=N_JOBS)
31-
return nested_score
21+
HYPEROPT_SPACE = {
22+
"learning_rate": hp.choice("learning_rate", [0.1, 0.05, 0.01, 0.005, 0.001]),
23+
"num_leaves": scope.int(2 ** hp.quniform("num_leaves", 2, 7, 1)),
24+
"colsample_bytree": hp.quniform("colsample_bytree", 0.4, 1, 0.1),
25+
"subsample": hp.quniform("subsample", 0.4, 1, 0.1),
26+
"min_child_samples": scope.int(2 ** hp.quniform("min_child_samples", 0, 7, 1)),
27+
"min_child_weight": 10 ** hp.quniform("min_child_weight", -6, 0, 1),
28+
"reg_alpha": hp.choice("reg_alpha", [0, 10 ** hp.quniform("reg_alpha_pos", -6, 1, 1)]),
29+
"reg_lambda": hp.choice("reg_lambda", [0, 10 ** hp.quniform("reg_lambda_pos", -6, 1, 1)]),
30+
"max_depth": scope.int(hp.choice("max_depth", [-1, 2 ** hp.quniform("max_depth_pos", 1, 4, 1)])),
31+
}
3232

3333

3434
def define_and_evaluate_lightgbm_pipeline(X, y, random_state=0):
35-
if len(set(y)) == 2:
36-
pipeline = lgb.LGBMClassifier(
35+
binary = len(set(y)) == 2
36+
if binary:
37+
lgb_model = lgb.LGBMClassifier(
3738
objective="binary",
3839
n_estimators=500,
3940
metric="auc",
@@ -43,7 +44,7 @@ def define_and_evaluate_lightgbm_pipeline(X, y, random_state=0):
4344
silent=True,
4445
)
4546
else:
46-
pipeline = lgb.LGBMClassifier(
47+
lgb_model = lgb.LGBMClassifier(
4748
objective="multiclass",
4849
n_estimators=500,
4950
metric="auc_mu",
@@ -52,18 +53,40 @@ def define_and_evaluate_lightgbm_pipeline(X, y, random_state=0):
5253
random_state=random_state,
5354
silent=True,
5455
)
55-
param_grid = {
56-
"learning_rate": [1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0],
57-
"num_leaves": [2, 4, 8, 16, 32, 64],
58-
"colsample_bytree": [0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
59-
"subsample": [0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
60-
"min_child_samples": [2, 4, 8, 16, 32, 64, 128, 256],
61-
"min_child_weight": [1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0],
62-
"reg_alpha": [1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0],
63-
"reg_lambda": [1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0],
64-
"max_depth": [1, 2, 4, 8, 16, 32, -1],
65-
}
66-
nested_scores = evaluate_pipeline_helper(X, y, pipeline, param_grid, random_state=random_state)
56+
nested_scores = []
57+
outer_cv = StratifiedKFold(n_splits=4, shuffle=True, random_state=random_state)
58+
for train_inds, test_inds in outer_cv.split(X, y):
59+
X_train, y_train = X[train_inds, :], y[train_inds]
60+
X_test, y_test = X[test_inds, :], y[test_inds]
61+
62+
def obj(params):
63+
lgb_model.set_params(**params)
64+
inner_cv = StratifiedKFold(n_splits=4, shuffle=True, random_state=random_state)
65+
scores = cross_val_score(
66+
lgb_model, X=X_train, y=y_train, cv=inner_cv, scoring="roc_auc_ovr_weighted", n_jobs=N_JOBS
67+
)
68+
return -np.mean(scores)
69+
70+
trials = Trials()
71+
_ = fmin(
72+
fn=obj,
73+
space=HYPEROPT_SPACE,
74+
algo=partial(tpe.suggest, n_startup_jobs=5),
75+
max_evals=N_ITER,
76+
trials=trials,
77+
rstate=np.random.RandomState(random_state),
78+
)
79+
# hyperopt has some problems with hp.choice so we need to do this:
80+
best_params = space_eval(HYPEROPT_SPACE, trials.argmin)
81+
lgb_model.set_params(**best_params)
82+
lgb_model.fit(X_train, y_train)
83+
y_pred = lgb_model.predict_proba(X_test)
84+
# same as roc_auc_ovr_weighted
85+
if binary:
86+
score = roc_auc_score(y_test, y_pred[:, 1], average="weighted", multi_class="ovr")
87+
else:
88+
score = roc_auc_score(y_test, y_pred, average="weighted", multi_class="ovr")
89+
nested_scores.append(score)
6790
return nested_scores
6891

6992

-13 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)