В этой статье приведены подробные пошаговые инструкции о том, как настроить эксперимент по машинному обучению в студии машинного обучения Microsoft Azure, запустить удаленный вычислительный ресурс и оптимизировать модель с помощью обучения гиперпараметрам. Если вы заинтересованы в запуске собственных моделей машинного обучения на платформе Microsoft Azure, смело выполняйте приведенные ниже шаги и получайте удовольствие! Код адаптирован из фантастического материала от Microsoft Learn (Designing and Implementing a Data Science Solution on Azure).

Набор данных

В этом примере я буду использовать набор данных о мошенничестве с кредитными картами от Kaggle, вы можете скачать набор данных здесь. Краткое описание набора данных скопировано ниже:

Контекст

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

Контент

Набор данных содержит транзакции, совершенные по кредитным картам в сентябре 2013 года держателями карт из Европы. Этот набор данных представляет транзакции, которые произошли за два дня, где у нас есть 492 мошенничества из 284 807 транзакций. Набор данных сильно несбалансирован, на положительный класс (мошенничество) приходится 0,172% всех транзакций.

Он содержит только числовые входные переменные, которые являются результатом преобразования PCA. К сожалению, из соображений конфиденциальности мы не можем предоставить исходные функции и дополнительную справочную информацию о данных. Признаки V1, V2, … V28 являются основными компонентами, полученными с помощью PCA, единственные признаки, которые не были преобразованы с помощью PCA, — это «Время» и «Количество». Функция «Время» содержит секунды, прошедшие между каждой транзакцией и первой транзакцией в наборе данных. Функция «Сумма» — это сумма транзакции, эту функцию можно использовать, например, для зависимого от затрат обучения. Функция «Класс» — это переменная ответа, которая принимает значение 1 в случае мошенничества и 0 в противном случае.

Я сохранил набор данных в своей папке машинного обучения и назвал его «creditcard.csv».

Шаг 1. Создайте рабочую область машинного обучения в Microsoft Azure

На домашней странице Azure выберите Машинное обучение Azure, а затем Создать новую рабочую область.

Вам нужно будет предоставить следующую информацию для настройки нового рабочего пространства:

  1. Имя рабочей области: введите уникальное имя, идентифицирующее вашу рабочую область. Имена должны быть уникальными в группе ресурсов. Имя рабочей области нечувствительно к регистру.
  2. Подписка: выберите подписку Azure, которую вы хотите использовать.
  3. Группа ресурсов. Группа ресурсов содержит связанные ресурсы для решения Azure. Вы можете использовать существующую группу ресурсов в своей подписке или ввести имя для создания новой группы ресурсов.
  4. Регион: выберите регион Azure, ближайший к вашим пользователям и ресурсам данных, для создания рабочей области.

Шаг 2. Создайте файл config.json и загрузите рабочую область.

Создайте файл config.json в папке вашего проекта машинного обучения. Файл JSON должен содержать три элемента: «subscription_id», «resource_group» и «workspace_name». Вы можете найти эту информацию на вкладке «Обзор» только что созданной рабочей области машинного обучения.

import azureml.core
from azureml.core import Workspace

# Load the workspace from the saved config file
ws = Workspace.from_config()
print('Ready to use Azure ML {} to work with {}'.format(azureml.core.VERSION, ws.name))

В случае успеха вы сможете увидеть сообщение, содержащее версию Azure ML и имя вашей рабочей области.

Шаг 3. Загрузите файл и зарегистрируйте набор данных в Azure.

default_ds = ws.get_default_datastore()

if 'credit dataset' not in ws.datasets:
    # first upload the files
    default_ds.upload_files(files=['./creditcard.csv'],
                        target_path='Fraud_Detection/', 
                        overwrite=True, 
                        show_progress=True)
    
        #Then Create a tabular dataset from the path on the datastore
    tab_data_set = Dataset.Tabular.from_delimited_files(path=(default_ds, 'Fraud_Detection/*.csv'))

    # Then Register the tabular dataset
    try:
        tab_data_set = tab_data_set.register(workspace=ws, 
                                name='credit dataset',
                                description='For Credit Card Fraud Detection',
                                tags = {'format':'CSV'},
                                create_new_version=True)
        print('Dataset registered.')
    except Exception as ex:
        print(ex)
