aimclub / FEDOT

Automated modeling and machine learning framework FEDOT
https://fedot.readthedocs.io
BSD 3-Clause "New" or "Revised" License
619 stars 84 forks source link

1182-fix #1215

Closed Lopa10ko closed 6 months ago

Lopa10ko commented 7 months ago

Test that checks the performance of all operations with synthetic data. Anything slower than Random Forest (rf and rfr) is considered not fast enough for the fast_train preset.

Closes #1182

pep8speaks commented 7 months ago

Hello @Lopa10ko! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

There are currently no PEP 8 issues detected in this Pull Request. Cheers! :beers:

Comment last updated at 2023-12-12 12:42:04 UTC
codecov[bot] commented 7 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (9d9469f) 79.27% compared to head (90f45cf) 79.16%. Report is 4 commits behind head on master.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #1215 +/- ## ========================================== - Coverage 79.27% 79.16% -0.12% ========================================== Files 145 145 Lines 10048 9937 -111 ========================================== - Hits 7966 7867 -99 + Misses 2082 2070 -12 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

aPovidlo commented 6 months ago

Проверка проводилась только для синтетических данных и, как я понял, в этих данных были только численные признаки, так?

aPovidlo commented 6 months ago

Пайплайны строились из одной ноды, в которой находилась проверяемая операция?

kasyanovse commented 6 months ago

Проверка проводилась только для синтетических данных и, как я понял, в этих данных были только численные признаки, так?

Данные только синтетические и только численные.

Пайплайны строились из одной ноды, в которой находилась проверяемая операция?

Да. Для временных рядов еще добавлялся lagged.

aPovidlo commented 6 months ago

Проверка проводилась только для синтетических данных и, как я понял, в этих данных были только численные признаки, так?

Данные только синтетические и только численные.

Кмк, этого не достаточно. Например, с категориальными для RF потребуется преобразовать их в OHE и это увеличит время. А, например, для CatBoost этого не нужно делать, и по идеи он выполнится быстрее, но однако он в финальную выборку в классификацию даже не попал.

Пайплайны строились из одной ноды, в которой находилась проверяемая операция?

Да. Для временных рядов еще добавлялся lagged.

А есть ли смысл проверять тогда операции 'resample' и 'one_hot_encoding'? Кажется, они даже не срабатывают и сейчас показывают время пустого прохода через код. Первый возможно потому что класса сбалансированы, а для второго требуется категориальные признаки, чтобы он их начал преобразовывать.

Также я бы разграничил все три задачи на три категории и сравнивал независимо. То есть, для задач TS не брал за эталон RF.

kasyanovse commented 6 months ago

Например, с категориальными для RF потребуется преобразовать их в OHE и это увеличит время

Тест необходим для того, чтобы принципиально медленные алгоритмы не попали в fast-train. Вопрос скорости работы лесов с OHE - это проблема этапа предобработки.

для CatBoost этого не нужно делать, и по идеи он выполнится быстрее

Согласен. Вообще, раз уж заходит про это речь, я бы убрал RF из fast-train и заменил его на CB. По тестам CB быстрее, плюс отлично работает на произвольных данных. Что скажешь?

А есть ли смысл проверять тогда операции 'resample' и 'one_hot_encoding'? Кажется, они даже не срабатывают и сейчас показывают время пустого прохода через код. Первый возможно потому что класса сбалансированы, а для второго требуется категориальные признаки, чтобы он их начал преобразовывать.

В таком случае смысла нет. Пропустим их.

Также я бы разграничил все три задачи на три категории и сравнивал независимо. То есть, для задач TS не брал за эталон RF.

Зачем разграничивать задачи?

А почему не стоит брать за эталон RF для временных рядов? Задачи с временными рядами в 99,9% случаев сводятся к задаче регрессии.

aPovidlo commented 6 months ago

Тест необходим для того, чтобы принципиально медленные алгоритмы не попали в fast-train. Вопрос скорости работы лесов с OHE - это проблема этапа предобработки.

Тут скорее тесты будут релевантные к датасетам, которые полностью будут состоять из численных признаков. С категориальными возможна другая картина.

Согласен. Вообще, раз уж заходит про это речь, я бы убрал RF из fast-train и заменил его на CB. По тестам CB быстрее, плюс отлично работает на произвольных данных. Что скажешь?

CatBoost не попал в таблицу "Операции, которые могут быть с пресетом fast_train". Возможно есть смысл заменить, но не уверен.

