Оживите свои модели машинного обучения с помощью Flask

Практическое введение в развертывание модели машинного обучения на Python

Что такое развертывание и зачем мне это нужно?

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

Затем они спрашивают, как модель будет работать с реальными данными в реальном времени. Как это повлияет на ценность бизнеса? Как будут реализованы прогнозы? В настоящий момент ваша недавно обученная модель живет на вашем локальном компьютере в Jupyter Notebook, который использовался для ее обучения. Как специалист по анализу данных, вы сосредоточили свое внимание на настройке модели и повышении ее производительности. Вы не задумывались о том, как ваша модель перейдет из стадии разработки в стадию эксплуатации. Введите: развертывание.

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

Как развернуть мою модель?

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

В этом разделе мы рассмотрим шаги, необходимые для развертывания модели машинного обучения. В этом руководстве мы будем использовать пример модели для прогнозирования ухода клиентов. Отток клиентов - это показатель лояльности клиентов: если покупатель «отталкивается», он покидает вашу компанию и уходит к конкуренту.

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

В таблице ниже показаны данные, включенные в этот набор данных, и описание столбцов. Последний столбец «Отток» - это целевое значение.

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

Шаг 1: Сохранение модели

Первым шагом в развертывании обученной модели машинного обучения является ее сохранение. Вы можете думать об этом шаге как о сохранении документа Word. Когда вы сохраняете текстовый документ, он больше не находится в зоне «чистилища» - у него есть имя и формат файла, а также это имя и формат файла (.doc), и его может открыть любой, кто также имеет Microsoft Word или любая другая программа, способная читать файлы .doc.

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

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

Следующий код показывает, как подготовить данные, обучить модель и, наконец, обработать эту модель:

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

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

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

Шаг 2. Рефакторинг кода для этапа эксплуатации

Пока что код, который мы написали, завершает обучение задаче и сохраняет модель как рассол. Этот код выполнил задачи, необходимые на этапе обучения. Хотя большая часть этого кода применима на этапе эксплуатации, этого недостаточно, и необходимо будет внести некоторые изменения. Например, наш код для обучения модели основывался на чтении в одном CSV, который содержал все данные обучения. В рабочем режиме у нас не будет единого CSV, содержащего все данные. Скорее, нам нужно будет много раз предсказывать отдельные точки данных.

Что происходит на этапе эксплуатации, показано на изображении ниже. Точка данных, представляющая функции для нового клиента, вводится в нашу обученную сохраненную модель, и возвращается прогноз того, откажутся они или нет. Прогноз состоит из двух частей: двоичного предсказания того, откажется ли человек от оттока (0 = нет оттока, 1 = оттока), и вероятности, представляющей вероятность того, что он откажется.

Эти прогнозы, а также входные функции, используемые для их создания, больше не будут иметь формат CSV, а будут представлены в виде объекта JSON. Почему объект JSON? Объекты JSON легко передавать между различными приложениями, а также могут быть легко считаны в фреймворк pandas, как и данные, которые мы изначально использовали для обучения нашей модели.

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

В следующем коде показан файл .py для выполнения основных шагов, необходимых на этапе эксплуатации:

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

Теперь мы знаем, что можем применить нашу обученную модель к новой точке данных в формате JSON и получить прогноз!

Шаг 3. Создание веб-службы прогнозирования с помощью Flask

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

Самым известным примером веб-службы является веб-сервер. Веб-сервер можно рассматривать как фабрику по созданию веб-страниц, которая в течение всего дня принимает запросы для разных веб-страниц (в форме URL-адреса ), а затем возвращает эти запросы (в виде HTML-кода, который отображается в вашем браузере как красивая веб-страница). Наша веб-служба будет работать примерно так же, но вместо того, чтобы принимать запросы в форме разных URL-адресов, она будет принимать запросы как JSON, и вместо того, чтобы возвращать HTML, необходимый для отображения веб-страницы, он будет возвращать JSON прогнозов.