else:
    print('Dataset already registered.')

После успешного запуска кода вы можете проверить это, перейдя на вкладку «Данные» в Microsoft Azure Machine Learning Studio. В разделе «Хранилища данных» выберите workspaceblobstore (по умолчанию) (это default_ds, указанный в первой строке кода), где файл creditcard.csv хранится в папке «Fraud_Detection»:

После загрузки CSV-файла на Azure мы создаем из него табличный набор данных с помощью функции Dataset.Tabular.from_delimited_files и регистрируем его под именем «кредитный набор данных». Он появится в разделе «Активы данных» на вкладке «Данные».

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

Шаг 4. Создайте папку, содержащую сценарий обучения и файл yml.

# Create a folder for the experiment files
experiment_folder = 'Credit_card_fraud_detection_on_azure'
os.makedirs(experiment_folder, exist_ok=True)
print(experiment_folder, 'folder created')

Шаг 5: Подготовьте параметризованный сценарий обучения

%%writefile $experiment_folder/fraud_detection_training_w_SMOTE_HYPER.py

# import libraries
import argparse
from azureml.core import Run
import pandas as pd
import numpy as np
import joblib
import os
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report,precision_score, recall_score, roc_auc_score
from imblearn.over_sampling import SMOTE


# instantiate parser and add arguments to it
parser = argparse.ArgumentParser()
parser.add_argument('--regularization', type=float, dest='reg_rate', default=1, help='choose a regularization rate')
parser.add_argument('--penalty',type=str, dest='penalty',default='none',help='pick a regularization type')
parser.add_argument("--input-data", type=str, dest='training_dataset_id', help='training dataset')
args = parser.parse_args()

reg = args.reg_rate
pen = args.penalty

# get the experiment run context
run = Run.get_context()

# load the credit card dataset (passed as an input dataset)
print("Loading Data...")
fraud_detection = run.input_datasets['training_data'].to_pandas_dataframe() 

#split data into training set and test set
X = fraud_detection.iloc[:, 1:-2]
y = fraud_detection.iloc[:, -1]

#instantiate SMOTE and transform the original dataset into a balanced dataset
sm = SMOTE(random_state=42)
X_bal,y_bal = sm.fit_resample(X,y)

# Split data into training set and test set
X_train, X_test, y_train, y_test = train_test_split(X_bal, y_bal, 
                                                    test_size=0.30, random_state=0)

# Train a logistic regression model
print('Training a logistic regression model with regularization rate of', reg)
run.log('Regularization Rate',  np.float(reg))
model = LogisticRegression(C=1/reg, solver="lbfgs",penalty=pen).fit(X_train, y_train)

# calculate precision
y_hat = model.predict(X_test)
precision = precision_score(y_test,y_hat)
print('Precision:', precision)
run.log('Precision', np.float(precision))

#calculate recall
recall = recall_score(y_test,y_hat)
print('recall:',recall)
run.log('Recall',np.float(recall))

# calculate AUC
y_scores = model.predict_proba(X_test)
auc = roc_auc_score(y_test,y_scores[:,1])
print('AUC: ' + str(auc))
run.log('AUC', np.float(auc))

# Plot the imbalanced data
fig = plt.figure(figsize=(12,7)) 
sns.countplot(data=fraud_detection,x='Class',log=True)
plt.title("Class Distribution",y=1.05,fontsize=15,loc='center')
plt.xticks([0,1],['False','True'],size=10)
plt.xlabel(xlabel='CLASS',size=10) 
run.log_image(name="Imbalanced_data",plot=fig)
plt.show()

