Недавно я наткнулся на одну из новинок от AWS - Amazon SageMaker.
Amazon SageMaker - это полностью управляемая платформа, которая позволяет разработчикам и специалистам по обработке данных быстро и легко создавать, обучать и развертывать модели машинного обучения в любом масштабе.
Теперь я использовал некоторые из моделей машинного обучения, которые AWS предоставлял в прошлом для линейной регрессии, и я не был полностью поражен, однако у SageMaker есть пара функций, которые выглядят действительно многообещающими.
Возможно, лучшая функция SageMaker - это размещенные на хосте Jupyter Notebooks. Мне нравится интеграция уценки и графиков / визуальных элементов с моим кодом при изучении моделей.
Я должен предварять это руководство двумя утверждениями:
- Я не претендую на знание Python или ML. Если вы столкнетесь с ошибкой, недоразумением или «плохим» способом написания Python, пожалуйста, дайте мне знать. Я пишу алгоритмы машинного обучения как хобби, а не как карьеру.
- Я пишу это, поскольку впервые смотрю на SageMaker, так что могут быть «лучшие» способы делать что-то.
В любом случае давайте рассмотрим простой пример линейной регрессии с SageMaker!
Что мы построим
При тестировании предварительно созданных алгоритмов машинного обучения мне нравится выполнять прогон для проверки сходимости / производительности модели, предоставляя ей данные, которые, как я знаю, имеют совершенно линейную зависимость.
В этом примере я собираюсь взять некоторые данные матчей AFL (Австралийский футбол по правилам) и попытаться найти взаимосвязь между статистикой матча и очками Fantasy. Очки фэнтези рассчитываются путем линейной комбинации подмножества статистики матча. Статистика и линейные веса являются общедоступными и известными, что означает, что мы можем проверить, насколько близко модель подходит к их поиску.
Набор данных, который я буду использовать для этого примера, можно найти здесь в форме csv.
Подготовка к настройке
Шаг 1. Настройте S3 и IAM
Чтобы использовать SageMaker, вам понадобится корзина S3 для хранения моделей, данных и результатов. Убедитесь, что у вас есть корзина.
В этом упражнении вы можете использовать test.sagemeaker.your.name
Вам также необходимо настроить роль пользователя IAM, чтобы SageMaker мог получить доступ к корзине S3 для чтения / записи данных.
Выберите любое имя для этой роли доступа IAM, просто убедитесь, что вы предоставили этой роли программный доступ.
В разделе разрешений для этого пользователя вы можете перейти к «Прикрепить существующие политики напрямую» и найти AmazonS3FullAccess и AmazonSageMakerFullAccess.
После того, как вы создали IAM, вам нужно будет скопировать User ARN, который доступен в сводке пользователя для этой роли IAM. Это понадобится вам для настройки экземпляра Notebook в SageMaker.
2. Создайте экземпляр записной книжки в SageMaker
Просто нажмите Создать новый экземпляр на панели управления SageMaker и дайте своему экземпляру Notebook имя. В поле ввода роли IAM вам нужно будет выбрать Введите настраиваемую роль ARN IAM и вставить ARN из роли, которую мы создали ранее. Это должно быть все, что требуется для запуска экземпляра, и вы можете нажать Создать экземпляр записной книжки.
Подготовка экземпляра займет несколько минут, но как только он будет готов, вы сможете открыть записную книжку и увидеть, как экземпляр Jupyter Notebooks открыт в вашем браузере.
Вы заметите несколько вкладок в экземпляре Notebook. Примеры SageMaker - отличный ресурс для ознакомления с реализацией пары примеров моделей SageMaker.
3. Создайте новый .ipynb (Блокнот)
Для начала создадим новый блокнот и начнем писать код. В правом верхнем углу вы увидите кнопку Создать для создания новой записной книжки. В этом примере я собираюсь использовать записную книжку conda_python3.
Настройка модели
Первое, что нам нужно сделать, это импортировать набор данных. Поскольку мы работаем с небольшим набором данных здесь в целях тестирования, я загрузил свой .csv прямо в экземпляр Jupyter вместо S3. Вы можете сделать это с помощью кнопки загрузки на главной панели инструментов Jupyter.
Затем мы можем получить доступ к CSV в нашем коде следующим образом
# import numpy and pandas libraries for working with data import numpy as np import pandas as pd # Read in csv and store in a pandas dataframe df = pd.read_csv('2018MatchData.csv, sep=',', encoding='latin1')
Если вы никогда раньше не работали с записной книжкой на Python, вам просто нужно нажать Shift + Enter, чтобы выполнить код внутри блока.
Чтобы убедиться, что csv был прочитан правильно, вы можете выполнить df.head (), чтобы получить список из 5 лучших записей в вашем фреймворке данных.
В моем CSV есть много данных, которые нам сейчас не нужны, мы должны создать фрейм данных только с той информацией, которая нам важна. Давайте создадим новый pandas df только с столбцами, которые нам нужны для упражнения.
# keep player name for readability and manual checking data = df.loc[:, ['player_name', 'K', 'H', 'M', 'T', 'G', 'B', 'HO', 'FF', 'FA', 'AF']] # Remove player name as it is irrelevant for calcs playerStats = data.loc[:, ['K', 'H','M','T','G','B','HO','FF','FA']] # confirm we got the data we wanted data.head(10)
Теперь у нас есть массив всей соответствующей статистики игроков для каждой игры AFL в сезоне 2018 года, а также очки Fantasy Points, которые набрал игрок.
Теперь очки фэнтези AFL рассчитываются по следующей формуле:
Удар ногой (3), Удар рукой (2), Метка (3), Отбор (4), Цель (6), Позади (1), Удар (1), Штрафной удар для (1), Штрафной удар ( -3)
Я заказал их в том же порядке, что и наш массив, чтобы мы могли создать массив weightings именно в этом порядке.
weightings = [3, 2, 3, 4, 6, 1, 1, 1, -3]
Прежде чем запускать какие-либо алгоритмы машинного обучения, мы должны убедиться, что наши данные и весовой массив действительны. Давайте напишем простую функцию, чтобы подтвердить это.
Эта функция возьмет массив статистики игрока и вектор весов, умножит каждую характеристику на соответствующий вес и просуммирует их вместе, чтобы получить рассчитанные очки фантазии.
def calculate_fantasy_points(playerStats, Weightings): return np.dot(playerStats, np.transpose(weightings))
Теперь мы можем вычислить фантастические точки на основе созданного нами вектора весов и проверить, действительно ли они являются правильными весами.
# Calculate Fantasy Points data['calculated'] = calculate_fantasy_points(playerStats, weightings) # Get the difference between actual points and predicted data['diff'] = data['AF'] - calculate_fantasy_points(playerStats, weightings) # Take the sum of the difference over all data points and verify that is is zero data['diff'].sum()
На этом этапе мы видим, что действительно созданный нами весовой вектор правильный и действительно генерирует ожидаемые фэнтезийные очки. Следующий шаг - проверить, сможет ли SageMaker Linear Learner найти этот весовой вектор, если он был нам неизвестен.
Использование SageMaker Linear Learner
Первое, что нам нужно сделать, это подготовить данные в формате, который может использовать SageMaker. Для Linear Learner требуется массив типа float32.
# Kicks, handballs, goals etc modelData = np.array(data.iloc[:, 1:10]).astype('float32') # Actual Fantasy Points target = np.array(data.iloc[:, 10]).astype('float32') #Verify that the conversion worked print(modelData[0])
Затем нам нужно импортировать некоторые библиотеки для связи с экземплярами ML.
import boto3 import sagemaker import io import os import sagemaker.amazon.common as smac # Create new sagemaker session sess = sagemaker.Session() # S3 bucket to export results to bucket = "test.sagemaker.michael.timbs" prefix = "AFLFantasy/test" # Use the IO buffer as dataset is small buf = io.BytesIO() smac.write_numpy_to_dense_tensor(buf, modelData, target) buf.seek(0) key = 'linearlearner' boto3.resource('s3').Bucket(bucket).Object(os.path.join(prefix, 'train', key)).upload_fileobj(buf) s3_train_data = 's3://{}/{}/train/{}'.format(bucket, prefix, key) print('uploaded training data location: {}'.format(s3_train_data)) output_location = 's3://{}/{}/output'.format(bucket, prefix) print('training artifacts will be uploaded to: {}'.format(output_location)) # Use all regions for ML model containers = {'us-west-2': '174872318107.dkr.ecr.us-west-2.amazonaws.com/linear-learner:latest', 'us-east-1': '382416733822.dkr.ecr.us-east-1.amazonaws.com/linear-learner:latest', 'us-east-2': '404615174143.dkr.ecr.us-east-2.amazonaws.com/linear-learner:latest', 'eu-west-1': '438346466558.dkr.ecr.eu-west-1.amazonaws.com/linear-learner:latest', 'ap-northeast-1': '351501993468.dkr.ecr.ap-northeast-1.amazonaws.com/linear-learner:latest'}
Теперь, когда мы выполнили некоторую настройку и настройку, можно приступить к запуску модели.
from sagemaker import get_execution_role role = get_execution_role() linear = sagemaker.estimator.Estimator(containers[boto3.Session().region_name], role, train_instance_count=1, train_instance_type='ml.c4.xlarge', output_path=output_location, sagemaker_session=sess)
Теперь нам нужно установить некоторые параметры модели для этой модели. В частности, нам нужно сообщить линейному учащемуся, что у нас есть 9 параметров, которые нужно подобрать, что нам нужна регрессионная модель и, что наиболее важно, мы не хотим нормализовать данные.
linear.set_hyperparameters(feature_dim=9, predictor_type='regressor', normalize_data=False)
Теперь мы готовы развернуть нашу модель в экземпляре, чтобы запустить линейное обучение и получить результаты. Чтобы развернуть эту модель, мы просто запускаем:
linear.fit({'train': s3_train_data}) linear_predictor = linear.deploy(initial_instance_count=1, instance_type='ml.m4.xlarge')
Это займет пару минут, чтобы подготовить и запустить, и вы узнаете, когда это будет сделано.
Доступ к результатам
После обучения модели мы можем отправлять в модель новые данные и получать прогнозы. В этом случае мы просто отправим ему данные обучения и посмотрим, насколько близко он подошел к поиску правильных весов.
# Set up from sagemaker.predictor import csv_serializer, json_deserializer linear_predictor.content_type = 'text/csv' linear_predictor.serializer = csv_serializer linear_predictor.deserializer = json_deserializer
Чтобы получить прогнозы для одной точки данных, мы должны сделать что-то вроде этого
# Pass the first row of data to the predictor result = linear_predictor.predict(modelData[0]) print(result)
Давайте просто передадим все данные и вернем все результаты
predictions = [] for array in modelData: result = linear_predictor.predict(array) predictions += [r['score'] for r in result['predictions']] predictions = np.array(predictions) # Push into our pandas dataframe data['Predicted'] = predictions.astype(int))
Полученные результаты
Удивительно, но веса, найденные линейным учеником, не были точными и имели небольшую ошибку. Это может быть связано с заданными по умолчанию критериями остановки в настройке модели.
Однако результаты были очень близкими, и с учетом простоты настройки модели и отсутствия знаний в предметной области, необходимых для запуска этой простой регрессии, SageMaker кажется удобным продуктом.
Я поиграю с настройкой параметров и выясню, почему точность прогнозов не была 100% (для очень простой модели), и напишу следующий пост.