Так как же нам открыть двери нашего завода? Как следует из названия, преобразование нашего сценария в веб-службу предполагает предоставление доступа к нему через Интернет. В приведенном ниже коде показаны изменения, которые были внесены в сценарий прогнозирования, чтобы превратить его в веб-службу:

Первое, что мы замечаем, это то, что мы создали экземпляр приложения Flask, создав экземпляр класса Flask. Это первый шаг к открытию нашей фабрики - вы можете думать об этом как о получении необходимых разрешений на ведение бизнеса. Следующим шагом является установка URL-адреса, который будет запускать нашу функцию прогнозирования. В нашем примере с фабрикой это похоже на адрес, на который наши клиенты будут отправлять запросы на получение прогнозов. Мы делаем это с помощью декоратора app.route () из flask, который помещается в коде прямо над нашей функцией предсказания.

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

Наконец, мы меняем способ получения входных данных и возврата наших прогнозов. Раньше в нашем сценарии прогнозов мы просто загружали файл JSON с нашего локального компьютера. Теперь мы хотим принимать JSONS, которые находятся внутри запроса. Мы должны использовать пакет запросов от Python для анализа входящего JSON нашего входящего запроса. Затем мы также снова возвращаем JSON на выходе. Вы можете заметить эти изменения в функции generate_predictions ().

Последнее изменение касается последней части сценария. Теперь он просто запускает приложение, а не вызывает функцию generate_predictions () напрямую. При этом он по-прежнему вызывает функцию generate_predictions, поскольку это функция, которая запускается при запуске приложения.

Теперь, когда у нас есть сценарий сервера, мы можем протестировать его на нашей локальной машине, отправив ему тестовый запрос.

Первый шаг - просто запустить наш новый скрипт веб-службы python из командной строки. Когда мы запускаем его, он запускает приложение Flask, вызывая нашу веб-службу на локальном порту, то есть просто запускается на нашей локальной машине.

Теперь мы можем отправить запрос с помощью cURL. cURL - это утилита командной строки, используемая для отправки запросов из командной строки на любой URL-адрес.

В этом случае URL-адрес, который мы используем, является локальным портом с конечной точкой / прогноз, которую мы определили в нашем серверном скрипте. Часть команды -X предшествует заявлению о том, какой именно тип запроса мы собираемся отправить. В этом случае мы указали в нашем серверном скрипте, что тип запроса будет простым почтовым запросом, так что это то, что мы также указываем здесь в нашем запросе. Подробнее о других типах запросов вы можете прочитать здесь. Часть команды -d сигнализирует о том, что далее следует данные или тело запроса. После этого сигнала -d мы передаем JSON функций, которые мы хотим, чтобы наша модель использовала для прогнозирования. Наконец, последний шаг нашей команды - перечислить локальный URL-адрес, по которому мы отправляем запрос.

Шаг 4: Развертывание нашего веб-сервиса с помощью Heroku

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

В настоящее время нам повезло иметь множество бесплатных служб, которые мы можем использовать для завершения этого процесса и развертывания нашей веб-службы по общедоступному URL-адресу. К ним относятся Python Anywhere и Heroku среди других.

При развертывании на одной из этих облачных служб хостинга мы удаляем код с нашего локального компьютера. Это означает, что он больше не работает в нашей локальной среде Python с пакетами, которые мы установили локально. Чтобы наш генератор прогнозов мог работать в своем новом доме в облаке, нам необходимо убедиться, что скрипт создания прогнозов имеет доступ ко всем тем же пакетам Python, которые он использует локально, например scikit-learn, Flask и pandas. Для этого мы перечисляем все эти пакеты и их правильные версии, необходимые для запуска кода, в файле requirements.txt.

Получив этот файл, мы можем легко развернуть наш генератор прогнозов, просто следуя инструкциям Heroku для Python.

Резюме

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

Обратите внимание, что все, что описано в шагах 1–3, происходит в нашей локальной среде. Только на последнем этапе наш предсказатель переходит с нашей локальной машины и становится действительно доступным для других.

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

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