Построение моделей машинного обучения с использованием алгоритма K-средних и Amazon SageMaker

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

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

Что такое Amazon SageMaker?

Amazon SageMaker - это полностью управляемый сервис машинного обучения от AWS, который предоставляет разработчикам и специалистам по обработке данных инструменты для создания, обучения и развертывания их моделей машинного обучения. Он был представлен в ноябре 2017 года на AWS re: Invent. Хотя он обеспечивает непрерывный рабочий процесс для моделей машинного обучения, любой из его модулей можно запускать независимо. Это дает командам возможность использовать только те детали, которые им нужны. Он также имеет надежный CLI и богатый набор SDK для разработчиков на различных языках, включая Java, C # и Python.

Простой пример использования

Представьте, если хотите, базу данных с миллионами записей о бизнес-области. У вас есть наиболее эффективные SQL-запросы для возврата любых данных. Добавьте к этому сценарию запрос от бизнеса, чтобы спрогнозировать тенденцию или обнаружить закономерность на основе миллионов записей в базе данных. Пройдет немного времени, и вы поймете, что эту задачу сложно выполнить с помощью только эффективных SQL-запросов. Именно такой вариант использования привел меня к Amazon SageMaker.

На моей нынешней должности в Capital One я работаю в группе из шести человек, занимающихся проектированием систем промежуточного программного обеспечения для предприятия. Мы создаем API и микросервисы с использованием Java и NodeJ в рамках экосистемы AWS. Часть нашей роли влечет за собой поиск новых инструментов, поставщиков и тактик, которые могут работать в наших проектах.

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

Моя команда начала исследовать способы усиления механизма правил, и вскоре мы пришли к выводу, что добавление машинного обучения - это правильный путь. Однако мы команда разработчиков программного обеспечения, а не специалисты по данным, поэтому мы действительно не знали, с чего начать. Мы хотели исследовать и, в идеале, найти новый инструмент, который могли бы использовать как специалисты по обработке данных, так и инженеры-программисты, но при этом он соответствовал бы строгим рекомендациям MRO. Мы искали не решение, а новый инструмент для использования в нашей экосистеме хорошо управляемых систем моделирования . Именно тогда мы вошли в Amazon SageMaker ...

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

Основные правила

Чтобы создать это доказательство концепции, мы изложили несколько основных правил, которые будут охранять и направлять нас в процессе:

  • Используйте инфраструктуру как код (IaC) для всего, что мы делаем, чтобы все было в соответствии с принципами хорошо спроектированной структуры. Это может быть Cloud Formation, SageMaker SDK или Lambdas.
  • Шифрование! Шифрование !! Шифрование !!! Нам нужно было гарантировать, что данные остаются зашифрованными, используя соответствующие ключи KMS в каждом SDK SageMaker.
  • Пометка любого создаваемого ресурса для упрощения управления.
  • Убедитесь, что этот инструмент соответствует требованиям нашего предприятия.

Хотя использование IaC вместо выполнения задач непосредственно в консоли AWS казалось излишним, этот подход быстро окупился, учитывая, сколько раз нам приходилось создавать и запускать модели.

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

Здесь происходит преобразование данных (нормализация, стандартизация и т. Д.), Включая удаление выбросов и систематической ошибки. Популярным инструментом среди специалистов по обработке данных для решения этих задач являются Jupyter Notebooks. AWS предоставляет управляемую версию Jupyter Notebooks, которая очень хорошо интегрируется с SageMaker. Однако следует отметить, что вам не обязательно использовать Jupyter Notebooks для построения моделей данных в Amazon SageMaker. Любая интегрированная среда разработки (IDE), поддерживающая языки манипулирования данными, должна быть достаточной. Julia, Python и R (Jupyter понял?) - популярные языки, созданные для обработки данных и численного анализа. Я выбрал Python из-за обширной поддержки AWS SDK (в настоящее время AWS SDK не поддерживает Julia и R).

Вот фрагмент кода Python для разделения данных для обучения и тестирования:

