PineBioML 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PineBioML/IO/__init__.py +158 -0
- PineBioML/__init__.py +0 -0
- PineBioML/model/__init__.py +0 -0
- PineBioML/model/supervised/Classification.py +989 -0
- PineBioML/model/supervised/Regression.py +783 -0
- PineBioML/model/supervised/Survival.py +1 -0
- PineBioML/model/supervised/__init__.py +414 -0
- PineBioML/model/utils.py +393 -0
- PineBioML/preprocessing/__init__.py +168 -0
- PineBioML/preprocessing/bagging.py +221 -0
- PineBioML/preprocessing/impute.py +143 -0
- PineBioML/preprocessing/utils.py +161 -0
- PineBioML/report/__init__.py +0 -0
- PineBioML/report/utils.py +763 -0
- PineBioML/selection/Volcano.py +201 -0
- PineBioML/selection/__init__.py +145 -0
- PineBioML/selection/classification.py +836 -0
- PineBioML/selection/regression.py +737 -0
- PineBioML-1.2.0.dist-info/LICENSE +21 -0
- PineBioML-1.2.0.dist-info/METADATA +148 -0
- PineBioML-1.2.0.dist-info/RECORD +23 -0
- PineBioML-1.2.0.dist-info/WHEEL +5 -0
- PineBioML-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,989 @@
|
|
|
1
|
+
from . import Basic_tuner
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from joblib import parallel_backend
|
|
6
|
+
|
|
7
|
+
from sklearn.model_selection import StratifiedKFold
|
|
8
|
+
from sklearn.utils.class_weight import compute_sample_weight
|
|
9
|
+
from sklearn.svm import SVC
|
|
10
|
+
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
|
|
11
|
+
from sklearn.tree import DecisionTreeClassifier
|
|
12
|
+
from statsmodels.discrete.discrete_model import Logit
|
|
13
|
+
from sklearn.linear_model import LogisticRegression
|
|
14
|
+
from xgboost import XGBClassifier
|
|
15
|
+
from lightgbm import LGBMClassifier
|
|
16
|
+
from catboost import CatBoostClassifier, Pool
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
from pandas import DataFrame
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Classification_tuner(Basic_tuner):
|
|
23
|
+
"""
|
|
24
|
+
A subclass of Basic_tuner for classification task.
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self,
|
|
29
|
+
n_try,
|
|
30
|
+
n_cv,
|
|
31
|
+
target,
|
|
32
|
+
validate_penalty,
|
|
33
|
+
kernel_seed=None,
|
|
34
|
+
valid_seed=None,
|
|
35
|
+
optuna_seed=None):
|
|
36
|
+
super().__init__(n_try=n_try,
|
|
37
|
+
n_cv=n_cv,
|
|
38
|
+
target=target,
|
|
39
|
+
validate_penalty=validate_penalty,
|
|
40
|
+
kernel_seed=kernel_seed,
|
|
41
|
+
valid_seed=valid_seed,
|
|
42
|
+
optuna_seed=optuna_seed)
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
n_try (int): The number of trials optuna should try.
|
|
47
|
+
n_cv (int): The number of folds to execute cross validation evaluation in iteration of optuna optimization.
|
|
48
|
+
target (str): The target of optuna optimization. Notice that is different from the training loss of model.
|
|
49
|
+
validate_penalty (bool): True to penalty the overfitting by difference between training score and cv score.
|
|
50
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
51
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
52
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def is_regression(self) -> bool:
|
|
56
|
+
"""
|
|
57
|
+
No, this is not a regresion tuner or for regresion task.
|
|
58
|
+
Returns:
|
|
59
|
+
bool: False
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
def reference(self) -> dict[str, str]:
|
|
65
|
+
"""
|
|
66
|
+
This function will return reference of this method in python dict.
|
|
67
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
dict[str, str]: a dict of reference.
|
|
71
|
+
"""
|
|
72
|
+
return super().reference()
|
|
73
|
+
|
|
74
|
+
@abstractmethod
|
|
75
|
+
def name(self) -> str:
|
|
76
|
+
"""
|
|
77
|
+
To be determined.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
str: Name of this tuner.
|
|
81
|
+
"""
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
@abstractmethod
|
|
85
|
+
def create_model(self, trial, default):
|
|
86
|
+
"""
|
|
87
|
+
Create model based on default setting or optuna trial
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
trial (optuna.trial.Trial): optuna trial in this call.
|
|
91
|
+
default (bool): To use default hyper parameter
|
|
92
|
+
|
|
93
|
+
Returns :
|
|
94
|
+
sklearn.base.BaseEstimator: A sklearn style model object.
|
|
95
|
+
"""
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
def predict_proba(self, x):
|
|
99
|
+
"""
|
|
100
|
+
The sklearn.base.BaseEstimator predict_prob api.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
x (pandas.DataFrame): feature to extract information from.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
pd.DataFrame: prediction in prob, an array with shape (n_samples, n_classes)
|
|
107
|
+
"""
|
|
108
|
+
return DataFrame(self.best_model.predict_proba(x),
|
|
109
|
+
index=x.index,
|
|
110
|
+
columns=self.y_mapping.classes_)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# linear model, elasticnet
|
|
114
|
+
class ElasticLogit_tuner(Classification_tuner):
|
|
115
|
+
"""
|
|
116
|
+
Tuning a elasic net logistic regression.
|
|
117
|
+
[sklearn.linear_model.LogisticRegression](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression), reminds the choice of the algorithm depends on the penalty chosen and on (multinomial) multiclass support.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
def __init__(self,
|
|
121
|
+
n_try=25,
|
|
122
|
+
n_cv=5,
|
|
123
|
+
target="mcc",
|
|
124
|
+
kernel_seed: int = None,
|
|
125
|
+
valid_seed: int = None,
|
|
126
|
+
optuna_seed: int = None,
|
|
127
|
+
validate_penalty=True):
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
n_try (int, optional): The number of trials optuna should try. Defaults to 25.
|
|
132
|
+
n_cv (int, optional): The number of folds to execute cross validation evaluation in iteration of optuna optimization. Defaults to 5.
|
|
133
|
+
target (str, optional): The target of optuna optimization. Notice that is different from the training loss of model. Defaults to "mcc".
|
|
134
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
135
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
136
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
137
|
+
validate_penalty (bool, optional): True to penalty the overfitting by difference between training score and cv score. Defaults to True.
|
|
138
|
+
"""
|
|
139
|
+
super().__init__(n_try=n_try,
|
|
140
|
+
n_cv=n_cv,
|
|
141
|
+
target=target,
|
|
142
|
+
kernel_seed=kernel_seed,
|
|
143
|
+
valid_seed=valid_seed,
|
|
144
|
+
optuna_seed=optuna_seed,
|
|
145
|
+
validate_penalty=validate_penalty)
|
|
146
|
+
|
|
147
|
+
# "saga" fast convergence is only guaranteed on features with approximately the same scale. You should do a feature-wise (between sample) normalization before fitting.
|
|
148
|
+
self.kernel = "saga"
|
|
149
|
+
self.penalty = "elasticnet"
|
|
150
|
+
|
|
151
|
+
def name(self):
|
|
152
|
+
return "ElasticNetLogisticRegression"
|
|
153
|
+
|
|
154
|
+
def reference(self) -> dict[str, str]:
|
|
155
|
+
"""
|
|
156
|
+
This function will return reference of this method in python dict.
|
|
157
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
dict[str, str]: a dict of reference.
|
|
161
|
+
"""
|
|
162
|
+
refer = super().reference()
|
|
163
|
+
refer[
|
|
164
|
+
self.name() +
|
|
165
|
+
" document"] = "https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html"
|
|
166
|
+
return refer
|
|
167
|
+
|
|
168
|
+
def create_model(self, trial, default=False):
|
|
169
|
+
if default:
|
|
170
|
+
parms = {
|
|
171
|
+
"C": 1.0,
|
|
172
|
+
"l1_ratio": 0.5,
|
|
173
|
+
"penalty": self.penalty,
|
|
174
|
+
"solver": self.kernel,
|
|
175
|
+
"random_state": self.kernel_seed_tape[trial.number],
|
|
176
|
+
"verbose": 0
|
|
177
|
+
}
|
|
178
|
+
else:
|
|
179
|
+
parms = {
|
|
180
|
+
"C": trial.suggest_float('C', 1e-6, 1e+2, log=True),
|
|
181
|
+
"l1_ratio": trial.suggest_float('l1_ratio', 0, 1),
|
|
182
|
+
"penalty": self.penalty,
|
|
183
|
+
"solver": self.kernel,
|
|
184
|
+
"random_state": self.kernel_seed_tape[trial.number],
|
|
185
|
+
"verbose": 0,
|
|
186
|
+
}
|
|
187
|
+
lg = LogisticRegression(**parms)
|
|
188
|
+
return lg
|
|
189
|
+
|
|
190
|
+
def summary(self):
|
|
191
|
+
"""
|
|
192
|
+
It is the way I found to cram a sklearn regression result into the statsmodel regresion.
|
|
193
|
+
The only reason to do this is that statsmodel provides R-style summary.
|
|
194
|
+
"""
|
|
195
|
+
if len(self.best_model.classes_) > 2:
|
|
196
|
+
# multi-class classification
|
|
197
|
+
# Todo
|
|
198
|
+
raise TypeError(
|
|
199
|
+
"multi-class classification summary not support yet. Please tell me why do you need that in a multi-class classification task"
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
# binary classification
|
|
203
|
+
sm_logit = Logit(self.y, self.x).fit(
|
|
204
|
+
disp=False,
|
|
205
|
+
start_params=self.best_model.coef_.flatten(),
|
|
206
|
+
maxiter=0,
|
|
207
|
+
warn_convergence=False)
|
|
208
|
+
print(sm_logit.summary())
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# RF
|
|
212
|
+
class RandomForest_tuner(Classification_tuner):
|
|
213
|
+
"""
|
|
214
|
+
Tuning a random forest model.
|
|
215
|
+
[sklearn.ensemble.RandomForestClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html)
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
def __init__(self,
|
|
219
|
+
using_oob=True,
|
|
220
|
+
n_try=50,
|
|
221
|
+
n_cv=5,
|
|
222
|
+
target="mcc",
|
|
223
|
+
kernel_seed=None,
|
|
224
|
+
valid_seed=None,
|
|
225
|
+
optuna_seed=None,
|
|
226
|
+
validate_penalty=True):
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
using_oob (bool, optional): Using out of bag score as validation. Defaults to True.
|
|
231
|
+
n_try (int, optional): The number of trials optuna should try. Defaults to 50.
|
|
232
|
+
n_cv (int, optional): The number of folds to execute cross validation evaluation in iteration of optuna optimization. Defaults to 5.
|
|
233
|
+
target (str, optional): The target of optuna optimization. Notice that is different from the training loss of model. Defaults to "mcc".
|
|
234
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
235
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
236
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
237
|
+
validate_penalty (bool, optional): True to penalty the overfitting by difference between training score and cv score. Defaults to True.
|
|
238
|
+
"""
|
|
239
|
+
super().__init__(n_try=n_try,
|
|
240
|
+
n_cv=n_cv,
|
|
241
|
+
target=target,
|
|
242
|
+
kernel_seed=kernel_seed,
|
|
243
|
+
valid_seed=valid_seed,
|
|
244
|
+
optuna_seed=optuna_seed,
|
|
245
|
+
validate_penalty=validate_penalty)
|
|
246
|
+
|
|
247
|
+
self.using_oob = using_oob
|
|
248
|
+
|
|
249
|
+
def name(self):
|
|
250
|
+
return "RandomForest"
|
|
251
|
+
|
|
252
|
+
def reference(self) -> dict[str, str]:
|
|
253
|
+
"""
|
|
254
|
+
This function will return reference of this method in python dict.
|
|
255
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
dict[str, str]: a dict of reference.
|
|
259
|
+
"""
|
|
260
|
+
refer = super().reference()
|
|
261
|
+
refer[
|
|
262
|
+
self.name() +
|
|
263
|
+
" document"] = "https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html"
|
|
264
|
+
refer[
|
|
265
|
+
self.name() +
|
|
266
|
+
" publication"] = "https://www.stat.berkeley.edu/~breiman/randomforest2001.pdf"
|
|
267
|
+
|
|
268
|
+
return refer
|
|
269
|
+
|
|
270
|
+
def create_model(self, trial, default=False):
|
|
271
|
+
if default:
|
|
272
|
+
parms = {
|
|
273
|
+
"bootstrap": self.using_oob,
|
|
274
|
+
"oob_score": self.using_oob,
|
|
275
|
+
"n_jobs": -1,
|
|
276
|
+
"random_state": self.kernel_seed_tape[trial.number],
|
|
277
|
+
"verbose": 0,
|
|
278
|
+
}
|
|
279
|
+
else:
|
|
280
|
+
parms = {
|
|
281
|
+
"n_estimators":
|
|
282
|
+
trial.suggest_int('n_estimators', 32, 1024, log=True),
|
|
283
|
+
"min_samples_leaf":
|
|
284
|
+
trial.suggest_int('min_samples_leaf', 1, 32, log=True),
|
|
285
|
+
"ccp_alpha":
|
|
286
|
+
trial.suggest_float('ccp_alpha', 1e-4, 1e-1, log=True),
|
|
287
|
+
"max_samples":
|
|
288
|
+
trial.suggest_float('max_samples', 0.5, 0.9, log=True),
|
|
289
|
+
"bootstrap":
|
|
290
|
+
self.using_oob,
|
|
291
|
+
"oob_score":
|
|
292
|
+
self.using_oob,
|
|
293
|
+
"n_jobs":
|
|
294
|
+
-1,
|
|
295
|
+
"random_state":
|
|
296
|
+
self.kernel_seed_tape[trial.number],
|
|
297
|
+
"verbose":
|
|
298
|
+
0,
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
rf = RandomForestClassifier(**parms)
|
|
302
|
+
return rf
|
|
303
|
+
|
|
304
|
+
def evaluate(self, trial, default=False):
|
|
305
|
+
"""
|
|
306
|
+
RF needs oob and we have it.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
trial (optuna.trial.Trial): optuna trial in this call.
|
|
310
|
+
default (bool): To use default hyper parameter. This argument will be passed to creat_model
|
|
311
|
+
Returns :
|
|
312
|
+
float: The score.
|
|
313
|
+
"""
|
|
314
|
+
classifier_obj = self.create_model(trial, default)
|
|
315
|
+
|
|
316
|
+
if self.using_oob:
|
|
317
|
+
# oob predict
|
|
318
|
+
# there is a bug that default sklaern randomforest parallel_backend using thread where others use "loky", see joblib.parallel_backend.
|
|
319
|
+
with parallel_backend('loky'):
|
|
320
|
+
classifier_obj.fit(self.x,
|
|
321
|
+
self.y,
|
|
322
|
+
sample_weight=compute_sample_weight(
|
|
323
|
+
class_weight="balanced", y=self.y))
|
|
324
|
+
|
|
325
|
+
# oob prediction
|
|
326
|
+
y_pred = classifier_obj.oob_decision_function_
|
|
327
|
+
if self.metric_name == "roc_auc":
|
|
328
|
+
# roc_auc can only be used on binary classification. Do not try ovr, ovo. forget them.
|
|
329
|
+
y_pred = y_pred[:, 1]
|
|
330
|
+
|
|
331
|
+
# oob score
|
|
332
|
+
### manual scorer wraper.
|
|
333
|
+
if self.metric_using_proba:
|
|
334
|
+
score = self.metric._score_func(self.y, y_pred,
|
|
335
|
+
**self.scorer_kargs)
|
|
336
|
+
else:
|
|
337
|
+
# revert to class symbols.
|
|
338
|
+
y_pred = classifier_obj.classes_[y_pred.argmax(axis=-1)]
|
|
339
|
+
score = self.metric._score_func(self.y, y_pred,
|
|
340
|
+
**self.scorer_kargs)
|
|
341
|
+
if not self.metric_great_better:
|
|
342
|
+
# if not great is better, then multiply -1
|
|
343
|
+
score *= -1
|
|
344
|
+
else:
|
|
345
|
+
# cv score
|
|
346
|
+
cv = StratifiedKFold(
|
|
347
|
+
n_splits=self.n_cv,
|
|
348
|
+
shuffle=True,
|
|
349
|
+
random_state=self.valid_seed_tape[trial.number])
|
|
350
|
+
|
|
351
|
+
score = []
|
|
352
|
+
for i, (train_ind, test_ind) in enumerate(cv.split(self.x,
|
|
353
|
+
self.y)):
|
|
354
|
+
x_train = self.x.iloc[train_ind]
|
|
355
|
+
y_train = self.y.iloc[train_ind]
|
|
356
|
+
x_test = self.x.iloc[test_ind]
|
|
357
|
+
y_test = self.y.iloc[test_ind]
|
|
358
|
+
|
|
359
|
+
with parallel_backend('loky'):
|
|
360
|
+
classifier_obj.fit(x_train,
|
|
361
|
+
y_train,
|
|
362
|
+
sample_weight=compute_sample_weight(
|
|
363
|
+
class_weight="balanced", y=y_train))
|
|
364
|
+
|
|
365
|
+
test_score = self.metric(classifier_obj, x_test, y_test)
|
|
366
|
+
train_score = self.metric(classifier_obj, x_train, y_train)
|
|
367
|
+
if self.validate_penalty:
|
|
368
|
+
score.append(test_score + 0.1 * (test_score - train_score))
|
|
369
|
+
else:
|
|
370
|
+
score.append(test_score)
|
|
371
|
+
|
|
372
|
+
score = sum(score) / self.n_cv
|
|
373
|
+
return score
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
# SVM
|
|
377
|
+
class SVM_tuner(Classification_tuner):
|
|
378
|
+
"""
|
|
379
|
+
Tuning a support vector machine.
|
|
380
|
+
[sklearn.svm.SVC](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html)
|
|
381
|
+
"""
|
|
382
|
+
|
|
383
|
+
def __init__(self,
|
|
384
|
+
kernel: Literal["linear", "poly", "rbf", "sigmoid"] = "rbf",
|
|
385
|
+
n_try=25,
|
|
386
|
+
n_cv=5,
|
|
387
|
+
target="mcc",
|
|
388
|
+
kernel_seed=None,
|
|
389
|
+
valid_seed=None,
|
|
390
|
+
optuna_seed=None,
|
|
391
|
+
validate_penalty=True):
|
|
392
|
+
"""
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
kernel (Literal["linear", "poly", "rbf", "sigmoid"], optional): This will be passed to the attribute of SVC: "kernel". Defaults to "rbf".
|
|
396
|
+
n_try (int, optional): The number of trials optuna should try. Defaults to 25.
|
|
397
|
+
n_cv (int, optional): The number of folds to execute cross validation evaluation in iteration of optuna optimization. Defaults to 5.
|
|
398
|
+
target (str, optional): The target of optuna optimization. Notice that is different from the training loss of model. Defaults to "mcc".
|
|
399
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
400
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
401
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
402
|
+
validate_penalty (bool, optional): True to penalty the overfitting by difference between training score and cv score. Defaults to True.
|
|
403
|
+
"""
|
|
404
|
+
super().__init__(n_try=n_try,
|
|
405
|
+
n_cv=n_cv,
|
|
406
|
+
target=target,
|
|
407
|
+
kernel_seed=kernel_seed,
|
|
408
|
+
valid_seed=valid_seed,
|
|
409
|
+
optuna_seed=optuna_seed,
|
|
410
|
+
validate_penalty=validate_penalty)
|
|
411
|
+
self.kernel = kernel # rbf, linear, poly, sigmoid
|
|
412
|
+
|
|
413
|
+
def name(self):
|
|
414
|
+
return self.kernel + "-SVM"
|
|
415
|
+
|
|
416
|
+
def reference(self) -> dict[str, str]:
|
|
417
|
+
"""
|
|
418
|
+
This function will return reference of this method in python dict.
|
|
419
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
420
|
+
|
|
421
|
+
Returns:
|
|
422
|
+
dict[str, str]: a dict of reference.
|
|
423
|
+
"""
|
|
424
|
+
refer = super().reference()
|
|
425
|
+
refer[
|
|
426
|
+
self.name() +
|
|
427
|
+
" document"] = "https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html"
|
|
428
|
+
refer[
|
|
429
|
+
self.name() +
|
|
430
|
+
" publication"] = "https://citeseerx.ist.psu.edu/doc_view/pid/42e5ed832d4310ce4378c44d05570439df28a393"
|
|
431
|
+
|
|
432
|
+
return refer
|
|
433
|
+
|
|
434
|
+
def create_model(self, trial, default=False):
|
|
435
|
+
if default:
|
|
436
|
+
parms = {
|
|
437
|
+
"kernel": self.kernel,
|
|
438
|
+
"random_state": self.kernel_seed_tape[trial.number],
|
|
439
|
+
"probability": True
|
|
440
|
+
}
|
|
441
|
+
else:
|
|
442
|
+
# scaling penalty: https://scikit-learn.org/stable/auto_examples/svm/plot_svm_scale_c.html#sphx-glr-auto-examples-svm-plot-svm-scale-c-py
|
|
443
|
+
parms = {
|
|
444
|
+
"C":
|
|
445
|
+
trial.suggest_float('C',
|
|
446
|
+
1e-4 * np.sqrt(self.n_sample),
|
|
447
|
+
1e+2 * np.sqrt(self.n_sample),
|
|
448
|
+
log=True),
|
|
449
|
+
"gamma":
|
|
450
|
+
"auto",
|
|
451
|
+
"kernel":
|
|
452
|
+
self.kernel,
|
|
453
|
+
"random_state":
|
|
454
|
+
self.kernel_seed_tape[trial.number],
|
|
455
|
+
"probability":
|
|
456
|
+
True
|
|
457
|
+
}
|
|
458
|
+
svm = SVC(**parms)
|
|
459
|
+
return svm
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
# Todo: learning rate and number of iteration adjustment
|
|
463
|
+
# XGboost
|
|
464
|
+
class XGBoost_tuner(Classification_tuner):
|
|
465
|
+
"""
|
|
466
|
+
Tuning a XGBoost classifier model.
|
|
467
|
+
[xgboost.XGBClassifier](https://xgboost.readthedocs.io/en/stable/python/python_api.html)
|
|
468
|
+
|
|
469
|
+
ToDo:
|
|
470
|
+
1. sample imbalance. (we have temporary solution)
|
|
471
|
+
2. early stop.
|
|
472
|
+
3. efficiency (optuna.integration.XGBoostPruningCallback).
|
|
473
|
+
|
|
474
|
+
"""
|
|
475
|
+
|
|
476
|
+
def __init__(self,
|
|
477
|
+
n_try=75,
|
|
478
|
+
n_cv=5,
|
|
479
|
+
target="mcc",
|
|
480
|
+
kernel_seed=None,
|
|
481
|
+
valid_seed=None,
|
|
482
|
+
optuna_seed=None,
|
|
483
|
+
validate_penalty=True):
|
|
484
|
+
"""
|
|
485
|
+
|
|
486
|
+
Args:
|
|
487
|
+
n_try (int, optional): The number of trials optuna should try. Defaults to 75.
|
|
488
|
+
n_cv (int, optional): The number of folds to execute cross validation evaluation in iteration of optuna optimization. Defaults to 5.
|
|
489
|
+
target (str, optional): The target of optuna optimization. Notice that is different from the training loss of model. Defaults to "mcc".
|
|
490
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
491
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
492
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
493
|
+
validate_penalty (bool, optional): True to penalty the overfitting by difference between training score and cv score. Defaults to True.
|
|
494
|
+
|
|
495
|
+
"""
|
|
496
|
+
super().__init__(n_try=n_try,
|
|
497
|
+
n_cv=n_cv,
|
|
498
|
+
target=target,
|
|
499
|
+
kernel_seed=kernel_seed,
|
|
500
|
+
valid_seed=valid_seed,
|
|
501
|
+
optuna_seed=optuna_seed,
|
|
502
|
+
validate_penalty=validate_penalty)
|
|
503
|
+
|
|
504
|
+
def name(self):
|
|
505
|
+
return "XGBoost"
|
|
506
|
+
|
|
507
|
+
def reference(self) -> dict[str, str]:
|
|
508
|
+
"""
|
|
509
|
+
This function will return reference of this method in python dict.
|
|
510
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
511
|
+
|
|
512
|
+
Returns:
|
|
513
|
+
dict[str, str]: a dict of reference.
|
|
514
|
+
"""
|
|
515
|
+
refer = super().reference()
|
|
516
|
+
refer[self.name() +
|
|
517
|
+
" document"] = "https://xgboost.readthedocs.io/en/stable/"
|
|
518
|
+
refer[
|
|
519
|
+
self.name() +
|
|
520
|
+
" publication"] = "https://dl.acm.org/doi/10.1145/2939672.2939785"
|
|
521
|
+
|
|
522
|
+
return refer
|
|
523
|
+
|
|
524
|
+
def create_model(self, trial, default=False):
|
|
525
|
+
if default:
|
|
526
|
+
parms = {
|
|
527
|
+
"n_jobs": None,
|
|
528
|
+
"random_state": self.kernel_seed_tape[trial.number],
|
|
529
|
+
"verbosity": 0
|
|
530
|
+
}
|
|
531
|
+
else:
|
|
532
|
+
if trial.suggest_categorical("use_subsample", [True, False]):
|
|
533
|
+
sampling_rate = trial.suggest_float('subsample',
|
|
534
|
+
0.5,
|
|
535
|
+
0.9,
|
|
536
|
+
log=True)
|
|
537
|
+
col_sampling_rate = trial.suggest_float(
|
|
538
|
+
'colsample_bytree', 0.1, 0.9)
|
|
539
|
+
else:
|
|
540
|
+
sampling_rate = 1.
|
|
541
|
+
col_sampling_rate = 1.
|
|
542
|
+
|
|
543
|
+
parms = {
|
|
544
|
+
"n_estimators":
|
|
545
|
+
trial.suggest_int('n_estimators', 16, 256, log=True),
|
|
546
|
+
"max_depth":
|
|
547
|
+
trial.suggest_int('max_depth', 2, 16, log=True),
|
|
548
|
+
"gamma":
|
|
549
|
+
trial.suggest_float('gamma', 5e-2, 2e+1, log=True),
|
|
550
|
+
"learning_rate":
|
|
551
|
+
trial.suggest_float('learning_rate', 5e-2, 5e-1, log=True),
|
|
552
|
+
"subsample":
|
|
553
|
+
sampling_rate,
|
|
554
|
+
"colsample_bytree":
|
|
555
|
+
col_sampling_rate,
|
|
556
|
+
"reg_lambda":
|
|
557
|
+
trial.suggest_float('reg_lambda', 1e-2, 1e+1, log=True),
|
|
558
|
+
"n_jobs":
|
|
559
|
+
None,
|
|
560
|
+
"random_state":
|
|
561
|
+
self.kernel_seed_tape[trial.number],
|
|
562
|
+
"verbosity":
|
|
563
|
+
0,
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
xgb = XGBClassifier(**parms)
|
|
567
|
+
return xgb
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
# lightGBM
|
|
571
|
+
class LighGBM_tuner(Classification_tuner):
|
|
572
|
+
"""
|
|
573
|
+
Tuning a LighGBM classifier model.
|
|
574
|
+
[lightgbm.LGBMClassifier](https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMClassifier.html)
|
|
575
|
+
|
|
576
|
+
ToDo:
|
|
577
|
+
1. compare with optuna.integration.lightgbm.LightGBMTuner
|
|
578
|
+
"""
|
|
579
|
+
|
|
580
|
+
def __init__(self,
|
|
581
|
+
n_try=75,
|
|
582
|
+
n_cv=5,
|
|
583
|
+
target="mcc",
|
|
584
|
+
kernel_seed=None,
|
|
585
|
+
valid_seed=None,
|
|
586
|
+
optuna_seed=None,
|
|
587
|
+
validate_penalty=True):
|
|
588
|
+
"""
|
|
589
|
+
|
|
590
|
+
Args:
|
|
591
|
+
n_try (int, optional): The number of trials optuna should try. Defaults to 75.
|
|
592
|
+
n_cv (int, optional): The number of folds to execute cross validation evaluation in iteration of optuna optimization. Defaults to 5.
|
|
593
|
+
target (str, optional): The target of optuna optimization. Notice that is different from the training loss of model. Defaults to "mcc".
|
|
594
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
595
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
596
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
597
|
+
validate_penalty (bool, optional): True to penalty the overfitting by difference between training score and cv score. Defaults to True.
|
|
598
|
+
"""
|
|
599
|
+
super().__init__(n_try=n_try,
|
|
600
|
+
n_cv=n_cv,
|
|
601
|
+
target=target,
|
|
602
|
+
kernel_seed=kernel_seed,
|
|
603
|
+
valid_seed=valid_seed,
|
|
604
|
+
optuna_seed=optuna_seed,
|
|
605
|
+
validate_penalty=validate_penalty)
|
|
606
|
+
|
|
607
|
+
def name(self):
|
|
608
|
+
return "LightGBM"
|
|
609
|
+
|
|
610
|
+
def reference(self) -> dict[str, str]:
|
|
611
|
+
"""
|
|
612
|
+
This function will return reference of this method in python dict.
|
|
613
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
614
|
+
|
|
615
|
+
Returns:
|
|
616
|
+
dict[str, str]: a dict of reference.
|
|
617
|
+
"""
|
|
618
|
+
refer = super().reference()
|
|
619
|
+
refer[
|
|
620
|
+
self.name() +
|
|
621
|
+
" document"] = "https://lightgbm.readthedocs.io/en/latest/index.html"
|
|
622
|
+
refer[
|
|
623
|
+
self.name() +
|
|
624
|
+
" publication"] = "https://proceedings.neurips.cc/paper_files/paper/2017/file/6449f44a102fde848669bdd9eb6b76fa-Paper.pdf"
|
|
625
|
+
|
|
626
|
+
return refer
|
|
627
|
+
|
|
628
|
+
def create_model(self, trial, default=False):
|
|
629
|
+
if default:
|
|
630
|
+
parms = {
|
|
631
|
+
"n_jobs": None,
|
|
632
|
+
"random_state": self.kernel_seed,
|
|
633
|
+
"verbosity": -1
|
|
634
|
+
}
|
|
635
|
+
else:
|
|
636
|
+
depth = trial.suggest_float('max_depth', 3, 16, log=True)
|
|
637
|
+
leaves = trial.suggest_float('num_leaves',
|
|
638
|
+
depth * 2 / 3,
|
|
639
|
+
depth,
|
|
640
|
+
log=True)
|
|
641
|
+
depth = int(np.rint(depth))
|
|
642
|
+
leaves = int(np.floor(np.power(2, leaves)))
|
|
643
|
+
|
|
644
|
+
if trial.suggest_categorical("use_subsample", [True, False]):
|
|
645
|
+
sampling_rate = trial.suggest_float('subsample',
|
|
646
|
+
0.5,
|
|
647
|
+
0.9,
|
|
648
|
+
log=True)
|
|
649
|
+
col_sampling_rate = trial.suggest_float(
|
|
650
|
+
'colsample_bytree', 0.1, 0.9)
|
|
651
|
+
else:
|
|
652
|
+
sampling_rate = 1.
|
|
653
|
+
col_sampling_rate = 1.
|
|
654
|
+
|
|
655
|
+
parms = {
|
|
656
|
+
"n_estimators":
|
|
657
|
+
trial.suggest_int('n_estimators', 16, 256, log=True),
|
|
658
|
+
"max_depth":
|
|
659
|
+
depth,
|
|
660
|
+
"num_leaves":
|
|
661
|
+
leaves,
|
|
662
|
+
"learning_rate":
|
|
663
|
+
trial.suggest_float('learning_rate', 1e-2, 1, log=True),
|
|
664
|
+
"subsample_freq":
|
|
665
|
+
1,
|
|
666
|
+
"subsample":
|
|
667
|
+
sampling_rate,
|
|
668
|
+
"colsample_bytree":
|
|
669
|
+
col_sampling_rate,
|
|
670
|
+
"min_child_samples":
|
|
671
|
+
trial.suggest_int('min_child_samples', 2, 32, log=True),
|
|
672
|
+
"reg_lambda":
|
|
673
|
+
trial.suggest_float('reg_lambda', 5e-3, 1e+1, log=True),
|
|
674
|
+
"n_jobs":
|
|
675
|
+
None,
|
|
676
|
+
"random_state":
|
|
677
|
+
self.kernel_seed_tape[trial.number],
|
|
678
|
+
"verbosity":
|
|
679
|
+
-1,
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
lgbm = LGBMClassifier(**parms)
|
|
683
|
+
return lgbm
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
# Adaboost
|
|
687
|
+
class AdaBoost_tuner(Classification_tuner):
|
|
688
|
+
"""
|
|
689
|
+
Tuning a AdaBoost calssifier.
|
|
690
|
+
[sklearn.ensemble.AdaBoostClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html)
|
|
691
|
+
"""
|
|
692
|
+
|
|
693
|
+
def __init__(self,
|
|
694
|
+
n_try=25,
|
|
695
|
+
n_cv=5,
|
|
696
|
+
target="mcc",
|
|
697
|
+
kernel_seed=None,
|
|
698
|
+
valid_seed=None,
|
|
699
|
+
optuna_seed=None,
|
|
700
|
+
validate_penalty=True):
|
|
701
|
+
"""
|
|
702
|
+
Args:
|
|
703
|
+
n_try (int, optional): The number of trials optuna should try. Defaults to 25.
|
|
704
|
+
n_cv (int, optional): The number of folds to execute cross validation evaluation in iteration of optuna optimization. Defaults to 5.
|
|
705
|
+
target (str, optional): The target of optuna optimization. Notice that is different from the training loss of model. Defaults to "mcc".
|
|
706
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
707
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
708
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
709
|
+
validate_penalty (bool, optional): True to penalty the overfitting by difference between training score and cv score. Defaults to True.
|
|
710
|
+
"""
|
|
711
|
+
super().__init__(n_try=n_try,
|
|
712
|
+
n_cv=n_cv,
|
|
713
|
+
target=target,
|
|
714
|
+
kernel_seed=kernel_seed,
|
|
715
|
+
valid_seed=valid_seed,
|
|
716
|
+
optuna_seed=optuna_seed,
|
|
717
|
+
validate_penalty=validate_penalty)
|
|
718
|
+
|
|
719
|
+
def name(self):
|
|
720
|
+
return "AdaBoost"
|
|
721
|
+
|
|
722
|
+
def reference(self) -> dict[str, str]:
|
|
723
|
+
"""
|
|
724
|
+
This function will return reference of this method in python dict.
|
|
725
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
726
|
+
|
|
727
|
+
Returns:
|
|
728
|
+
dict[str, str]: a dict of reference.
|
|
729
|
+
"""
|
|
730
|
+
refer = super().reference()
|
|
731
|
+
refer[
|
|
732
|
+
self.name() +
|
|
733
|
+
" document"] = "https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html"
|
|
734
|
+
refer[
|
|
735
|
+
self.name() +
|
|
736
|
+
" publication: original version"] = "https://www.ee.columbia.edu/~sfchang/course/svia-F03/papers/freund95decisiontheoretic-adaboost.pdf"
|
|
737
|
+
refer[
|
|
738
|
+
self.name() +
|
|
739
|
+
" publication: implemented version"] = "https://doi.org/10.4310/SII.2009.v2.n3.a8"
|
|
740
|
+
|
|
741
|
+
return refer
|
|
742
|
+
|
|
743
|
+
def create_model(self, trial, default=False):
|
|
744
|
+
if default:
|
|
745
|
+
parms = {
|
|
746
|
+
"random_state": self.kernel_seed,
|
|
747
|
+
}
|
|
748
|
+
else:
|
|
749
|
+
# scaling penalty: https://scikit-learn.org/stable/auto_examples/svm/plot_svm_scale_c.html#sphx-glr-auto-examples-svm-plot-svm-scale-c-py
|
|
750
|
+
parms = {
|
|
751
|
+
"n_estimators":
|
|
752
|
+
trial.suggest_int('n_estimators', 8, 256, log=True),
|
|
753
|
+
"learning_rate":
|
|
754
|
+
trial.suggest_float('learning_rate', 1e-2, 1, log=True),
|
|
755
|
+
"algorithm":
|
|
756
|
+
"SAMME",
|
|
757
|
+
"random_state":
|
|
758
|
+
self.kernel_seed_tape[trial.number]
|
|
759
|
+
}
|
|
760
|
+
ada = AdaBoostClassifier(**parms)
|
|
761
|
+
return ada
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
# DT
|
|
765
|
+
class DecisionTree_tuner(Classification_tuner):
|
|
766
|
+
"""
|
|
767
|
+
Tuning a DecisionTree calssifier.
|
|
768
|
+
[sklearn.tree.DecisionTreeClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html)
|
|
769
|
+
"""
|
|
770
|
+
|
|
771
|
+
def __init__(self,
|
|
772
|
+
n_try=25,
|
|
773
|
+
n_cv=5,
|
|
774
|
+
target="mcc",
|
|
775
|
+
kernel_seed=None,
|
|
776
|
+
valid_seed=None,
|
|
777
|
+
optuna_seed=None,
|
|
778
|
+
validate_penalty=True):
|
|
779
|
+
"""
|
|
780
|
+
Args:
|
|
781
|
+
n_try (int, optional): The number of trials optuna should try. Defaults to 25.
|
|
782
|
+
n_cv (int, optional): The number of folds to execute cross validation evaluation in iteration of optuna optimization. Defaults to 5.
|
|
783
|
+
target (str, optional): The target of optuna optimization. Notice that is different from the training loss of model. Defaults to "mcc".
|
|
784
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
785
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
786
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
787
|
+
validate_penalty (bool, optional): True to penalty the overfitting by difference between training score and cv score. Defaults to True.
|
|
788
|
+
"""
|
|
789
|
+
super().__init__(n_try=n_try,
|
|
790
|
+
n_cv=n_cv,
|
|
791
|
+
target=target,
|
|
792
|
+
kernel_seed=kernel_seed,
|
|
793
|
+
valid_seed=valid_seed,
|
|
794
|
+
optuna_seed=optuna_seed,
|
|
795
|
+
validate_penalty=validate_penalty)
|
|
796
|
+
|
|
797
|
+
def name(self):
|
|
798
|
+
return "DecisionTree"
|
|
799
|
+
|
|
800
|
+
def reference(self) -> dict[str, str]:
|
|
801
|
+
"""
|
|
802
|
+
This function will return reference of this method in python dict.
|
|
803
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
804
|
+
|
|
805
|
+
Returns:
|
|
806
|
+
dict[str, str]: a dict of reference.
|
|
807
|
+
"""
|
|
808
|
+
refer = super().reference()
|
|
809
|
+
refer[
|
|
810
|
+
self.name() +
|
|
811
|
+
" document"] = "https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html"
|
|
812
|
+
refer[
|
|
813
|
+
self.name() +
|
|
814
|
+
" publication"] = "https://www.taylorfrancis.com/books/mono/10.1201/9781315139470/classification-regression-trees-leo-breiman-jerome-friedman-olshen-charles-stone"
|
|
815
|
+
|
|
816
|
+
return refer
|
|
817
|
+
|
|
818
|
+
def create_model(self, trial, default=False):
|
|
819
|
+
if default:
|
|
820
|
+
parms = {
|
|
821
|
+
"random_state": self.kernel_seed,
|
|
822
|
+
}
|
|
823
|
+
else:
|
|
824
|
+
parms = {
|
|
825
|
+
"max_depth":
|
|
826
|
+
trial.suggest_int('max_depth', 2, 16, log=True),
|
|
827
|
+
"min_samples_split":
|
|
828
|
+
trial.suggest_int('min_samples_split', 2, 32, log=True),
|
|
829
|
+
"min_samples_leaf":
|
|
830
|
+
trial.suggest_int('min_samples_leaf', 1, 16, log=True),
|
|
831
|
+
"ccp_alpha":
|
|
832
|
+
trial.suggest_float('ccp_alpha', 1e-3, 1e-1, log=True),
|
|
833
|
+
"random_state":
|
|
834
|
+
self.kernel_seed_tape[trial.number],
|
|
835
|
+
}
|
|
836
|
+
DT = DecisionTreeClassifier(**parms)
|
|
837
|
+
return DT
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
# catboost
|
|
841
|
+
class CatBoost_tuner(Classification_tuner):
|
|
842
|
+
"""
|
|
843
|
+
Tuning a CatBoost classifier model.
|
|
844
|
+
[catboost.CatBoostClassifier](https://catboost.ai/en/docs/concepts/python-reference_catboostclassifier)
|
|
845
|
+
|
|
846
|
+
ToDo:
|
|
847
|
+
1. compare with optuna.integration.CatBoost...
|
|
848
|
+
"""
|
|
849
|
+
|
|
850
|
+
def __init__(self,
|
|
851
|
+
n_try=75,
|
|
852
|
+
n_cv=5,
|
|
853
|
+
target="mcc",
|
|
854
|
+
kernel_seed=None,
|
|
855
|
+
valid_seed=None,
|
|
856
|
+
optuna_seed=None,
|
|
857
|
+
validate_penalty=True):
|
|
858
|
+
"""
|
|
859
|
+
|
|
860
|
+
Args:
|
|
861
|
+
n_try (int, optional): The number of trials optuna should try. Defaults to 75.
|
|
862
|
+
n_cv (int, optional): The number of folds to execute cross validation evaluation in iteration of optuna optimization. Defaults to 5.
|
|
863
|
+
target (str, optional): The target of optuna optimization. Notice that is different from the training loss of model. Defaults to "mcc".
|
|
864
|
+
kernel_seed (int, optional): Random seed for model. Defaults to None.
|
|
865
|
+
valid_seed (int, optional): Random seed for cross validation. Defaults to None.
|
|
866
|
+
optuna_seed (int, optional): Random seed for optuna's hyperparameter sampling. Defaults to None.
|
|
867
|
+
validate_penalty (bool, optional): True to penalty the overfitting by difference between training score and cv score. Defaults to True.
|
|
868
|
+
|
|
869
|
+
"""
|
|
870
|
+
super().__init__(n_try=n_try,
|
|
871
|
+
n_cv=n_cv,
|
|
872
|
+
target=target,
|
|
873
|
+
kernel_seed=kernel_seed,
|
|
874
|
+
valid_seed=valid_seed,
|
|
875
|
+
optuna_seed=optuna_seed,
|
|
876
|
+
validate_penalty=validate_penalty)
|
|
877
|
+
|
|
878
|
+
def name(self):
|
|
879
|
+
return "CatBoost"
|
|
880
|
+
|
|
881
|
+
def reference(self) -> dict[str, str]:
|
|
882
|
+
"""
|
|
883
|
+
This function will return reference of this method in python dict.
|
|
884
|
+
If you want to access it in PineBioML api document, then click on the >Expand source code
|
|
885
|
+
|
|
886
|
+
Returns:
|
|
887
|
+
dict[str, str]: a dict of reference.
|
|
888
|
+
"""
|
|
889
|
+
refer = super().reference()
|
|
890
|
+
refer[self.name() + " document"] = "https://catboost.ai/en/docs/"
|
|
891
|
+
refer[
|
|
892
|
+
self.name() +
|
|
893
|
+
" publication"] = "https://proceedings.neurips.cc/paper_files/paper/2018/file/14491b756b3a51daac41c24863285549-Paper.pdf"
|
|
894
|
+
|
|
895
|
+
return refer
|
|
896
|
+
|
|
897
|
+
def create_model(self, trial, default=False):
|
|
898
|
+
if default:
|
|
899
|
+
parms = {
|
|
900
|
+
"random_seed": self.kernel_seed,
|
|
901
|
+
"verbose": False,
|
|
902
|
+
#"use_best_model": True
|
|
903
|
+
}
|
|
904
|
+
else:
|
|
905
|
+
depth = trial.suggest_float('max_depth', 3, 16, log=True)
|
|
906
|
+
leaves = trial.suggest_float('num_leaves',
|
|
907
|
+
depth * 2 / 3,
|
|
908
|
+
depth,
|
|
909
|
+
log=True)
|
|
910
|
+
depth = int(np.rint(depth))
|
|
911
|
+
leaves = int(np.floor(np.power(2, leaves)))
|
|
912
|
+
|
|
913
|
+
if trial.suggest_categorical("use_subsample", [True, False]):
|
|
914
|
+
sampling_rate = trial.suggest_float('subsample',
|
|
915
|
+
0.5,
|
|
916
|
+
0.9,
|
|
917
|
+
log=True)
|
|
918
|
+
col_sampling_rate = trial.suggest_float(
|
|
919
|
+
'colsample_bytree', 0.1, 0.9)
|
|
920
|
+
else:
|
|
921
|
+
sampling_rate = 1.
|
|
922
|
+
col_sampling_rate = 1.
|
|
923
|
+
|
|
924
|
+
parms = {
|
|
925
|
+
"n_estimators":
|
|
926
|
+
trial.suggest_int('n_estimators', 16, 256, log=True),
|
|
927
|
+
"learning_rate":
|
|
928
|
+
trial.suggest_float('learning_rate', 1e-2, 1, log=True),
|
|
929
|
+
"max_depth":
|
|
930
|
+
depth,
|
|
931
|
+
"reg_lambda":
|
|
932
|
+
trial.suggest_float('reg_lambda', 5e-3, 1e+1, log=True),
|
|
933
|
+
"colsample_bylevel":
|
|
934
|
+
col_sampling_rate,
|
|
935
|
+
"subsample":
|
|
936
|
+
sampling_rate,
|
|
937
|
+
#"use_best_model": True,
|
|
938
|
+
"random_seed":
|
|
939
|
+
self.kernel_seed_tape[trial.number],
|
|
940
|
+
"verbose":
|
|
941
|
+
False,
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
cat = CatBoostClassifier(**parms)
|
|
945
|
+
return cat
|
|
946
|
+
|
|
947
|
+
def evaluate(self, trial, default=False):
|
|
948
|
+
"""
|
|
949
|
+
To evaluate the score of this trial. you should call create_model instead of creating model manually in this function.
|
|
950
|
+
catboost need to be used with pool.
|
|
951
|
+
|
|
952
|
+
Args:
|
|
953
|
+
trial (optuna.trial.Trial): optuna trial in this call.
|
|
954
|
+
default (bool): To use default hyper parameter. This argument will be passed to creat_model
|
|
955
|
+
Returns :
|
|
956
|
+
float: The score.
|
|
957
|
+
"""
|
|
958
|
+
classifier_obj = self.create_model(trial, default)
|
|
959
|
+
|
|
960
|
+
cv = StratifiedKFold(n_splits=self.n_cv,
|
|
961
|
+
shuffle=True,
|
|
962
|
+
random_state=self.valid_seed_tape[trial.number])
|
|
963
|
+
|
|
964
|
+
score = []
|
|
965
|
+
for i, (train_ind, test_ind) in enumerate(cv.split(self.x, self.y)):
|
|
966
|
+
x_train = self.x.iloc[train_ind]
|
|
967
|
+
y_train = self.y.iloc[train_ind]
|
|
968
|
+
pool_train = Pool(x_train, y_train)
|
|
969
|
+
|
|
970
|
+
x_test = self.x.iloc[test_ind]
|
|
971
|
+
y_test = self.y.iloc[test_ind]
|
|
972
|
+
#pool_test = Pool(x_test, y_test)
|
|
973
|
+
|
|
974
|
+
classifier_obj.fit(pool_train) #, eval_set=pool_test
|
|
975
|
+
|
|
976
|
+
train_score = self.metric(classifier_obj, x_train, y_train)
|
|
977
|
+
test_score = self.metric(classifier_obj, x_test, y_test)
|
|
978
|
+
if self.validate_penalty:
|
|
979
|
+
score.append(test_score + 0.1 * (test_score - train_score))
|
|
980
|
+
else:
|
|
981
|
+
score.append(test_score)
|
|
982
|
+
|
|
983
|
+
score = sum(score) / self.n_cv
|
|
984
|
+
return score
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
# Todo
|
|
988
|
+
# KNN
|
|
989
|
+
# KNN-Graph spectrum
|