# Plot the balanced data
fig = plt.figure(figsize=(12,7))
y_bal.value_counts().plot(kind='bar')
plt.xticks([0,1],['False','True'],rotation=0,size=15)
plt.yticks(size=15)
plt.xlabel("Class",size=15)
plt.title("Class distribution",loc='center',size=20)
run.log_image(name="Balanced_data",plot=fig)
plt.show()

# Create an output folder in Azure
os.makedirs('outputs',exist_ok=True)
# Save the model to the output folder
joblib.dump(value=model, filename='outputs/fraud_detection_model_2.pkl') 

run.complete()

В первой строке кода мы создаем новый файл Python с помощью волшебной командной функции %%writefile. Затем импортируем необходимые библиотеки. Обратите внимание, что библиотека argparse позволяет нам добавлять параметры в сценарий обучения, чтобы мы могли повторить тот же эксперимент с другими настройками параметров. Это также необходимо, когда мы проводим поиск гиперпараметров, как показано в коде ниже. Например, args.reg_rate позволяет нам контролировать силу регуляризации (обратите внимание, что она появляется в параметрах C функции LogisticRegression).

Run.get_context() позволяет нам регистрировать метрики и изображения эксперимента в Azure с помощью функций .log и .log_image соответственно. В приведенном выше коде мы регистрируем три метрики: точность, отзыв и показатель AUC. Мы также записали две диаграммы для справки.

Также обратите внимание, что когда мы загружаем набор кредитных данных, мы используем run.input_datasets[‘training_data’]. Это метод получения набора данных «по имени», и мы определяем «training_data» в методе .as_named_input() внутри ScripRunConfig на шаге 8. Кроме того, можно также получить набор данных по его идентификатору, используя метод Dataset.get_by_id.

(Примечание: по неизвестным причинам Azure не регистрирует объект FacetGrid — вместо этого отображается пустое изображение. Если вы знаете причину, оставьте ее в комментарии.)

Шаг 6. Определите пользовательскую среду для запуска обучающего сценария.

%%writefile $experiment_folder/experiment_env.yml
name: experiment_env
dependencies:
- python=3.6.2
- scikit-learn
- ipykernel
- matplotlib
- pandas
- seaborn
- pip
- pip:
  - azureml-defaults  
  - pyarrow           
  - imbalanced-learn
from azureml.core import Environment

# Create a Python environment for the experiment 
experiment_env = Environment.from_conda_specification("experiment_env", "/experiment_env.yml")
                                                  
# Let Azure ML manage dependencies
experiment_env.python.user_managed_dependencies = False 

# Print the environment details
print(experiment_env.name, 'defined.')
print(experiment_env.python.conda_dependencies.serialize_to_string())

Файл yml создает необходимую среду для обучающего скрипта, указывая версию интерпретатора Python и импортируя библиотеки, необходимые для работы с обучающим скриптом. Обратите внимание, что сначала устанавливаются зависимости Conda, а затем зависимости pip. Пакет pip включается в зависимости Conda перед установкой зависимостей pip.

Шаг 7. Создайте вычислительный кластер

from azureml.core.compute import ComputeTarget, AmlCompute
from azureml.core.compute_target import ComputeTargetException

cluster_name = "your-unique-compute-cluster-name"

# Check for existing compute target
try:
    training_cluster = ComputeTarget(workspace=ws, name=cluster_name)
    print('Found existing cluster, use it.')

except ComputeTargetException: 
    try:
        #Creating a new compute cluster and configure it
        compute_config = AmlCompute.provisioning_configuration(vm_size='STANDARD_DS11_V2', max_nodes=2)
        training_cluster = ComputeTarget.create(ws, cluster_name, compute_config)
        training_cluster.wait_for_completion(show_output=True)
    except Exception as ex:
        print(ex)

Создание вычислительных ресурсов в облаке необходимо, когда ваших локальных вычислительных ресурсов недостаточно для обработки длительных экспериментов, обрабатывающих большой набор данных, или когда вы хотите воспользоваться возможностью быстрого создания и использования вычислительных ресурсов в облаке. В этом примере мы демонстрируем, как создать вычислительный кластер в Azure — управляемой вычислительной инфраструктуре, предназначенной для производственного использования. Вы можете изменить vm_size и max_nodes в соответствии с рабочей нагрузкой. Вы можете обратиться к этой странице для получения дополнительной информации.

