рекомендации

понедельник, 2 ноября 2020 г.

Предсказание поведения рынков с помощью eXtreme Gradient Boosting (XGBoost)


В последние годы машинное обучение вызвало большой интерес в связи с его прибыльным применением в трейдинге. Многочисленные модели машинного обучения, такие как линейная/логистическая регрессия, машины опорных векторов, нейронные сети, модели на основе деревьев и т. д., испытываются и применяются в попытке анализировать и прогнозировать рынки. Исследователи обнаружили, что некоторые модели более успешны по сравнению с другими моделями машинного обучения. eXtreme Gradient Boosting, также называемый XGBoost, является одной из таких моделей машинного обучения, которая получила восторженные отзывы от практиков машинного обучения.

В этом посте мы расскажем об основах XGBoost, выигрышной модели для многих соревнований kaggle. Затем мы пытаемся разработать модель прогнозирования курса ценной бумаги XGBoost, используя пакет «xgboost» в R.

Основы XGBoost и связанные концепции

Модель eXtreme Gradient Boosting (XGBoost), разработанная Тианки Ченом, представляет собой реализацию структуры gradient boosting. Алгоритм Gradient Boosting - это метод машинного обучения, используемый для построения прогнозных древовидных моделей.

Boosting - это метод ансамбля, при котором новые модели добавляются для исправления ошибок, допущенных существующими моделями. Модели добавляются последовательно до тех пор, пока дальнейшие улучшения не прекратятся.

В методе ансамбля используется модель ансамбля деревьев, которая представляет собой набор деревьев классификации и регрессии (CART). Ансамблевой подход используется потому, что одно дерево CART, как правило, не обладает сильной предсказательной силой. При использовании набора CART (т.е. модели ансамбля деревьев) учитывается сумма прогнозов нескольких деревьев.

Градиентный бустинг - это подход, при котором создаются новые модели, которые предсказывают остатки или ошибки предыдущих моделей, а затем складываются вместе, чтобы сделать окончательный прогноз.

Задача модели XGBoost определяется следующим образом:

Obj = L + Ω

Где:
L - функция потерь, которая контролирует предсказательную силу, 
Ω - компонент регуляризации, контролирующий простоту и переобучение.

Функция потерь (L), которую необходимо оптимизировать, может представлять собой среднеквадратическую ошибку для регрессии, Logloss для двоичной классификации или mlogloss для мультиклассовой классификации.

Компонент регуляризации (Ω) зависит от количества листьев и оценки прогноза, присвоенной листьям в модели ансамбля деревьев.

Он называется градиентным бустингом, потому что в нем используется алгоритм градиентного спуска для минимизации потерь при добавлении новых моделей. Алгоритм градиентного бустинга поддерживает задачи как регрессии, так и классификации.

Пример модели XGBoost:

Мы будем использовать пакет R «xgboost» для создания образца модели XGBoost. Вы можете обратиться к документации пакета «xgboost» здесь.

Установка и загрузка библиотеки xgboost

Устанавливаем библиотеку xgboost с помощью функции install.packages. Для загрузки этого пакета мы используем функцию library. Мы также загружаем другие пакеты, необходимые для запуска кода.

install.packages("xgboost")
# Load the relevant libraries
library(quantmod); library(TTR); library(xgboost);
Создаем входные характеристики и целевую переменную. Мы берем 5-летние данные OHLC и данные объемов торговли по активу и вычисляем технические индикаторы (входные характеристики), используя этот набор данных. Вычисляемые индикаторы включают Relative Strength Index (RSI), Average Directional Index (ADX) и Parabolic SAR (SAR). Мы создаем лаг в вычисляемых индикаторах, чтобы избежать предвзятости прогнозирования. Это дает нам входные признаки для построения модели XGBoost. Поскольку это образец модели, мы включили только несколько индикаторов для построения нашего набора входных признаков.

# Read the stock data 
symbol = "ACC"
fileName = paste(getwd(),"/",symbol,".csv",sep="") ; 
df = as.data.frame(read.csv(fileName))
colnames(df) = c("Date","Time","Close","High", "Low", "Open","Volume")
# Define the technical indicators to build the model 
rsi = RSI(df$Close, n=14, maType="WMA")
adx = data.frame(ADX(df[,c("High","Low","Close")]))
sar = SAR(df[,c("High","Low")], accel = c(0.02, 0.2))
trend = df$Close - sar
# create a lag in the technical indicators to avoid look-ahead bias 
rsi = c(NA,head(rsi,-1)) 
adx$ADX = c(NA,head(adx$ADX,-1)) 
trend = c(NA,head(trend,-1))
Наша цель - предсказать направление ежедневного изменения цены акций (вверх/вниз), используя эти входные признаки. Это проблема двоичной классификации. Мы вычисляем дневное изменение цены и присваиваем ему значение 1, если дневное изменение цены положительное. Если изменение цены отрицательное, мы присваиваем нулевое значение.

# Create the target variable
price = df$Close-df$Open
class = ifelse(price > 0,1,0)
Объединяем входные признаки в матрицу. Входные объекты и целевая переменная, созданная на предыдущем шаге, объединяются в единую матрицу. Мы используем матричную структуру в модели XGBoost, поскольку библиотека xgboost принимает данные в матричном формате.
# Create a Matrix
model_df = data.frame(class,rsi,adx$ADX,trend)
model = matrix(c(class,rsi,adx$ADX,trend), nrow=length(class))
model = na.omit(model)
colnames(model) = c("class","rsi","adx","trend")
Разделяем набор данных на обучающие и тестовые данные. На следующем шаге мы разделим набор данных на обучающие и тестовые данные. Используя этот обучающий и тестовый наборы данных, мы создаем соответствующий набор входных признаков и целевую переменную.

# Split data into train and test sets 
train_size = 2/3
breakpoint = nrow(model) * train_size

training_data = model[1:breakpoint,]
test_data = model[(breakpoint+1):nrow(model),]
# Split data training and test data into X and Y
X_train = training_data[,2:4] ; Y_train = training_data[,1]
class(X_train)[1]; class(Y_train)

X_test = test_data[,2:4] ; Y_test = test_data[,1]
class(X_test)[1]; class(Y_test)
Обучение модели XGBoost на обучающем наборе данных. Мы используем функцию xgboost для обучения модели. Аргументы функции xgboost показаны на картинке ниже.

Аргумент data в функции xgboost предназначен для набора данных входных признаков. Он принимает матрицу, dgCMatrix или локальный файл данных. Аргумент nrounds относится к максимальному количеству итераций (т. е. количеству деревьев, добавленных в модель). Аргумент obj относится к настроенной целевой функции. Он возвращает градиент и градиент второго порядка с заданным прогнозом и dtrain.
# Train the xgboost model using the "xgboost" function
dtrain = xgb.DMatrix(data = X_train, label = Y_train)
xgModel = xgboost(data = dtrain, nround = 5, objective = "binary:logistic")
Выходные данные - выходными данными является ошибка классификации в наборе обучающих данных.



Перекрестная проверка

Мы также можем использовать функцию перекрестной проверки xgboost, то есть xgb.cv. В этом случае исходная выборка случайным образом разбивается на nfold подвыборок равного размера. Из nfold подвыборок одна подвыборка сохраняется в качестве проверочных данных для тестирования модели, а оставшиеся (nfold - 1) подвыборки используются в качестве обучающих данных. Затем процесс перекрестной проверки повторяется много раз, при этом каждая из nfold подвыборок используется в качестве проверочных данных ровно один раз.

# Using cross validation
dtrain = xgb.DMatrix(data = X_train, label = Y_train)
cv = xgb.cv(data = dtrain, nround = 10, nfold = 5, objective = "binary:logistic")
Вывод - xgb.cv возвращает объект data.table, содержащий результаты перекрестной проверки.


Прогнозы на основе тестовых данных

Чтобы делать прогнозы на новом наборе данных (то есть на тестовых данных), мы применяем к нему обученную модель XGBoost, которая дает ряд чисел.

# Make the predictions on the test data
preds = predict(xgModel, X_test)
# Determine the size of the prediction vector
print(length(preds))
# Limit display of predictions to the first 6
print(head(preds))
Вывод:


Эти числа не похожи на двоичную классификацию {0, 1}. Следовательно, мы должны выполнить простое преобразование, прежде чем мы сможем использовать эти результаты. В примере кода, показанном ниже, мы сравниваем предсказанное число с порогом 0,5. Пороговое значение может быть изменено в зависимости от цели разработчика модели, показателей (например, оценка F1, точность), которые разработчик модели хочет отслеживать и оптимизировать.

prediction = as.numeric(preds > 0.5)
print(head(prediction))
Вывод:


Оценка эффективности модели

Для оценки эффективности модели можно использовать различные метрики оценки. В нашем примере мы вычислим простой показатель - среднюю ошибку. Он сравнивает прогнозируемую оценку с порогом 0,50.

Например: если прогнозируемая оценка меньше 0,50, то выражение (preds> 0,5) дает значение 0. Если это значение не равно фактическому результату из набора тестовых данных, то оно принимается как неправильный результат. 

Мы сравниваем все прогнозы с соответствующими точками данных в Y_test и вычисляем среднюю ошибку. Код для оценки эффективности приведен ниже. В качестве альтернативы мы можем использовать процент попаданий или создать матрицу ошибок для оценки эффективности модели.

# Measuring model performance
error_value = mean(as.numeric(preds > 0.5) != Y_test)
print(paste("test-error=", error_value))
Вывод:


Строим набор важности признаков - мы можем найти самые важные признаки в модели с помощью функции xgb.importance.

# View feature importance from the learnt model
importance_matrix = xgb.importance(model = xgModel)
print(importance_matrix)

Строим деревья XGBoost:

Наконец, мы можем построить деревья XGBoost, используя функцию xgb.plot.tree. Чтобы ограничить график определенным количеством деревьев, мы можем использовать аргумент n_first_tree. Если он равен NULL, строятся все деревья модели.

# View the trees from a model
xgb.plot.tree(model = xgModel)
# View only the first tree in the XGBoost model
xgb.plot.tree(model = xgModel, n_first_tree = 1)
Вывод:



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

Комментариев нет:

Отправить комментарий