НАУКА ДАННЫХ, ВИЗУАЛИЗАЦИЯ ДАННЫХ

Прогнозирование временных рядов с помощью XGBoost

Учебное пособие по написанию кода для реализации модели XGBoost в Jupyter Notebook.

В этой статье я расскажу о том, как построить XGBoost model для обработки одномерного набора данных по электроэнергии с временными рядами. Цель состоит в том, чтобы создать модель, которая позволит нам с уверенностью прогнозировать будущее потребление электроэнергии в Китае. К концу этой статьи вы сможете понять, почему мы должны использовать XGBoost и как написать код для реализации модели в Jupyter Notebook.

Скачать данные

Эти данные были изначально загружены из онлайн-базы данных, созданной и поддерживаемой Исследовательским отделом Федерального резервного банка Сент-Луиса (FRED). Если вы хотите продолжить, вы можете скачать набор данных, размещенный на моем Github.

Введение в XGBoost

XGBoost - это оптимизированная библиотека с распределенным повышением градиента, разработанная для обеспечения высокой скорости вычислений и производительности. В Python XGBoost library дает вам модель контролируемого машинного обучения, которая соответствует структуре Gradient Boosting. Для создания прогнозов он использует алгоритм увеличения параллельного дерева. Пакет XGBoost в Python может обрабатывать файлы текстового формата LIBSVM, файлы CSV, Numpy 2D-массивы, SciPy 2D разреженные массивы, cuDF DataFrames и Pandas DataFrames. В этом примере мы будем использовать файл CSV. Вы можете установить XGBoost, набрав в командной строке следующее:

pip install xgboost

Импорт зависимостей

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

Эти модули вызываются, чтобы мы могли использовать их в нашем коде. В этом руководстве будут использоваться модули NumPy, Pandas, Plotly, sklearn и XGBoost modules.

import pandas as pd
import numpy as np
import xgboost as xgb
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score, KFold
import plotly.express as px
import plotly.figure_factory as ff
import plotly.graph_objs as go
import chart_studio
import chart_studio.plotly as py 

Загрузка данных

Мы используем Pandas для импорта файла CSV - «CHNPRENEL01MLM.CSV» с заголовками. Давайте напечатаем первые 10 элементов нашего набора данных, чтобы увидеть, что в нем содержится!

#Read the dataset and print the first 10 elements of the dataset
data = pd.read_csv('CHNPRENEL01MLM.csv')
data.head(10)

Как видите, этот набор данных содержит данные о производстве электроэнергии из Китая. Эти числа указаны в гигаватт-часах и не корректируются с учетом сезонных колебаний. Теперь давайте проверим типы данных наших столбцов, присутствующих в Pandas DataFrame data, используя встроенное свойство dtypes.

data.dtypes
DATE            object
Electricity    float64
dtype: object

Мы ясно видим, что этот dataframe содержит столбец DATE , который нужно изменить на Pandas datetimeformat.

data['DATE'] = pd.to_datetime(data.DATE)

Постройте столбцы "Год" и "Месяц"

На этом этапе мы извлечем столбцы Year и Month из столбца DATE, используя встроенное свойство DatetimeIndex. Мы должны выполнить этот шаг, чтобы сделать DataFrame доступным для чтения для структуры данных «DMatrix», которая XGBoost необходима для правильного функционирования в Python.

data['Year'] = pd.DatetimeIndex(data['DATE']).year
data['Month'] = pd.DatetimeIndex(data['DATE']).month

На этом этапе мы быстро проверим форму нашего DataFrame. В настоящее время у нас есть 4 столбца и 256 строк данных.

# check the number of rows and columns in DataFrame
print(data.shape)
(256, 4)

Структура данных DMatrix

Чтобы запустить набор данных с XGBoost, необходимо, чтобы данные были введены в структуру DMatrix data. Он оптимизирует как эффективность памяти, так и скорость обучения XGBoost model.

Теперь мы разделим целевую переменную - «Электричество» и остальные переменные, используя .iloc для подмножества данных. Это необходимо сделать, чтобы наши данные были совместимы с DMatrix’s structure.

X, y =  data.loc[:,['Month', 'Year']].values, data.loc[:,'Electricity'].values
data_dmatrix = xgb.DMatrix(X,label=y)

Поезд-тестовый сплит

Затем мы создадим набор данных для обучения и тестирования, используя функцию train_test_split из модуля sklearn’s model_selection. Обучающий набор будет содержать известные выходные данные, и модель будет учиться на этих данных, в то время как набор тестирования будет использоваться для проверки прогноза нашей модели.

Данные обучения будут составлять 80% данных об электричестве, а данные тестирования - все остальное. Мы будем использовать свойство random_state, чтобы наши разделенные наборы данных не менялись каждый раз, когда мы запускаем функцию.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)

XGBRegressor

В этом конкретном примере мы будем использовать XGBRegressor class с гиперпараметрами, переданными в качестве аргументов, для оптимизации нашей модели. Мы выберем целевую функцию потерь «reg:squarederror» для прогнозирования стоимости электроэнергии. Другие функции потерь, включенные в пакет для решения задач регрессии: reg:squaredlogerror, reg:logistic, reg:pseudohubererror, reg:gamma и reg:tweedie. Однако ни одна из этих функций не дала мне результатов, которые были бы такими же хорошими, как результаты, полученные при использовании reg:squarederror. Здесь используются и другие гиперпараметры:

n_estimators — Этот параметр определяет количество раундов повышения.

max_depth — Этот параметр определяет максимальную глубину дерева для базовых учащихся.

learning_rate - Этот параметр указывает на ускоряющуюся скорость обучения («eta» xgb).

subsample — Этот параметр определяет коэффициент подвыборки обучающего набора данных.

colsample_bytree - этот параметр обеспечивает соотношение подвыборки столбцов при построении каждого дерева.

reg_mod = xgb.XGBRegressor(objective='reg:squarederror',
    n_estimators=1000,
    learning_rate=0.10,
    subsample=0.5,
    colsample_bytree=1, 
    max_depth=5,
)
reg_mod.fit(X_train, y_train)
XGBRegressor(base_score=0.5, booster='gbtree', colsample_bylevel=1,
             colsample_bynode=1, colsample_bytree=1, gamma=0, gpu_id=-1,
             importance_type='gain', interaction_constraints='',
             learning_rate=0.1, max_delta_step=0, max_depth=5,
             min_child_weight=1, missing=nan, monotone_constraints='()',
             n_estimators=1000, n_jobs=8, num_parallel_tree=1, random_state=0,
             reg_alpha=0, reg_lambda=1, scale_pos_weight=1, subsample=0.5,
             tree_method='exact', validate_parameters=1, verbosity=None)

Прогнозы

Затем мы будем использовать XGBRegressor , чтобы соответствовать данным обучения, делать прогнозы на основе данных тестирования и сохранять их.

reg_mod.fit(X_train,y_train)

predictions = reg_mod.predict(X_test)

Метрики точности

После того, как мы построили модель, мы можем проверить ее точность, вычислив оценку RMSE и оценку R-квадрат.

RMSE (среднеквадратичная ошибка) оценщика параметра генеральной совокупности - это квадратный корень из среднеквадратичной ошибки (MSE). Среднеквадратичная ошибка определяется как ожидаемое значение квадрата разницы между оценкой и параметром. Это сумма дисперсии и квадрата смещения.

Значение R-квадрата, обозначаемое R2 - это статистическая мера, которая вычисляет долю вариации в зависимой переменной, которая может быть отнесена к независимой переменной.

rmse = np.sqrt(mean_squared_error(y_test, predictions))
print("RMSE: %f" % (rmse))
RMSE: 13379.472413
from sklearn.metrics import r2_score
r2 = np.sqrt(r2_score(y_test, predictions))
print("R_Squared Score : %f" % (r2))
R_Squared Score : 0.997134

Оценка R-квадрат 99,7% и RMSE 13 379 указывают на то, что у нас есть удовлетворительная модель, которую можно применить для прогнозирования темпов потребления электроэнергии в будущем.

Тест против прогнозируемых значений

Мы можем визуализировать исходные и прогнозируемые тестовые данные на графике с помощью библиотеки Plotly. Для этого я создам пустой DataFrame и назначу проверенные и прогнозируемые значения result DataFrame.

# Creating an empty Dataframe with column names only
result = pd.DataFrame(columns=['Time', 'Test', 'Predicted'])
result['Time'] = pd.date_range(start='1/1/2000', periods=52, freq='M')
result['Test'] = y_test
result['Predicted'] = predictions
#Using Plotly to build the graph
fig = go.Figure()
fig.add_trace(go.Scatter(x=result['Time'], y=result['Test'],
                    mode='lines',
                    name='Test'))
fig.add_trace(go.Scatter(x=result['Time'], y=result['Predicted'],
                    mode='lines',
                    name='Predicted'))

# Edit the layout
fig.update_layout(title='Test vs Predicted Values',
                   xaxis_title='Months',
                   yaxis_title='Electricity (GWh)',
                   template='gridon')

fig.show()

Прогнозируемые значения

Наконец, последний фрагмент кода распечатает значения потребления электроэнергии до 2026 года.

df=pd.DataFrame(predictions, columns=['pred']) 
df['date'] = pd.date_range(start='2/28/2021', periods=len(df), freq='M')
fig = px.line(df, x="date", y="pred")
# Edit the layout
fig.update_layout(title='China Electricity Consumption Forecast',
                   xaxis_title='Date',
                   yaxis_title='Electricity - GWh',
                   template='gridon')
fig.show()

Заключение

Это пошаговое руководство для всех, кто начинает с XGBoost и требует использовать этот подход контролируемого машинного обучения для решения проблем регрессии. Мы рассмотрели, как сформировать набор данных, чтобы он соответствовал структуре DMatrix data, присущей модели XGBoost . Более того, вы применили различные параметры, используемые для оптимизации вашей модели с помощью XGBRegressor class.

Наконец, мы визуализировали тестовые, прогнозируемые и прогнозируемые значения электроэнергии, полученные из обученной модели XGBoost .

Чтобы просмотреть полный код, посетите мой репозиторий Github.

Ресурсы

  1. Https://xgboost.readthedocs.io/en/latest/
  2. Https://github.com/rishabh89007/China_Electricity_Consuming
  3. Https://fredhelp.stlouisfed.org/fred/about/about-fred/what-is-fred/
  4. Https://ec.europa.eu/eurostat/cros/content/root-mean-square-error-rmse_en
  5. Https://condor.depaul.edu/sjost/it223/documents/correlation.htm

Надеюсь, вы нашли это полезным. Спасибо за чтение.