Шаг 8. Запустите эксперимент и выполните поиск гиперпараметров в Azure.

from azureml.core import Experiment, ScriptRunConfig
from azureml.train.hyperdrive import GridParameterSampling, HyperDriveConfig, PrimaryMetricGoal, choice

# Get the training dataset
credit_ds = ws.datasets.get("credit dataset")

# Create a script config
script_config = ScriptRunConfig(source_directory=experiment_folder,
                                script='fraud_detection_training_w_SMOTE_HYPER.py',
                                arguments = ['--input-data', credit_ds.as_named_input('training_data')], 
                                environment=experiment_env,
                                compute_target=cluster_name)
                                
# Sample a range of parameter values
params = GridParameterSampling(
    {
        '--regularization': choice(0.1, 1.0,10),
        '--penalty' : choice(['none', 'l2'])
    }
)                                

# Configure hyperdrive settings
hyperdrive = HyperDriveConfig(run_config=script_config, 
                          hyperparameter_sampling=params, 
                          policy=None, 
                          primary_metric_name='AUC', 
                          primary_metric_goal=PrimaryMetricGoal.MAXIMIZE, 
                          max_total_runs=6, 
                          max_concurrent_runs=2) 

                                
# submit the experiment
experiment_name = 'mslearn-train-fraud-detection-23-01-02_hyper_tune'
experiment = Experiment(workspace=ws, name=experiment_name)
run = experiment.submit(config=hyperdrive)

run.wait_for_completion()

ScriptRunConfig принимает три основных параметра: обучающий скрипт и необходимые аргументы (здесь имя входных данных), среду (которую мы определили на шаге 6) и Compute_target (созданную на шаге 7).

Для поиска гиперпараметров мы использовали GridParameterSampling, который просматривает все возможные комбинации параметров. (Обратите внимание, что GridParameterSampling принимает только дискретные значения, генерируемые функцией выбора). Мы используем метод HyperDriveConfig для настройки поиска гиперпараметров; в частности, мы выбрали политику отказа от преждевременной остановки и стремились максимизировать показатель AUC. Мы также ограничиваем эксперимент 6 итерациями и выполняем до 2 итераций параллельно.

В Студии машинного обучения Azure есть шесть завершенных дочерних запусков, соответствующих каждой из шести возможных комбинаций параметров:

Когда вы нажимаете на один из дочерних запусков, вы можете увидеть зарегистрированные показатели соответствующего запуска в разделе «Метрики»:

Зарегистрированные диаграммы и сохраненную модель можно найти в разделе «Выводы + журнал»: (это также место, где можно просмотреть журнал ошибок, когда вы сталкиваетесь с проблемами при выполнении кода)

В качестве альтернативы вы можете использовать следующий код для получения информации о дочерних запусках:

for child_run in run.get_children_sorted_by_primary_metric():
    print(child_run)

# Get the best run, and its metrics and arguments
best_run = run.get_best_run_by_primary_metric()
best_run_metrics = best_run.get_metrics()
script_arguments = best_run.get_details() ['runDefinition']['arguments']
print('Best Run Id: ', best_run.id)
print(' -AUC:', best_run_metrics['AUC'])
print(' -Arguments:',script_arguments)

Бонусный шаг:

Не забудьте удалить неиспользуемые вычислительные ресурсы и удалить связанные ресурсы, такие как Container Registry, чтобы избежать ненужных затрат.

Заключение:

Поздравляем! Вы успешно настроили эксперимент по логистической регрессии и выполнили поиск гиперпараметров в Azure! Тем не менее, этот пример упрощен, так как он лишь немного подготовил данные (используя SMOTE для балансировки двух классов). В следующих статьях я покажу, как настроить конвейер в Azure для инкапсуляции подготовки данных и этапов обучения, а также создать службу логических выводов в реальном времени для производства.