from sklearn.model_selection import train_test_split
# get Training and testing Data
df = pd.read_csv("TrainTest_RawData.csv", sep=",")
# randomly select 20% of the data for testing and the other 80% for training
x_train, x_test, y_train, y_test = train_test_split(df.Amount, df.tranCode,test_size=0.2

Модельное обучение

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

Роль IAM
Роль IAM, которая будет использоваться для построения этих моделей, должна соответствовать следующим критериям:

  • Вы должны быть в состоянии взять на себя роль.
  • К роли должно быть привязано доверительное отношение SageMaker.
{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "Service": [
            "sagemaker.amazonaws.com"
          ]
        },
        "Action": "sts:AssumeRole"
      }
    ]
}
  • К роли должна быть привязана политика SageMaker / KMS.
{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "iam:PassRole",
        "Resource": "*",
        "Effect": "Allow",
        "Condition": {
          "StringEquals": {
            "iam:PassedToService": "sagemaker.amazonaws.com"
          }
        },
        "Sid": "GrantsIamPassRole"
      },
      {
        "Action": [
          "kms:DescribeKey",
          "kms:ListAliases"
        ],
        "Resource": "*",
        "Effect": "Allow",
        "Sid": "KmsKeysForCreateForms"
      },
      {
        "Action": [
          "iam:ListRoles"
        ],
        "Resource": "*",
        "Effect": "Allow",
        "Sid": "ListAndCreateExecutionRoles"
      },
      {
        "Action": [
          "kms:Encrypt",
          "kms:Decrypt",
          "kms:ReEncrypt*",
          "kms:GenerateDataKey*",
          "kms:DescribeKey",
          "kms:GetKeyPolicy",
          "kms:CreateGrant",
          "kms:ListGrants",
          "kms:RevokeGrant"
      ],
      "Resource": "KMS_KEY_ARN",
      "Effect": "Allow",
      "Sid": "GrantKMSAccess"
    },
    {
      "Action": [
        "sagemaker:CreateEndPoint",
        "sagemaker:DescribeEndpoint"
      ],
      "Resource": "*",
      "Effect": "Allow",
      "Sid": "GrantSageMakerCreate"
    }
  ]
}

Ключи KMS
К ключам KMS, которые будут использоваться для шифрования, должна быть привязана политика, которая будет предоставлять доступ к роли IAM, которая будет использовать SageMaker.

{
    "Version": "2012-10-17",
    "Id": "key-consolepolicy-3",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "ARN_OF_ROOT"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": "ARN_OF_KEY_ADMINISTRATORS_ROLE"
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "ARN_OF_SAGEMAKER_ROLE"
                ]
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey",
                "kms:GetKeyPolicy"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow attachment of persistent resources",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "ARN_OF_SAGEMAKER_ROLE"
                ]
            },
            "Action": [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}

Работа по обучению
На этом этапе вы готовы перенести свои данные в SageMaker для обучения. Наш вариант использования хорошо подходит для кластеризации. Amazon SageMaker поддерживает более 15 алгоритмов машинного обучения, которые удовлетворяют огромной базе сценариев. K-Means - один из таких алгоритмов, решающий проблемы кластеризации.

Моя коллега по Capital One Мэдисон Шотт написала блог об алгоритме K-средних, если вы хотите получить более подробное представление.

Есть два способа создать учебное задание в Amazon SageMaker для алгоритма K-средних (и для большинства поддерживаемых им алгоритмов):

  • API создания учебных заданий. Используется, когда вы хорошо представляете гиперпараметры (аргументы), которые необходимы вашей учебной работе для построения оптимальной модели. Это приводит к тому, что ваша модель строится быстрее, однако требует, чтобы у вас были знания предметной области ваших данных, чтобы предоставить точные значения гиперпараметров для построения оптимальной модели. В конце процесса создается одно учебное задание.
  • Create HyperParameter Tuning Job API: Используется, когда вы не знаете точные значения гиперпараметров для получения оптимальной модели. Вы предоставляете ему диапазон значений гиперпараметров для использования, и SageMaker создаст для вас множество учебных заданий и пометит задание, которое было оптимальным на основе предоставленного диапазона. Для алгоритма K-средних SageMaker предоставляет рекомендуемый диапазон значений гиперпараметров для использования.

Для нашего POC мы использовали API задания настройки гиперпараметров, это дало нам гибкость, чтобы попробовать разные сценарии обучения, а не создавать их по одному.

Следующий код Python можно использовать для создания задания настройки гиперпараметров:

import boto3
import os
from sagemaker.amazon.amazon_estimator import get_image_uri
os.environ['AWS_PROFILE'] = 'YOUR_AWS_STS_PROFILE'
# gets the K-Means docker image from AWS
image = get_image_uri(boto3.Session().region_name, 'kmeans')
role = 'ARN_OF_ROLE'
bucket = 'S3_BUCKET'
data_key = 'S3_TRAINING_DATA_LOCATION'
test_key = 'S3_TESTING_DATA_LOCATION'
output_key = 'S3_MODEL_OUTPUT_LOCATION'
data_location = 's3://{}/{}'.format(bucket, data_key)
output_location = 's3://{}/{}'.format(bucket,output_key)
test_location = 's3://{}/{}'.format(bucket, test_key)
sagemaker = boto3.client('sagemaker')
response = sagemaker.create_hyper_parameter_tuning_job(
    HyperParameterTuningJobName='TRAINING_JOB_NAME',
    HyperParameterTuningJobConfig={
        'Strategy': 'Bayesian',
        'HyperParameterTuningJobObjective': {
            'Type': 'Minimize',
            'MetricName': 'test:msd'
        },
        'ResourceLimits': {
            'MaxNumberOfTrainingJobs': 50,
            'MaxParallelTrainingJobs': 2
        },
        'ParameterRanges': {
            'IntegerParameterRanges': [
                {
                    'Name': 'extra_center_factor',
                    'MinValue': '4',
                    'MaxValue': '10'
                },
                {
                    'Name': 'mini_batch_size',
                    'MinValue': '3000',
                    'MaxValue': '15000'
                },
            ],
            'CategoricalParameterRanges': [
                {
                    'Name': 'init_method',
                    'Values': [
                        'kmeans++', 'random'
                    ]
                },
            ]
        },
        'TrainingJobEarlyStoppingType' : 'Auto'
    },
    TrainingJobDefinition={
        'StaticHyperParameters': {
            'k': '10',
            'feature_dim': '2',
        },
        'AlgorithmSpecification': {
            'TrainingImage': image,
            'TrainingInputMode': 'File'
        },
        'RoleArn': role,
        'InputDataConfig': [
            {
                'ChannelName': 'train',
                'DataSource': {
                    'S3DataSource': {
                        'S3DataType': 'S3Prefix',
                        'S3Uri': data_location,
                        'S3DataDistributionType': 'FullyReplicated'
                    }
                },
                'ContentType': 'text/csv;label_size=0'
            },
            
            {
                'ChannelName': 'test',
                'DataSource': {
                    'S3DataSource': {
                        'S3DataType': 'S3Prefix',
                        'S3Uri': test_location,
                        'S3DataDistributionType': 'FullyReplicated'
                    }
                },
                'ContentType': 'text/csv;label_size=0'
            },
        ],
        'OutputDataConfig': {
            'KmsKeyId': 'KMS_KEY_ID',
            'S3OutputPath': output_location
        },
        'ResourceConfig': {
            'InstanceType': 'ml.m4.16xlarge',
            'InstanceCount': 1,
            'VolumeSizeInGB': 50,
            'VolumeKmsKeyId': 'KMS_KEY_ID'
        },
        'StoppingCondition': {
            'MaxRuntimeInSeconds': 60 * 60
        }
    }
)
print(response)

Модель
После создания учебного задания, отвечающего вашим критериям, вы готовы к созданию модели. Модель берет задание на обучение и алгоритм и создает конфигурацию Docker, которую SageMaker (или любая платформа) может разместить для вас. Это базовое доказательство концепции, показывающее, как можно создавать модели, и приукрашивает процессы управления и партнерства при внедрении моделей в производство.

Следующий пример кода Python можно использовать для создания модели:

import boto3
import os
from sagemaker.amazon.amazon_estimator import get_image_uri
os.environ['AWS_PROFILE'] = 'AWS_STS_PROFILE'
sagemaker = boto3.client('sagemaker')
role = 'ARN_IAM_ROLE'
# gets the K-Means docker image from AWS
image = get_image_uri(boto3.Session().region_name, 'kmeans')
job_name = 'TRAINING_JOB_NAME'
model_name = 'MODEL_NAME'
info = sagemaker.describe_training_job(TrainingJobName=job_name)
print(info)
model_data = info['ModelArtifacts']['S3ModelArtifacts']
primary_container = {
    'Image': image,
    'ModelDataUrl': model_data
}
tags = [
        {'Key' : 'ResourceName', 'Value': 'KMeans_Model'}
    ]
create_model_response = sagemaker.create_model(
    ModelName = model_name,
    ExecutionRoleArn = role,
    PrimaryContainer = primary_container,
    Tags = tags)
print(create_model_response['ModelArn'])

Конфигурация конечной точки
Следующим шагом после создания модели является создание конфигурации конечной точки. Это создает конфигурацию, которая будет использоваться для создания конечной точки API, которая в конечном итоге будет размещать модель.

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

import boto3
import os
os.environ['AWS_PROFILE'] = 'AWS_STS_PROFILE'
sagemaker = boto3.client('sagemaker')
model_name = 'MODEL_NAME'
endpoint_config_name = 'ENDPOINT_CONFIG_NAME'
print(endpoint_config_name)
tags = [
        {'Key' : 'ResourceName', 'Value': 'KMeans_EndPointConfig'}
    ]
create_endpoint_config_response = sagemaker.create_endpoint_config(
    EndpointConfigName = endpoint_config_name,
    ProductionVariants=[{
        'InstanceType':'ml.m4.xlarge',
        'InitialInstanceCount':1,
        'ModelName':model_name,
        'VariantName':'AllTraffic'}],
    Tags= tags,
    KmsKeyId='KMS_KEY_ID')
print("Endpoint Config Arn: " + create_endpoint_config_response['EndpointConfigArn'])

Конечная точка
Конечная точка - это API, на котором будет размещена модель, из которой можно делать выводы. В SDK для создания конечной точки нет параметра для назначения роли, которая будет выполнять SDK. Таким образом, вы не можете выполнить sagemaker.create_endpoint локально.

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

Это пример кода лямбда-функции:

import json
import boto3
import os

def lambda_handler(event, context):
    sagemaker = boto3.client('sagemaker')
    
    endpoint_name = event['EndPointName']
    endpoint_config_name = event['EndPointConfigName'] 
    
    tags = [
            {'Key' : 'ResourceName', 'Value': 'Kmeans_Lambda'}
        ]
    
    print(endpoint_name)
    
    create_endpoint_response = sagemaker.create_endpoint(
        EndpointName=endpoint_name,
        EndpointConfigName=endpoint_config_name,
        Tags = tags)
    
    print(create_endpoint_response['EndpointArn'])
    
    resp = sagemaker.describe_endpoint(EndpointName=endpoint_name)
    status = resp['EndpointStatus']
    print("Status: " + status)
    
    try:
  sagemaker.get_waiter('endpoint_in_service').wait(EndpointName=endpoint_name)
    finally:
        resp = sagemaker.describe_endpoint(EndpointName=endpoint_name)
        status = resp['EndpointStatus']
        print("Arn: " + resp['EndpointArn'])
        print("Create endpoint ended with status: " + status)
    
        if status != 'InService':
            message = sagemaker.describe_endpoint(EndpointName=endpoint_name)['FailureReason']
            print('Create endpoint failed with the following error: {}'.format(message))
            raise Exception('Endpoint creation did not succeed')

Проверка

После создания конечной точки вы готовы начать отправку тестовых данных на конечную точку и получение результатов. Самый простой метод получения сегментов обучающих / тестовых данных - это равномерное рисование 80/20 на этапах подготовки данных. Валидация этого метода - это строгий процесс, который мы для краткости пропустили. Чтобы совершать звонки на свою конечную точку, вы можете использовать SDK для среды выполнения SageMaker на выбранном вами языке.

Вот фрагмент Python, который я использовал для своего POC.

import boto3
import os
import json
os.environ['AWS_PROFILE'] = 'AWS_STS_PROFILE'
runtime = boto3.Session().client('sagemaker-runtime',use_ssl=True)
endpoint_name = 'ENDPOINT'
payload = 'DATA_TO_SEND'
response = runtime.invoke_endpoint(EndpointName=endpoint_name, 
                                   ContentType='text/csv', 
                                   Body=payload)
result = json.loads(response['Body'].read())
print(result)

Результаты возвращаются в формате JSON:

{"closest_cluster": 1.0, "distance_to_cluster": 7.6}
{"closest_cluster": 2.0, "distance_to_cluster": 3.2}

Значение идентификаторов кластера и расстояния до кластера связано с математическим объяснением алгоритма K-средних. Модель не будет напрямую сообщать вам, принадлежит точка кластеру или нет, вы должны предоставить логику, чтобы делать выводы на основе расстояния до кластера. В нашем POC мы обнаружили, что наши точки данных были тесно сгруппированы (очень небольшое расстояние до кластера) для точек, которые действительно принадлежали друг другу. Однако для точек, которые не были в норме для области бизнеса, мы заметили гораздо большее, чем среднее расстояние до кластера. Мы начали строить нашу логику вывода на основе этого открытия.

Реализация

Если вы удовлетворены результатами проверки, это означает, что у вас есть модель, готовая для проверки руководящим органом. Когда ваша модель утверждена и готова к производству, AWS SageMaker упрощает размещение и масштабирование вашей модели в AWS. Учитывая гибкость его модулей, вы можете экспортировать свою модель из AWS и разместить ее на своей платформе или на любой другой платформе.

Заключение

Как инженер-программист с небольшим опытом работы в области науки о данных, Amazon SageMaker упростил создание моделей машинного обучения. Мы все еще находимся в процессе работы с нашим отделом управления модельными рисками, чтобы оценить модель и уточнить точность ее результатов. Построение точной модели требует времени, сотрудничества и целой экосистемы инструментов, но это окупается, когда у вас есть модель, которая может обнаруживать сложные закономерности.

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

РАСКРЫТИЕ ИНФОРМАЦИИ: © 2020 Capital One. Мнения принадлежат отдельному автору. Если в этом посте не указано иное, Capital One не является аффилированным лицом и не поддерживается ни одной из упомянутых компаний. Все используемые или отображаемые товарные знаки и другая интеллектуальная собственность являются собственностью соответствующих владельцев.