В таком случае смысла нет. Пропустим их.

Хорошо.

Зачем разграничивать задачи?

Сравнение в общей таблицы сейчас общее же и кажется не учитывает разбиение по задачам, или я не прав? Можно также попробовать разграничить графики и использовать заместо matplotlib, например, plotly или seaborn для лучшей визуализации.

А почему не стоит брать за эталон RF для временных рядов? Задачи с временными рядами в 99,9% случаев сводятся к задаче регрессии.

А все понял, неправильно прочитал, вы для них сравниваетесь с RFR.

kasyanovse commented 6 months ago

Тут скорее тесты будут релевантные к датасетам, которые полностью будут состоять из численных признаков. С категориальными возможна другая картина.

Так и задумывалось.

CatBoost не попал в таблицу "Операции, которые могут быть с пресетом fast_train". Возможно есть смысл заменить, но не уверен.

Ладно, пока оставим как есть.

Сравнение в общей таблицы сейчас общее же и кажется не учитывает разбиение по задачам, или я не прав? Можно также попробовать разграничить графики и использовать заместо matplotlib, например, plotly или seaborn для лучшей визуализации.

Не учитывает, все модели тестируются в одной куче.

Lopa10ko commented 6 months ago

Решенные задачи:

Измерение скорости различных операций после смены пресетов. Название операции | Тэг `fast_train` | Время обучения на 251 точке, мс| Время обучения на 10000 точек, мс | Отношение времени обучения на 251 и 10000 точек -- | -- | -- | -- | -- rf|1|157.31|3785.36|24.06 rfr|1|199.30|6657.89|33.41 adareg|1|15.47|94.37|6.10 ar|1|3.85|131.27|34.08 arima|0|131.21|3375.51|25.73 cgru|0|1421.76|67605.94|47.55 bernb|1|5.97|73.12|12.26 catboost|0|1459.84|4486.16|3.07 catboostreg|0|600.09|3414.26|5.69 dt|1|5.21|121.75|23.35 dtreg|1|4.70|110.52|23.52 gbr|0|66.38|1142.02|17.20 knn|1|7.18|57.05|7.94 knnreg|1|5.50|59.23|10.78 lasso|1|5.16|34.00|6.59 lda|1|6.45|60.86|9.44 lgbm|0|18.83|224.88|11.94 lgbmreg|0|15.95|216.93|13.60 linear|1|5.40|32.37|6.00 logit|1|6.83|42.32|6.20 mlp|0|30.92|700.75|22.66 multinb|1|4.55|34.01|7.48 qda|1|6.01|57.38|9.55 ridge|1|5.07|30.16|5.95 polyfit|1|1.51|100.28|66.27 sgdr|1|5.95|35.61|5.98 stl_arima|0|212.05|9963.82|46.99 glm|1|3.64|92.69|25.44 ets|1|9.07|227.75|25.10 locf|1|1.35|88.68|65.79 ts_naive_average|1|5.55|4684.58|844.46 svc|0|21.01|12619.37|600.78 svr|0|5.52|48.58|8.81 treg|0|100.73|1533.77|15.23 xgboost|0|45.42|186.34|4.10 xgbreg|0|32.11|149.65|4.66 data_source_table|0|3.88|31.68|8.16 data_source_ts|0|0.85|1.38|1.62 scaling|1|6.91|33.55|4.86 normalization|1|4.89|32.49|6.65 simple_imputation|1|6.44|34.36|5.33 pca|1|4.81|32.80|6.82 kernel_pca|0|27.01|172321.96|6380.50 fast_ica|0|6.37|103.47|16.24 poly_features|0|6.51|39.94|6.13 one_hot_encoding|0|5.07|42.11|8.31 label_encoding|1|3.72|28.54|7.67 ransac_lin_reg|1|12.51|123.65|9.89 ransac_non_lin_reg|0|663.21|717734.59|1082.21 isolation_forest_reg|0|200.81|479.74|2.39 isolation_forest_class|0|162.72|412.40|2.53 rfe_lin_reg|0|6.96|62.42|8.97 rfe_non_lin_reg|0|6.43|149.68|23.28 rfe_lin_class|0|9.94|53.73|5.40 rfe_non_lin_class|0|6.73|169.46|25.19 lagged|1|2.83|131.51|46.48 sparse_lagged|1|1.65|131.91|79.83 smoothing|1|2.21|39.93|18.06 gaussian_filter|1|1.28|143.91|112.52 diff_filter|0|60.88|3682.23|60.48 cut|1|0.83|12.38|14.93 exog_ts|0|1.58|58.26|36.78 resample|0|4.90|30.02|6.12 ![test_all-1](https://github.com/aimclub/FEDOT/assets/81328772/8d518d01-0814-4593-b69a-d8de04117c29) ![test-1](https://github.com/aimclub/FEDOT/assets/81328772/17406c6c-ac86-4b6f-b61d-2946bdb707cc)
Операции, которые могут быть с пресетом fast_train Название операции | Тэг `fast_train` | Время обучения на 251 точке, мс| Время обучения на 10000 точек, мс | -- | -- | -- | -- rf|1|130|3569 rfr|1|147|5583 arima|0|164|3134 catboostreg|0|1023|2803 gbr|0|56|1089 lgbm|0|18|197 lgbmreg|0|14|158 mlp|0|28|434 svr|0|5|46 treg|0|97|1454 xgboost|0|32|139 xgbreg|0|43|129 data_source_table|0|3|27 data_source_ts|0|0|0 fast_ica|0|6|34 poly_features|0|5|32 one_hot_encoding|0|4|29 isolation_forest_reg|0|149|381 isolation_forest_class|0|156|404 rfe_lin_reg|0|6|36 rfe_non_lin_reg|0|5|122 rfe_lin_class|0|7|40 rfe_non_lin_class|0|6|146 exog_ts|0|1|48 resample|0|3|26 ![fast_non_fast_train](https://github.com/aimclub/FEDOT/assets/81328772/737da889-2fb8-4957-a273-5599b53a7834)
Код для тестирования скорости операций в IPython На примере временных рядов и узла `lagged`. ```py import numpy as np import pandas as pd from fedot.core.data.data import InputData from fedot.core.pipelines.node import PipelineNode from fedot.core.pipelines.pipeline import Pipeline from fedot.core.repository.dataset_types import DataTypesEnum from fedot.core.repository.tasks import Task, TaskTypesEnum, TsForecastingParams def get_time(time): return np.mean(time.all_runs) / time.loops build_pipeline = lambda: Pipeline(PipelineNode('lagged')) base_time = %timeit -o build_pipeline() base_time = get_time(base_time) results = dict() for i in map(int, np.linspace(200, 20000, 5)): results[i] = dict() for j in map(int, np.linspace(10, 150, 5)): data = InputData(idx=np.arange(i), features=np.arange(i), target=np.arange(i), task=Task(TaskTypesEnum.ts_forecasting, TsForecastingParams(j)), data_type=DataTypesEnum.ts) res = %timeit -o build_pipeline().fit(data) results[i][j] = get_time(res) res = ((pd.DataFrame(results) - base_time) * 1000).round().astype(int) print(res) ```
Код для профилирования в IPython На примере временных рядов и узла `ts_naive_average`. ```py import numpy as np from fedot.core.data.data import InputData from fedot.core.pipelines.node import PipelineNode from fedot.core.pipelines.pipeline import Pipeline from fedot.core.repository.dataset_types import DataTypesEnum from fedot.core.repository.tasks import Task, TaskTypesEnum, TsForecastingParams def main(): i = 20000 j = 10 data = InputData(idx=np.arange(i), features=np.arange(i), target=np.arange(i), task=Task(TaskTypesEnum.ts_forecasting, TsForecastingParams(j)), data_type=DataTypesEnum.ts) Pipeline(PipelineNode('ts_naive_average')).fit(data) import cProfile cProfile.run('main()', filename=r'D:/profile.prof') ```
Код для построения графиков по результатам замеров ```py import matplotlib.pyplot as plt def plot_operation_perfomance(operation_id: str, data_lengths: Tuple[float], perfomance_values: Tuple[float]) -> None: """ Temporary function for plotting perfomance values and their approximate function. """ coefficients = np.polyfit(data_lengths, perfomance_values, 2) approx_data_lengths = np.linspace(data_lengths[0], data_lengths[-1], 1000) approx_perfomance_values = np.poly1d(coefficients)(approx_data_lengths) with plt.ion(): plt.scatter(data_lengths, perfomance_values, label='Perfomance values') plt.plot(approx_data_lengths, approx_perfomance_values, label='Approximation') plt.text(approx_data_lengths[-1], approx_perfomance_values[-1], operation_id, fontsize=4) plt.pause(0.1) # plt.savefig('test.pdf') ```