From a794d8858811f4925196d67f2ddc07783ffe5355 Mon Sep 17 00:00:00 2001 From: "d.a.bunin" Date: Fri, 18 Feb 2022 12:13:59 +0300 Subject: [PATCH 1/2] Add table parameter for ConsoleLogger and tests for it --- etna/loggers/console_logger.py | 36 +++++++++++++++-------- tests/test_loggers/test_console_logger.py | 18 ++++++++++++ 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/etna/loggers/console_logger.py b/etna/loggers/console_logger.py index 90034a431..8b745cb88 100644 --- a/etna/loggers/console_logger.py +++ b/etna/loggers/console_logger.py @@ -16,11 +16,20 @@ class ConsoleLogger(BaseLogger): """Log any events and metrics to stderr output. Uses loguru.""" - def __init__(self): - """Create instance of ConsoleLogger.""" + def __init__(self, table: bool = True): + """Create instance of ConsoleLogger. + + Parameters + ---------- + table: + Indicator for writing tables to the console + """ super().__init__() - if 0 in _logger._core.handlers: + self.table = table + try: _logger.remove(0) + except ValueError: + pass _logger.add(sink=sys.stderr) self.logger = _logger.opt(depth=2, lazy=True, colors=True) @@ -37,7 +46,7 @@ def log(self, msg: Union[str, Dict[str, Any]], **kwargs): kwargs: Parameters for changing additional info in log message """ - self.logger.patch(lambda r: r.update(**kwargs)).info(msg) + self.logger.patch(lambda r: r.update(**kwargs)).info(msg) # type: ignore def log_backtest_metrics( self, ts: "TSDataset", metrics_df: pd.DataFrame, forecast_df: pd.DataFrame, fold_info_df: pd.DataFrame @@ -60,15 +69,16 @@ def log_backtest_metrics( ----- The result of logging will be different for aggregate_metrics=True and aggregate_metrics=False """ - for _, row in metrics_df.iterrows(): - for metric in metrics_df.columns[1:-1]: - # case for aggregate_metrics=False - if "fold_number" in row: - msg = f'Fold {row["fold_number"]}:{row["segment"]}:{metric} = {row[metric]}' - # case for aggregate_metrics=True - else: - msg = f'Segment {row["segment"]}:{metric} = {row[metric]}' - self.logger.info(msg) + if self.table: + for _, row in metrics_df.iterrows(): + for metric in metrics_df.columns[1:-1]: + # case for aggregate_metrics=False + if "fold_number" in row: + msg = f'Fold {row["fold_number"]}:{row["segment"]}:{metric} = {row[metric]}' + # case for aggregate_metrics=True + else: + msg = f'Segment {row["segment"]}:{metric} = {row[metric]}' + self.logger.info(msg) @property def pl_logger(self): diff --git a/tests/test_loggers/test_console_logger.py b/tests/test_loggers/test_console_logger.py index 2f6b1b940..6b22127bd 100644 --- a/tests/test_loggers/test_console_logger.py +++ b/tests/test_loggers/test_console_logger.py @@ -53,6 +53,24 @@ def test_backtest_logging(example_tsds: TSDataset): tslogger.remove(idx) +def test_backtest_logging_no_tables(example_tsds: TSDataset): + """Check working of logging inside backtest with `table=False`.""" + file = NamedTemporaryFile() + _logger.add(file.name) + idx = tslogger.add(ConsoleLogger(table=False)) + metrics = [MAE(), MSE(), SMAPE()] + date_flags = DateFlagsTransform(day_number_in_week=True, day_number_in_month=True) + pipe = Pipeline(model=CatBoostModelMultiSegment(), horizon=10, transforms=[date_flags]) + n_folds = 5 + pipe.backtest(ts=example_tsds, metrics=metrics, n_jobs=1, n_folds=n_folds) + with open(file.name, "r") as in_file: + lines = in_file.readlines() + # remain lines only about backtest + lines = [line for line in lines if "backtest" in line] + assert len(lines) == 0 + tslogger.remove(idx) + + @pytest.mark.parametrize("model", [LinearPerSegmentModel(), LinearMultiSegmentModel()]) def test_model_logging(example_tsds, model): """Check working of logging in fit/forecast of model.""" From 4c9009ae950e2d2c752472c708cc9c562db968b1 Mon Sep 17 00:00:00 2001 From: "d.a.bunin" Date: Fri, 18 Feb 2022 12:16:06 +0300 Subject: [PATCH 2/2] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3db2aaae..78acc3e69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Change the way `Sklearn` models works with regressors ([#440](https://github.com/tinkoff-ai/etna/pull/440)) - Change the way `FeatureSelectionTransform` works with regressors, rename variables replacing the "regressor" to "feature" ([#522](https://github.com/tinkoff-ai/etna/pull/522)) - -- +- Add table option to ConsoleLogger ([#544](https://github.com/tinkoff-ai/etna/pull/544)) - Installation instruction ([#526](https://github.com/tinkoff-ai/etna/pull/526)) - - Trainer kwargs for deep models ([#540](https://github.com/tinkoff-ai/etna/pull/540))