FLAML 2.3.1__tar.gz → 2.3.3__tar.gz
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.
- {flaml-2.3.1 → flaml-2.3.3}/FLAML.egg-info/PKG-INFO +1 -1
- {flaml-2.3.1 → flaml-2.3.3}/PKG-INFO +1 -1
- {flaml-2.3.1 → flaml-2.3.3}/flaml/__init__.py +4 -2
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/automl.py +3 -3
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/data.py +1 -1
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/model.py +52 -18
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/spark/metrics.py +17 -1
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/task/generic_task.py +2 -6
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/task/task.py +1 -1
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/time_series/ts_data.py +1 -1
- {flaml-2.3.1 → flaml-2.3.3}/flaml/fabric/mlflow.py +8 -1
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/tune.py +10 -0
- flaml-2.3.3/flaml/version.py +1 -0
- flaml-2.3.1/flaml/version.py +0 -1
- {flaml-2.3.1 → flaml-2.3.3}/FLAML.egg-info/SOURCES.txt +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/FLAML.egg-info/dependency_links.txt +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/FLAML.egg-info/requires.txt +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/FLAML.egg-info/top_level.txt +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/LICENSE +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/NOTICE.md +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/README.md +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/agentchat/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/agentchat/agent.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/agentchat/assistant_agent.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/agentchat/conversable_agent.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/agentchat/groupchat.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/agentchat/user_proxy_agent.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/code_utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/extensions/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/math_utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/oai/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/oai/completion.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/oai/openai_utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/autogen/retrieve_utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/contrib/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/contrib/histgb.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/logger.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/ml.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/nlp/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/nlp/huggingface/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/nlp/huggingface/data_collator.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/nlp/huggingface/trainer.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/nlp/huggingface/training_args.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/nlp/huggingface/utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/nlp/utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/spark/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/spark/utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/state.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/task/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/task/factory.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/task/time_series_task.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/time_series/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/time_series/feature.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/time_series/sklearn.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/time_series/tcn.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/time_series/tft.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/time_series/ts_model.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/automl/training_log.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/config.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/all/binary.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/all/multiclass.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/all/regression.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/estimator.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/extra_tree/binary.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/extra_tree/multiclass.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/extra_tree/regression.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/greedy.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/lgbm/binary.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/lgbm/multiclass.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/lgbm/regression.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/portfolio.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/regret.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/rf/binary.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/rf/multiclass.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/rf/regression.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/suggest.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/xgb_limitdepth/binary.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/xgb_limitdepth/multiclass.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/xgb_limitdepth/regression.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/xgboost/binary.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/xgboost/multiclass.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/default/xgboost/regression.json +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/fabric/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/ml.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/onlineml/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/onlineml/autovw.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/onlineml/trial.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/onlineml/trial_runner.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/analysis.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/result.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/sample.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/scheduler/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/scheduler/online_scheduler.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/scheduler/trial_scheduler.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/searcher/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/searcher/blendsearch.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/searcher/cfo_cat.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/searcher/flow2.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/searcher/online_searcher.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/searcher/search_thread.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/searcher/suggestion.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/searcher/variant_generator.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/space.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/spark/__init__.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/spark/utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/trial.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/trial_runner.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/flaml/tune/utils.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/pyproject.toml +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/setup.cfg +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/setup.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/test/test_autovw.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/test/test_conda_distribution.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/test/test_gpu.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/test/test_model.py +0 -0
- {flaml-2.3.1 → flaml-2.3.3}/test/test_version.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import warnings
|
|
2
3
|
|
|
3
4
|
try:
|
|
4
5
|
from flaml.automl import AutoML, logger_formatter
|
|
@@ -12,7 +13,8 @@ from flaml.version import __version__
|
|
|
12
13
|
|
|
13
14
|
# Set the root logger.
|
|
14
15
|
logger = logging.getLogger(__name__)
|
|
15
|
-
logger.
|
|
16
|
+
if logger.level == logging.NOTSET:
|
|
17
|
+
logger.setLevel(logging.INFO)
|
|
16
18
|
|
|
17
19
|
if not has_automl:
|
|
18
|
-
|
|
20
|
+
warnings.warn("flaml.automl is not available. Please install flaml[automl] to enable AutoML functionalities.")
|
|
@@ -203,7 +203,7 @@ class AutoML(BaseEstimator):
|
|
|
203
203
|
* Valid str options depend on different tasks.
|
|
204
204
|
For classification tasks, valid choices are
|
|
205
205
|
["auto", 'stratified', 'uniform', 'time', 'group']. "auto" -> stratified.
|
|
206
|
-
For regression tasks, valid choices are ["auto", 'uniform', 'time'].
|
|
206
|
+
For regression tasks, valid choices are ["auto", 'uniform', 'time', 'group'].
|
|
207
207
|
"auto" -> uniform.
|
|
208
208
|
For time series forecast tasks, must be "auto" or 'time'.
|
|
209
209
|
For ranking task, must be "auto" or 'group'.
|
|
@@ -739,7 +739,7 @@ class AutoML(BaseEstimator):
|
|
|
739
739
|
* Valid str options depend on different tasks.
|
|
740
740
|
For classification tasks, valid choices are
|
|
741
741
|
["auto", 'stratified', 'uniform', 'time', 'group']. "auto" -> stratified.
|
|
742
|
-
For regression tasks, valid choices are ["auto", 'uniform', 'time'].
|
|
742
|
+
For regression tasks, valid choices are ["auto", 'uniform', 'time', 'group'].
|
|
743
743
|
"auto" -> uniform.
|
|
744
744
|
For time series forecast tasks, must be "auto" or 'time'.
|
|
745
745
|
For ranking task, must be "auto" or 'group'.
|
|
@@ -1358,7 +1358,7 @@ class AutoML(BaseEstimator):
|
|
|
1358
1358
|
* Valid str options depend on different tasks.
|
|
1359
1359
|
For classification tasks, valid choices are
|
|
1360
1360
|
["auto", 'stratified', 'uniform', 'time', 'group']. "auto" -> stratified.
|
|
1361
|
-
For regression tasks, valid choices are ["auto", 'uniform', 'time'].
|
|
1361
|
+
For regression tasks, valid choices are ["auto", 'uniform', 'time', 'group'].
|
|
1362
1362
|
"auto" -> uniform.
|
|
1363
1363
|
For time series forecast tasks, must be "auto" or 'time'.
|
|
1364
1364
|
For ranking task, must be "auto" or 'group'.
|
|
@@ -293,7 +293,7 @@ class DataTransformer:
|
|
|
293
293
|
y = y.rename(TS_VALUE_COL)
|
|
294
294
|
for column in X.columns:
|
|
295
295
|
# sklearn\utils\validation.py needs int/float values
|
|
296
|
-
if X[column].dtype.name in ("object", "category"):
|
|
296
|
+
if X[column].dtype.name in ("object", "category", "string"):
|
|
297
297
|
if X[column].nunique() == 1 or X[column].nunique(dropna=True) == n - X[column].isnull().sum():
|
|
298
298
|
X.drop(columns=column, inplace=True)
|
|
299
299
|
drop = True
|
|
@@ -157,7 +157,25 @@ class BaseEstimator:
|
|
|
157
157
|
|
|
158
158
|
@property
|
|
159
159
|
def estimator(self):
|
|
160
|
-
"""
|
|
160
|
+
"""
|
|
161
|
+
Get the best trained estimator model.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
object or None: The trained model obtained after calling the `fit()` method,
|
|
165
|
+
representing the best estimator found during the training process. If `fit()` has
|
|
166
|
+
not been called yet, it returns `None`.
|
|
167
|
+
|
|
168
|
+
Examples:
|
|
169
|
+
>>> from flaml import AutoML
|
|
170
|
+
>>> automl = AutoML()
|
|
171
|
+
>>> automl.fit(X_train, y_train)
|
|
172
|
+
>>> best_estimator = automl.model.estimator
|
|
173
|
+
>>> print(best_estimator)
|
|
174
|
+
RandomForestClassifier()
|
|
175
|
+
|
|
176
|
+
Note:
|
|
177
|
+
To access the best estimator, use `automl.model.estimator`.
|
|
178
|
+
"""
|
|
161
179
|
return self._model
|
|
162
180
|
|
|
163
181
|
@property
|
|
@@ -249,9 +267,11 @@ class BaseEstimator:
|
|
|
249
267
|
mem = psutil.virtual_memory() if psutil is not None else None
|
|
250
268
|
try:
|
|
251
269
|
with limit_resource(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
270
|
+
(
|
|
271
|
+
mem.available * (1 - free_mem_ratio) + psutil.Process(os.getpid()).memory_info().rss
|
|
272
|
+
if mem is not None
|
|
273
|
+
else -1
|
|
274
|
+
),
|
|
255
275
|
budget,
|
|
256
276
|
):
|
|
257
277
|
train_time = self._fit(X_train, y_train, **kwargs)
|
|
@@ -1534,12 +1554,16 @@ class LGBMEstimator(BaseEstimator):
|
|
|
1534
1554
|
if n_iter > 1:
|
|
1535
1555
|
max_iter = min(
|
|
1536
1556
|
n_iter,
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1557
|
+
(
|
|
1558
|
+
int((budget - time.time() + start_time - self._t1) / self._time_per_iter + 1)
|
|
1559
|
+
if budget is not None
|
|
1560
|
+
else n_iter
|
|
1561
|
+
),
|
|
1562
|
+
(
|
|
1563
|
+
int((1 - free_mem_ratio) * mem0 / self._mem_per_iter)
|
|
1564
|
+
if psutil is not None and self._mem_per_iter > 0
|
|
1565
|
+
else n_iter
|
|
1566
|
+
),
|
|
1543
1567
|
)
|
|
1544
1568
|
if trained and max_iter <= self.params[self.ITER_HP]:
|
|
1545
1569
|
return time.time() - start_time
|
|
@@ -1561,18 +1585,17 @@ class LGBMEstimator(BaseEstimator):
|
|
|
1561
1585
|
callbacks = None
|
|
1562
1586
|
if callbacks is None:
|
|
1563
1587
|
self._fit(X_train, y_train, **kwargs)
|
|
1564
|
-
else:
|
|
1565
|
-
self._fit(X_train, y_train, callbacks=callbacks, **kwargs)
|
|
1566
|
-
if callbacks is None:
|
|
1567
1588
|
# for xgboost>=1.6.0, pop callbacks to enable pickle
|
|
1568
1589
|
callbacks = self.params.pop("callbacks")
|
|
1569
1590
|
self._model.set_params(callbacks=callbacks[:-1])
|
|
1591
|
+
else:
|
|
1592
|
+
self._fit(X_train, y_train, callbacks=callbacks, **kwargs)
|
|
1570
1593
|
best_iteration = (
|
|
1571
1594
|
getattr(self._model.get_booster(), "best_iteration", None)
|
|
1572
1595
|
if isinstance(self, XGBoostSklearnEstimator)
|
|
1573
1596
|
else self._model.best_iteration_
|
|
1574
1597
|
)
|
|
1575
|
-
if best_iteration is not None:
|
|
1598
|
+
if best_iteration is not None and best_iteration > 0:
|
|
1576
1599
|
self._model.set_params(n_estimators=best_iteration + 1)
|
|
1577
1600
|
else:
|
|
1578
1601
|
self._fit(X_train, y_train, **kwargs)
|
|
@@ -2043,8 +2066,8 @@ class CatBoostEstimator(BaseEstimator):
|
|
|
2043
2066
|
self.estimator_class = CatBoostRegressor
|
|
2044
2067
|
|
|
2045
2068
|
def fit(self, X_train, y_train, budget=None, free_mem_ratio=0, **kwargs):
|
|
2046
|
-
|
|
2047
|
-
|
|
2069
|
+
kwargs.pop("is_retrain", None)
|
|
2070
|
+
kwargs.pop("groups", None)
|
|
2048
2071
|
start_time = time.time()
|
|
2049
2072
|
deadline = start_time + budget if budget else np.inf
|
|
2050
2073
|
train_dir = f"catboost_{str(start_time)}"
|
|
@@ -2090,7 +2113,8 @@ class CatBoostEstimator(BaseEstimator):
|
|
|
2090
2113
|
if weight is not None:
|
|
2091
2114
|
kwargs["sample_weight"] = weight
|
|
2092
2115
|
self._model = model
|
|
2093
|
-
|
|
2116
|
+
# Commented-out line below incorrectly assigned n_estimators - see https://github.com/microsoft/FLAML/pull/1364
|
|
2117
|
+
# self.params[self.ITER_HP] = self._model.tree_count_
|
|
2094
2118
|
train_time = time.time() - start_time
|
|
2095
2119
|
return train_time
|
|
2096
2120
|
|
|
@@ -2184,6 +2208,11 @@ class SVCEstimator(SKLearnEstimator):
|
|
|
2184
2208
|
|
|
2185
2209
|
def __init__(self, task="binary", **config):
|
|
2186
2210
|
super().__init__(task, **config)
|
|
2211
|
+
self.params.update(
|
|
2212
|
+
{
|
|
2213
|
+
"random_state": config.get("random_seed", 10242048),
|
|
2214
|
+
}
|
|
2215
|
+
)
|
|
2187
2216
|
assert self._task.is_classification(), "LinearSVC for classification task only"
|
|
2188
2217
|
self.estimator_class = LinearSVC
|
|
2189
2218
|
|
|
@@ -2428,6 +2457,11 @@ class ElasticNetEstimator(SKLearnEstimator):
|
|
|
2428
2457
|
|
|
2429
2458
|
def __init__(self, task="regression", **config):
|
|
2430
2459
|
super().__init__(task, **config)
|
|
2460
|
+
self.params.update(
|
|
2461
|
+
{
|
|
2462
|
+
"random_state": config.get("random_seed", 10242048),
|
|
2463
|
+
}
|
|
2464
|
+
)
|
|
2431
2465
|
assert self._task.is_regression(), "ElasticNet for regression task only"
|
|
2432
2466
|
self.estimator_class = ElasticNet
|
|
2433
2467
|
|
|
@@ -2752,7 +2786,7 @@ class BaseResourceLimit:
|
|
|
2752
2786
|
def check_resource_limits(self, current_time, current_iteration, mllib):
|
|
2753
2787
|
if (mllib == "xgb" and current_iteration == 0) or (mllib == "cat" and current_iteration == 1):
|
|
2754
2788
|
self._time_per_iter = current_time - self.start_time
|
|
2755
|
-
if current_time + self._time_per_iter > self.deadline:
|
|
2789
|
+
if mllib != "cat" and current_time + self._time_per_iter > self.deadline:
|
|
2756
2790
|
return False
|
|
2757
2791
|
if psutil is not None and self.free_mem_ratio is not None:
|
|
2758
2792
|
mem = psutil.virtual_memory()
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
from typing import Union
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
@@ -9,7 +10,7 @@ from pyspark.ml.evaluation import (
|
|
|
9
10
|
RegressionEvaluator,
|
|
10
11
|
)
|
|
11
12
|
|
|
12
|
-
from flaml.automl.spark import F, psSeries
|
|
13
|
+
from flaml.automl.spark import F, T, psDataFrame, psSeries, sparkDataFrame
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def ps_group_counts(groups: Union[psSeries, np.ndarray]) -> np.ndarray:
|
|
@@ -36,6 +37,16 @@ def _compute_label_from_probability(df, probability_col, prediction_col):
|
|
|
36
37
|
return df
|
|
37
38
|
|
|
38
39
|
|
|
40
|
+
def string_to_array(s):
|
|
41
|
+
try:
|
|
42
|
+
return json.loads(s)
|
|
43
|
+
except json.JSONDecodeError:
|
|
44
|
+
return []
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
string_to_array_udf = F.udf(string_to_array, T.ArrayType(T.DoubleType()))
|
|
48
|
+
|
|
49
|
+
|
|
39
50
|
def spark_metric_loss_score(
|
|
40
51
|
metric_name: str,
|
|
41
52
|
y_predict: psSeries,
|
|
@@ -135,6 +146,11 @@ def spark_metric_loss_score(
|
|
|
135
146
|
)
|
|
136
147
|
elif metric_name == "log_loss":
|
|
137
148
|
# For log_loss, prediction_col should be probability, and we need to convert it to label
|
|
149
|
+
# handle data like "{'type': '1', 'values': '[1, 2, 3]'}"
|
|
150
|
+
# Fix cannot resolve "array_max(prediction)" due to data type mismatch: Parameter 1 requires the "ARRAY" type,
|
|
151
|
+
# however "prediction" has the type "STRUCT<type: TINYINT, size: INT, indices: ARRAY<INT>, values: ARRAY<DOUBLE>>"
|
|
152
|
+
df = df.withColumn(prediction_col, df[prediction_col].cast(T.StringType()))
|
|
153
|
+
df = df.withColumn(prediction_col, string_to_array_udf(df[prediction_col]))
|
|
138
154
|
df = _compute_label_from_probability(df, prediction_col, prediction_col + "_label")
|
|
139
155
|
evaluator = MulticlassClassificationEvaluator(
|
|
140
156
|
metricName="logLoss",
|
|
@@ -87,7 +87,6 @@ class GenericTask(Task):
|
|
|
87
87
|
"transformer": TransformersEstimator,
|
|
88
88
|
"transformer_ms": TransformersEstimatorModelSelection,
|
|
89
89
|
"histgb": HistGradientBoostingEstimator,
|
|
90
|
-
# Above are open-source, below are internal
|
|
91
90
|
"svc": SVCEstimator,
|
|
92
91
|
"sgd": SGDEstimator,
|
|
93
92
|
"nb_spark": SparkNaiveBayesEstimator,
|
|
@@ -443,8 +442,8 @@ class GenericTask(Task):
|
|
|
443
442
|
X_train_all, y_train_all = shuffle(X_train_all, y_train_all, random_state=RANDOM_SEED)
|
|
444
443
|
if data_is_df:
|
|
445
444
|
X_train_all.reset_index(drop=True, inplace=True)
|
|
446
|
-
|
|
447
|
-
|
|
445
|
+
if isinstance(y_train_all, pd.Series):
|
|
446
|
+
y_train_all.reset_index(drop=True, inplace=True)
|
|
448
447
|
|
|
449
448
|
X_train, y_train = X_train_all, y_train_all
|
|
450
449
|
state.groups_all = state.groups
|
|
@@ -706,7 +705,6 @@ class GenericTask(Task):
|
|
|
706
705
|
fit_kwargs = {}
|
|
707
706
|
if cv_score_agg_func is None:
|
|
708
707
|
cv_score_agg_func = default_cv_score_agg_func
|
|
709
|
-
start_time = time.time()
|
|
710
708
|
val_loss_folds = []
|
|
711
709
|
log_metric_folds = []
|
|
712
710
|
metric = None
|
|
@@ -813,8 +811,6 @@ class GenericTask(Task):
|
|
|
813
811
|
if is_spark_dataframe:
|
|
814
812
|
X_train.spark.unpersist() # uncache data to free memory
|
|
815
813
|
X_val.spark.unpersist() # uncache data to free memory
|
|
816
|
-
if budget and time.time() - start_time >= budget:
|
|
817
|
-
break
|
|
818
814
|
val_loss, metric = cv_score_agg_func(val_loss_folds, log_metric_folds)
|
|
819
815
|
n = total_fold_num
|
|
820
816
|
pred_time /= n
|
|
@@ -192,7 +192,7 @@ class Task(ABC):
|
|
|
192
192
|
* Valid str options depend on different tasks.
|
|
193
193
|
For classification tasks, valid choices are
|
|
194
194
|
["auto", 'stratified', 'uniform', 'time', 'group']. "auto" -> stratified.
|
|
195
|
-
For regression tasks, valid choices are ["auto", 'uniform', 'time'].
|
|
195
|
+
For regression tasks, valid choices are ["auto", 'uniform', 'time', 'group'].
|
|
196
196
|
"auto" -> uniform.
|
|
197
197
|
For time series forecast tasks, must be "auto" or 'time'.
|
|
198
198
|
For ranking task, must be "auto" or 'group'.
|
|
@@ -393,7 +393,7 @@ class DataTransformerTS:
|
|
|
393
393
|
|
|
394
394
|
for column in X.columns:
|
|
395
395
|
# sklearn/utils/validation.py needs int/float values
|
|
396
|
-
if X[column].dtype.name in ("object", "category"):
|
|
396
|
+
if X[column].dtype.name in ("object", "category", "string"):
|
|
397
397
|
if (
|
|
398
398
|
# drop columns where all values are the same
|
|
399
399
|
X[column].nunique() == 1
|
|
@@ -127,6 +127,13 @@ def _get_notebook_name():
|
|
|
127
127
|
return None
|
|
128
128
|
|
|
129
129
|
|
|
130
|
+
def safe_json_dumps(obj):
|
|
131
|
+
def default(o):
|
|
132
|
+
return str(o)
|
|
133
|
+
|
|
134
|
+
return json.dumps(obj, default=default)
|
|
135
|
+
|
|
136
|
+
|
|
130
137
|
class MLflowIntegration:
|
|
131
138
|
def __init__(self, experiment_type="automl", mlflow_exp_name=None, extra_tag=None):
|
|
132
139
|
try:
|
|
@@ -438,7 +445,7 @@ class MLflowIntegration:
|
|
|
438
445
|
"flaml.meric": automl_metric_name,
|
|
439
446
|
"flaml.run_source": "flaml-automl",
|
|
440
447
|
"flaml.log_type": self.log_type,
|
|
441
|
-
"flaml.automl_user_configurations":
|
|
448
|
+
"flaml.automl_user_configurations": safe_json_dumps(automl._automl_user_configurations),
|
|
442
449
|
},
|
|
443
450
|
"params": {
|
|
444
451
|
"sample_size": search_state.sample_size,
|
|
@@ -260,6 +260,8 @@ def run(
|
|
|
260
260
|
mlflow_exp_name: Optional[str] = None,
|
|
261
261
|
automl_info: Optional[Tuple[float]] = None,
|
|
262
262
|
extra_tag: Optional[dict] = None,
|
|
263
|
+
cost_attr: Optional[str] = "auto",
|
|
264
|
+
cost_budget: Optional[float] = None,
|
|
263
265
|
**ray_args,
|
|
264
266
|
):
|
|
265
267
|
"""The function-based way of performing HPO.
|
|
@@ -462,6 +464,12 @@ def run(
|
|
|
462
464
|
overwritten by the value of `n_concurrent_trials` in AutoML. When <= 0, the concurrent trials
|
|
463
465
|
will be set to the number of executors.
|
|
464
466
|
extra_tag: dict, default=None | Extra tags to be added to the mlflow runs created by autologging.
|
|
467
|
+
cost_attr: None or str to specify the attribute to evaluate the cost of different trials.
|
|
468
|
+
Default is "auto", which means that we will automatically choose the cost attribute to use (depending
|
|
469
|
+
on the nature of the resource budget). When cost_attr is set to None, cost differences between different trials will be omitted
|
|
470
|
+
in our search algorithm. When cost_attr is set to a str different from "auto" and "time_total_s",
|
|
471
|
+
this cost_attr must be available in the result dict of the trial.
|
|
472
|
+
cost_budget: A float of the cost budget. Only valid when cost_attr is a str different from "auto" and "time_total_s".
|
|
465
473
|
**ray_args: keyword arguments to pass to ray.tune.run().
|
|
466
474
|
Only valid when use_ray=True.
|
|
467
475
|
"""
|
|
@@ -600,6 +608,8 @@ def run(
|
|
|
600
608
|
metric_constraints=metric_constraints,
|
|
601
609
|
use_incumbent_result_in_evaluation=use_incumbent_result_in_evaluation,
|
|
602
610
|
lexico_objectives=lexico_objectives,
|
|
611
|
+
cost_attr=cost_attr,
|
|
612
|
+
cost_budget=cost_budget,
|
|
603
613
|
)
|
|
604
614
|
else:
|
|
605
615
|
if metric is None or mode is None:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.3.3"
|
flaml-2.3.1/flaml/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.3.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|