Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1182-fix #1215

Merged
merged 14 commits into from
Dec 12, 2023
Merged

1182-fix #1215

merged 14 commits into from
Dec 12, 2023

Conversation

Lopa10ko
Copy link
Collaborator

@Lopa10ko Lopa10ko commented Dec 1, 2023

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
Copy link

pep8speaks commented Dec 1, 2023

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! 🍻

Comment last updated at 2023-12-12 12:42:04 UTC

@kasyanovse kasyanovse added research test The additon or modification of the unit test labels Dec 1, 2023
@kasyanovse kasyanovse self-assigned this Dec 1, 2023
@kasyanovse kasyanovse linked an issue Dec 1, 2023 that may be closed by this pull request
@kasyanovse kasyanovse marked this pull request as draft December 1, 2023 12:22
Copy link

codecov bot commented Dec 1, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

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
@@            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     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kasyanovse kasyanovse marked this pull request as ready for review December 4, 2023 11:36
test/integration/models/test_model.py Outdated Show resolved Hide resolved
@aPovidlo
Copy link
Collaborator

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

@aPovidlo
Copy link
Collaborator

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

@kasyanovse
Copy link
Collaborator

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

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

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

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

@aPovidlo
Copy link
Collaborator

aPovidlo commented Dec 12, 2023

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

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

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

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

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

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

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

@kasyanovse
Copy link
Collaborator

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

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

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

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

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

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

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

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

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

@aPovidlo
Copy link
Collaborator

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

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

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

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

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

Хорошо.

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

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

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

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

@kasyanovse
Copy link
Collaborator

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

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

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

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

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

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

@Lopa10ko
Copy link
Collaborator Author

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

  • Сконфигурировать тест так, чтобы проходили rf и rfr
  • Убрать пресет fast-train у ransac_non_lin_reg
  • Убрать тэг non-default ransac_non_lin_reg
  • Определить причину медленной работы ts_naive_average, lagged и diff_filter
    • Провести многократные измерения скорости, определить среднее
      • lagged - проблема не воспроизвелась
      • ts_naive_average - проблема воспроизвелась, рост времени выполнения квадратичный или быстрее
      • diff_filter - почти строго линейная зависимость времени выполнения от количества данных, но сам фильтр медленный и на объемах в несколько тысяч строк время выполнения измеряется секундами.
    • Запустить эти операции в профилировщике
      • ts_naive_average - нужно отрефакторить split_rolling_slices и _average в NaiveAverageForecastImplementation
      • diff_filter - скорость завязана на сторонние библиотеки.
    • Убрать тег fast_train для diff_filter
    • Отрефакторить ts_naive_average
  • Посмотреть для каких еще моделей допустим тег fast-train
  • Посмотреть для каких моделей недопустим тег fast-train
  • Реализовать повторные замеры для медленных случаев
Измерение скорости различных операций после смены пресетов.
Название операции Тэг 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
test-1

Операции, которые могут быть с пресетом 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

Код для тестирования скорости операций в IPython

На примере временных рядов и узла lagged.

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.

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')
Код для построения графиков по результатам замеров
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')

@Lopa10ko Lopa10ko merged commit dd7a75e into master Dec 12, 2023
6 checks passed
@kasyanovse kasyanovse deleted the 1182-fix branch December 12, 2023 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
test The additon or modification of the unit test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New test for operation speed measuring
5 participants