Повышение эффективности ThymeBoost
Фреймворк ThymeBoost, по своей сути, представляет собой просто алгоритм повышения градиента, основанный на стандартных методах временных рядов. Это означает, что инфраструктура в значительной степени зависит от эффективности и скорости базового метода. Повышение и дополнительная логика добавляют, как мы увидим в этой статье, не только точность, но и вычисление. Большая часть этой тяжелой работы ранее выполнялась с помощью StatsModels для таких вещей, как ETS и ARIMA, но использование пакета статистического прогнозирования Nixtla: StatsForecast может повысить и скорость, и точность. Создание ThymeBoost и StatsForecast идеального союза для прогнозирования временных рядов.
Хороший TLDR для этой статьи:
StatsForecast быстрее, чем StatsModels, а ThymeBoost обеспечивает точность увеличения.
Введение
Во-первых, если вы еще не слышали о ThymeBoost, я рекомендую вам ознакомиться с моей предыдущей статьей, в которой представлен достойный обзор. В новейшей версии я добавил StatsForecast в качестве дополнительной зависимости. Чтобы запустить эти примеры, вам необходимо установить его:
pip install StatsForecast
И на всякий случай обновите ThymeBoost:
pip install ThymeBoost --upgrade
Теперь, когда мы это убрали, основной мясо и картошка этой статьи будет бенчмаркинг на наборе данных Weekly M4, чтобы увидеть, как все эти модели работают как по точности, так и по скорости. Все наборы данных с открытым исходным кодом и живут на M-соревнованиях github. Он разделен на стандартные поезда и тесты, поэтому мы будем использовать CSV-файл поезда для подбора, а тестовый CSV-файл — только для оценки с помощью SMAPE.
Не стесняйтесь проверить это с другими наборами данных и дайте мне знать, как они работают!
Основная цель этого — проанализировать, как новые методы складываются в инфраструктуре повышения, и, в конечном итоге, увидеть, как их добавление в инфраструктуру ThymeBoost может обеспечить повышение точности.
Сравнительный анализ методов
Для начала мы попробуем наиболее ресурсоемкий метод в ThymeBoost: AutoArima. Раньше это делалось с PmdArima, теперь мы можем протестировать с помощью StatsForecast, просто передав trend_estimator=‘fast_arima’
при настройке с ThymeBoost. Давайте взглянем на некоторый код, в котором мы сначала создаем наш набор данных, а затем запускаем ThymeBoost:
from tqdm import tqdm from statsforecast.models import ETS, AutoARIMA from ThymeBoost import ThymeBoost as tb tqdm.pandas() train_df = pd.read_csv(r'm4-weekly-train.csv') test_df = pd.read_csv(r'm4-weekly-test.csv') forecast_horizon = len(test_df.columns) - 1 train_df = train_df.rename({'V1': 'ID'}, axis=1) train_long = pd.wide_to_long(train_df, ['V'], 'ID', 'Date') test_df = test_df.rename({'V1': 'ID'}, axis=1) test_df = pd.wide_to_long(test_df, ['V'], 'ID', 'Date') train_long = train_long.dropna() train_df = train_long.reset_index() train_df.index = train_df['ID'] train_df = train_df.drop('ID', axis = 1) X = train_long X = X.reset_index()
- Примечание: этот код, вероятно, очень неэффективен при манипулировании данными, и я уверен, что есть лучшие способы сделать это, это было просто то, что я собрал вместе, и это работает для теста. Время не включает время, необходимое для запуска этого кода.
В любом случае, теперь у нас есть данные для обучения, давайте взглянем на функцию подбора:
def grouped_forecast(df): y = df['V'].values boosted_model = tb.ThymeBoost(verbose=0) output = boosted_model.fit(y, seasonal_period=None, trend_estimator=['fast_arima']) predicted_output = boosted_model.predict(output, forecast_horizon, trend_penalty=True) predictions = predicted_output['predictions'] return predictions
Здесь мы просто создаем функцию, которая будет передана, когда мы выполним группировку и применим:
def counter(df): df['counter'] = np.arange(2, len(df) + 2) return df predictions = X.groupby('ID').progress_apply(grouped_forecast) predictions = predictions.reset_index() predictions = predictions.groupby('ID').apply(counter) test_df = test_df.reset_index() benchmark_df = predictions.merge(test_df, left_on=['ID', 'counter'], right_on=['ID', 'Date']) def smape(A, F): return 100/len(A) * np.sum(2 * np.abs(F - A) / (np.abs(A) + np.abs(F))) tqdm.pandas() def grouped_smape(df): return smape(df['V'], df['predictions']) test = benchmark_df.groupby('ID').progress_apply(grouped_smape) print(np.mean(test))
Затем мы просто получаем среднее значение SMAPE для заданных результатов, здесь все должно быть хорошо, но дайте мне знать, если есть какие-либо ошибки, которые могут исказить тест.
Это даст вам среднее значение SMAPE 8,61 и займет примерно 10 минут.
Далее, давайте просто запустим Auto Arima от Nixtla и посмотрим, как она работает.
Мы просто изменим эту функцию прогноза groupby на:
def grouped_forecast(df): y = df['V'].values ar_model = AutoARIMA().fit(y) predictions = pd.DataFrame(ar_model.predict(forecast_horizon)['mean'], columns=['predictions']) return predictions
Повторный запуск приведенного выше фрагмента расчета SMAPE даст вам SMAPE 8,93 и время примерно 4 минуты.
Хорошо, отлично, мы продемонстрировали некоторый прирост точности, просто улучшив процедуру Auto-Arima. Это не должно вас шокировать, так как я показал очень похожие результаты в статье о глубоком погружении Gradient Boosted Arima. Но я хочу предостеречь, что усиление не является панацеей и не всегда улучшает Арима, но все же это интересное наблюдение.
Следующий шаг должен быть очевиден. Мы рассмотрели «быстрый» Auto-Arimain ThymeBoost, а также Auto-Arima без бустинга от StatsForecast. Далее мы должны увидеть, как они сочетаются с использованием Auto-Arimain ThymeBoost от PmdArima.
Если вы использовали этот код до сих пор, пристегнитесь.
Этот следующий бит займет некоторое время…
def grouped_forecast(df): y = df['V'].values boosted_model = tb.ThymeBoost(verbose=0, n_rounds=None) output = boosted_model.fit(y, seasonal_period=None, trend_estimator=['arima'], arima_order='auto') predicted_output = boosted_model.predict(output, forecast_horizon, trend_penalty=True) predictions = predicted_output['predictions'] return predictions
А результаты?
SMAPE 8,78, но это заняло 90 минут. Похоже, что ускорение Pmd Arima превосходит StatsForecast от Nixtla из коробки, но это занимает довольно много времени.
Arima — это не все предложения в StatsForecast, другая реализация — это метод ETS. С этими новыми методами мы действительно можем использовать эти более быстрые реализации в методе autofit
ThymeBoost. Для этого нам просто нужно передать fast=True
при вызове autofit. Тогда новая функция прогноза будет выглядеть так:
def grouped_forecast(df): y = df['V'].values boosted_model = tb.ThymeBoost(verbose=0, n_rounds=None) output = boosted_model.autofit(y, seasonal_period=[52], optimization_type='grid_search', optimization_strategy='holdout', lag=26, optimization_metric='smape', verbose=False, fast=False ) predicted_output = boosted_model.predict(output, forecast_horizon, trend_penalty=True) predictions = predicted_output['predictions'] return predictions
Это приводит к SMAPE 7,88 и занимает около 80 минут. Определенно лучшая точность plug-and-play из всех протестированных, но мы немного жульничаем, выбирая модель.
Следует отметить, что передавать сезонную длину 52 в методы StatsForecast — не лучшая идея. Для ETS это ошибки, а для Auto-Arima это занимает слишком много времени. Это одна из областей, в которой использование преимуществ работы ThymeBoost на самом деле увеличивает скорость, поскольку длительные сезонные периоды в настройке ARIMA занимают значительно больше времени.
Были протестированы несколько других методов, и вы можете просмотреть результаты тестов ниже:
Что касается аббревиатур:
- ТБ: ThymeBoost
- СФ: СтатистикаПрогноз
- NS: Несезонный
- Mult: Мультипликативная сезонность
- Быстро: ThymeBoost использует StatsForecast под капотом
На высоком уровне лучше всего работает метод Fast AutoFit от ThymeBoost. По какой-то странной причине использование ThymeBoost с сезонностью и быстрой Arima работает не слишком хорошо, фактически это значительно хуже, чем использование Auto-Arima PmdArima. Еще одно наблюдение заключается в том, что усиление простых методов ETS из StatsForecast может ухудшить точность по сравнению с обычной подгонкой с помощью методов без повышения. Это может измениться, если мы изменим параметр global_cost
в функции подгонки, поскольку значение по умолчанию может не всегда быть оптимальным.
Заключение
В новейшей версии ThymeBoost есть дополнительные возможности для использования методов StatsForecast. Благодаря этому мы можем увидеть повышенную скорость и, возможно, точность по сравнению с предыдущей реализацией.
Как и в случае с хорошим пирогом, в основе ThymeBoost должно быть хорошее тесто. StatsForecast может быть лучшим тестом, чем StatsModels. Повышение градиента — это просто посыпка сверху.
Если вам понравилась эта статья, вы можете ознакомиться с другими моими постами, связанными с временными рядами: