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

воскресенье, 29 марта 2020 г.

Deep Learning - построение искусственных нейронных сетей с использованием TensorFlow и Python


В этой статье мы собираемся разработать технику машинного обучения под названием «Глубокое обучение (искусственная нейронная сеть)» с использованием tensor flow и спрогнозировать цену акций в python. В конце этой статьи вы узнаете, как построить искусственную нейронную сеть, используя tensor flow, и как кодировать стратегию, используя прогнозы нейронной сети.

Кодирование стратегии

Импорт библиотек

Мы начнем с импорта всех необходимых библиотек. Обратите внимание, если указанная ниже библиотека еще не установлена, вам необходимо установить ее сначала в приглашении anaconda перед импортом. 


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

Numpy - это фундаментальный пакет для научных вычислений, мы будем использовать эту библиотеку для вычислений в нашем наборе данных. Библиотека импортируется с использованием псевдонима np.

Pandas поможет нам в использовании мощного объекта dataframe, который будет использоваться в коде для построения искусственной нейронной сети в Python.

Scikit-learn - бесплатная библиотека машинного обучения для Python. Она включает различные алгоритмы классификации, регрессии и кластеризации, включая машины опорных векторов. 

Matplotlib - это двухмерная библиотека визализации для Python, которая создает графики полиграфического качества в различных форматах и интерактивных средах на разных платформах.

Talib - это библиотека технического анализа, которая будет использоваться для вычисления RSI и Williams% R. Они будут использоваться как функции для обучения нашей искусственной нейронной сети. Мы могли бы добавить еще больше признаков, используя эту библиотеку.

Импорт набора данных

Мы будем использовать ежедневные данные OHLC для акций Tata Motors, торгующихся на NSE, за период с 1 января 2000 года по 30 августа 2018 года. Сначала мы импортируем наш файл набора данных с именем 'TATAMOTORS.NS.csv'. Это делается с помощью библиотеки pandas, и данные хранятся в dataframe с именем dataset. Затем мы удаляем отсутствующие значения в наборе данных с помощью функции dropna(). Мы выбираем только данные OHLC из этого набора данных, которые также будут содержать данные о дате, скорректированной цене закрытии и объеме. Мы будем строить наши входные функции, используя только значения OHLC.

Обратите внимание, что вы также можете скачать эти данные с моего GitHub.



Подготовка набора данных

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

High минус Low 
Close минус Open
Трехдневная скользящая средняя
Скользящее среднее за десять дней
Скользящее среднее за 30 дней
Стандартное отклонение за 5 дней
Индекс относительной силы
Williams %R


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



Затем мы удаляем все строки, хранящие значения NaN, используя функцию dropna().


Затем мы удаляем все данные OHLC из «dataset» и сохраняем только «8 input features» и «Output» в новом фрейме данных с именем «data».


Затем мы делаем все данные массивом np.array.


Разделение набора данных

Далее мы разбиваем весь набор данных на данные для обучения и тестирования. Обучающие данные содержат 80% всего набора данных, начиная с 1 января 2000 года, а данные испытаний содержали оставшиеся 20% набора данных. Данные были не перетасованы, а последовательно разрезаны.



Масштабирование данных и построение X, Y

Другим важным шагом в предварительной обработке данных является нормализация набора данных. Этот процесс делает среднее значение всех входных объектов равным нулю, а также преобразует их дисперсию в 1. Это гарантирует, что при обучении модели не будет смещения из-за разных масштабов всех входных объектов. Если этого не сделать, нейронная сеть может запутаться и придать больший вес тем функциям, которые имеют более высокое среднее значение, чем другие. Кроме того, наиболее распространенные функции активации нейронов сети, такие как tanh или sigmoid, определяются в интервале [-1, 1] или [0, 1] соответственно. В настоящее время часто используются активаторы rectified linear unit (ReLU), которые не ограничены осью возможных значений активации. Однако мы будем масштабировать как входы, так и цели. Мы сделаем масштабирование с помощью Sklearn MinMaxScaler. Мы создаем экземпляр переменной sc с помощью функции MinMaxScalerr(). После чего мы используем функцию fit, а затем transform.


Затем мы разделяем обучающий и тестовый наборы данных на X_train, y_train & X_test, y_test. Мы выбираем цель и предикторы из data_train и data_test. Цель, которая является повышением цены (y_train & y_test), расположена в последнем столбце data_train / test, предикторы, которые включают 8 функций (X_train & X_test) от 1-го столбца до 8-го столбца data_train/test. Весь набор данных будет выглядеть следующим образом.



Это неотъемлемая часть любого алгоритма машинного обучения, обучающие данные используются для определения весов модели. Тестовый набор данных используется, чтобы увидеть, как модель будет работать с новыми данными, которые будут введены в модель. Тестовый набор данных также помогает нам понять, насколько эффективна модель. Теперь, когда наборы данных готовы, мы можем приступить к построению искусственной нейронной сети с использованием библиотеки TensorFlow.

Построение искусственной нейронной сети

Входной, скрытые и выходной слои

Модель состоит из трех основных строительных блоков. Входной слой, скрытые слои и выходной слой. Входным слоем является 8 объектов. После входного слоя есть 3 скрытых слоя. Первый скрытый слой содержит 512 нейронов. Последующие скрытые слои всегда в два раза меньше предыдущего, что означает, что 2-й скрытый слой содержит 256 и, наконец, 3-й из 128 нейронов. После 3 скрытых слоев есть выходной слой. 



Заполнители и переменные

Искусственная нейронная сеть начинается с заполнителей. Нам нужны два заполнителя, чтобы соответствовать нашей модели: X содержит входы сети (признаки акции в момент времени T = t) и Y выход сети (движение акции в момент времени T + 1). Форма заполнителей соответствует None, n_features с [None] означает, что входные данные представляют собой 2-мерную матрицу, а выходные данные представляют собой 1-мерный вектор. Крайне важно понять, какие входные и выходные размеры нужны нейронной сети для ее правильного проектирования. Аргумент none указывает на то, что на данный момент мы еще не знаем количество наблюдений, которые проходят через граф нейронной сети в каждом пакете, поэтому мы сохраняем гибкость. Позже мы определим переменный размер пакета, который контролирует количество наблюдений на обучающий пакет. 


Помимо заполнителей, еще одним краеугольным камнем вселенной TensorFlow являются переменные. В то время как заполнители используются для хранения входных и целевых данных в графе, переменные используются в качестве гибких контейнеров, которые могут изменяться во время выполнения графа. Здесь веса и смещения представлены как переменные, чтобы адаптироваться во время тренировки. Переменные должны быть инициализированы до обучения модели.

Инициализаторы

Инициализаторы используются для инициализации переменных сети перед обучением. Поскольку нейронные сети обучаются с использованием методов численной оптимизации, отправная точка проблемы оптимизации является одним из ключевых факторов для поиска хороших решений. В Tensor flow доступны разные инициализаторы, каждый с разными подходами инициализации. Здесь мы будем использовать одну из стратегий инициализации по умолчанию tf.variance_scaling_initializer() для двух переменных веса и смещения.


Проектирование архитектуры сети

При проектировании архитектуры сети, во-первых, нам необходимо понять необходимые размерности переменных между входным, скрытыми и выходным слоями. В случае многослойного персептрона (MLP), тип сети, который мы здесь используем, второе измерение предыдущего уровня - это первое измерение в текущем слое для весовых матриц. Это означает, что каждый слой передает свой вывод в качестве входных данных на следующий слой. Измерение смещения равно второму измерению весовой матрицы текущего слоя, которое соответствует количеству нейронов в этом слое.


После определения требуемых весовых переменных и смещения необходимо указать топологию сети, архитектуру сети. Таким образом, заполнители (данные) и переменные (веса и смещения) должны быть объединены в систему последовательных умножений матриц. Кроме того, скрытые слои сети преобразуются с помощью функций активации. Функции активации являются важными элементами сетевой архитектуры, поскольку они вносят нелинейность в систему. Существует много возможных функций активации, одна из наиболее распространенных - rectified linear unit (ReLU), которая будет использоваться в этой модели.



Функция стоимости

Мы используем функцию стоимости для оптимизации модели. Функция стоимости используется для определения степени отклонения прогнозов сети от фактическими наблюдаемых целей обучения. Для задач регрессии обычно используется функция среднеквадратичной ошибки (MSE). MSE вычисляет среднеквадратичное отклонение прогнозов от целей.


Оптимизатор

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



В этой модели мы используем оптимизатор Adam (Adaptive Moment Estimation), который является расширением стохастического градиентного спуска, и является одним из оптимизаторов по умолчанию в процессе глубокого обучения.

Обучение нейронной сети

Теперь нам нужно обучить созданную нами нейронную сеть с помощью нашего обучающего набора данных. После определения заполнителей, переменных, инициализаторов, функций стоимости и оптимизаторов сети модель необходимо обучить. Обычно это делается способом mini batch training. Во время обучения извлекаются случайные выборки данных n = batch_size  из обучающего набора и передаются в сеть. Обучающий набор данных делится на пакеты n/batch_size, которые последовательно подаются в сеть. В этот момент в игру вступают заполнители X и Y. Они хранят входные и выходные данные и представляют их сети в качестве входных данных и целей.

Пакет данных с выборкой X проходит через сеть, пока не достигнет выходного уровня. Там TensorFlow сравнивает прогнозы моделей с фактическими наблюдаемыми целями Y в текущем пакете. После этого TensorFlow проводит этап оптимизации и обновляет параметры сети, соответствующие выбранной схеме обучения. После обновления весов и смещений производится выборка следующей партии, и процесс повторяется. Процедура продолжается до тех пор, пока все партии не будут представлены в сети. Один полный цикл по всем партиям называется эпохой (epoch).

Обучение сети прекращается после достижения максимального количества эпох или применения другого критерия останова, определенного пользователем. Мы прекращаем обучение сети, когда количество эпох достигает 10.


Благодаря этому наша искусственная нейронная сеть скомпилирована и готова делать прогнозы.

Прогнозирование движения цен акций

Теперь, когда нейронная сеть скомпилирована, мы можем использовать метод predict() для прогнозирования. Мы передаем X_test в качестве аргумента и сохраняем результат в переменной с именем pred. Затем мы преобразуем данные pred в dataframe и сохраняем их в другой переменной с именем y_pred. Затем мы конвертируем y_pred для хранения двоичных значений, сохраняя условие y_pred> 0.5. Теперь переменная y_pred хранит либо True, либо False, в зависимости от того, было ли прогнозируемое значение больше или меньше 0,5.


Затем мы создаем новый столбец в dataframe фрейма с заголовком столбца «y_pred» и сохраняем значения NaN в столбце. Затем мы сохраняем значения y_pred в этом новом столбце, начиная со строк тестового набора данных. Это делается путем нарезки dataset с использованием метода iloc, как показано в коде ниже. Затем мы удаляем все значения NaN из набора данных и сохраняем их в новом фрейме данных с именем trade_dataset.



Расчет доходности стратегии

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

Сначала мы вычисляем доходность, которую получит стратегия, если в конце сегодняшнего дня будет открыта длинная позиция, а в конце следующего дня закрыта. Мы начинаем с создания нового столбца с именем «Tomorrows Returns» в trade_dataset и сохраняем в нем значение 0. Мы используем десятичную запись, чтобы указать, что в этом новом столбце будут храниться значения с плавающей запятой. Далее, мы храним в нем журнал доходности за сегодня, то есть логарифм цены закрытия сегодня, деленный на цену закрытия вчера. Затем мы смещаем эти значения вверх на один элемент, чтобы завтрашние доходы сохранялись по сравнению с сегодняшними ценами.


Далее мы рассчитаем доходность стратегии. Мы создаем новый столбец под заголовком «Strategy_Returns» и инициализируем его значением 0, чтобы указать хранение значений с плавающей запятой. Используя функцию np.where(), мы затем сохраняем значение в столбце «Tomorrows Returns», если значение в столбце «y_pred» хранит True (длинная позиция), иначе мы сохраним отрицательное значение в столбце «Tomorrows Returns» (короткая позиция); в столбце «Strategy Returns».


Теперь мы рассчитываем совокупную доходность как для рынка, так и для стратегии. Эти значения вычисляются с использованием функции cumsum().



Построение графика доходности

Теперь мы построим график доходности рынка и нашей стратегии, чтобы визуализировать, как наша стратегия работает по сравнению с рынком. Затем мы используем функцию plot для построения графиков доходностей, используя кумулятивные значения, хранящиеся в dataframe trade_dataset. Затем мы создаем легенду и выводим график, используя функции legend() и show() соответственно. График, показанный ниже, является выводом данного кода. Зеленая линия представляет доход, полученный с помощью стратегии, а красная линия представляет рыночный доход.




Заключение

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

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

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

Вы также можете скачать код Pyhon и набор данных из моего GitHub A/C

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

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