НАУКА ДАННЫХ, ВИЗУАЛИЗАЦИЯ ДАННЫХ
Прогнозирование временных рядов с помощью 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 datetime
format.
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.
Ресурсы
- Https://xgboost.readthedocs.io/en/latest/
- Https://github.com/rishabh89007/China_Electricity_Consuming
- Https://fredhelp.stlouisfed.org/fred/about/about-fred/what-is-fred/
- Https://ec.europa.eu/eurostat/cros/content/root-mean-square-error-rmse_en
- Https://condor.depaul.edu/sjost/it223/documents/correlation.htm
Надеюсь, вы нашли это полезным. Спасибо за чтение.