Среди наиболее частых вопросов, которые мне задают, что будет дальше после того, как мы подготовили данные, обучили модель и пошли дальше, чтобы проверить производительность? Обычно в академических кругах мы останавливаемся на этом этапе, и пора составить исследовательскую работу, которая, надеюсь, будет принята с менее резкими комментариями рецензентов. Хотя в последнее время стало доступно больше академической работы, в которой сообщество извлекло пользу из этого и привлекло больше энтузиастов для работы с этой моделью. С другой стороны, есть больше программистов, которые застревают и часто выражают радикальную откровенность и называют машинное обучение бесполезным. Итак, если вы застряли с людьми, которые занимаются научными исследованиями по созданию модели, которая работает с точностью на 1% выше, этот пост будет вашим способом подготовить ваши модели для развертывания в качестве API.

Намерение

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

Предисловие

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

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

1- Получение данных.

Набор данных, который мы будем использовать здесь, взят отсюда, но я больше не могу получить к нему доступ, поэтому вы можете получить его из kaggle. Набор данных из kaggle находится в формате значений, разделенных запятыми (CSV), тогда как версия, которая у меня есть, находится в файле txt. Набор данных состоит из 7 столбцов:

  1. цена покупки.
  2. стоимость технического обслуживания.
  3. количество дверей.
  4. количество персон.
  5. lug_boot.
  6. безопасность.
  7. столбец трагедии или решения.

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

Чтение данных

Сначала мы считываем данные во фрейм данных pandas:

data = pd.read_csv (‘car.data.txt’, names = [‘Buying’, ‘Maint’, ’doors’, ‘person’, ’lug-boot’, ’security’, ’target’])

data.head ()

Я назвал столбцы, так как мой txt-файл не имеет заголовков, но если у вас есть версия набора данных kaggle, вы увидите доступные заголовки, и поэтому в параметре names не будет необходимости.

Чтение данных в фрейм данных pandas представит их в табличном формате:

Предварительная обработка

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

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

data['Buying']=data['Buying'].apply(Trans_Buying)

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

# let's split data into training and testing
feature_columns = ['Buying', 'Maint','doors', 'persons','lug-boot','safety']
labels = data["target"].values
features = data[list(feature_columns)].values
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.3, random_state=42)

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

Классификатор случайного леса

RFC = RandomForestClassifier(random_state=101)
RFC.fit(X_train, y_train)
print("Score on the training set is: {:2}"
      .format(RFC.score(X_train, y_train)))
print("Score on the test set is: {:.2}"
      .format(RFC.score(X_test, y_test)))

Классификатор дерева решений

DTC = tree.DecisionTreeClassifier(criterion = 'entropy')
DTC.fit(X_train, y_train)
print("Score on the training set is: {:2}"
      .format(DTC.score(X_train, y_train)))
print("Score on the test set is: {:.2}"
      .format(DTC.score(X_test, y_test)))

Экспорт модели

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

# Create persistent model
model_filename = 'carDTC.pkl'
print("Model exported to {}...".format(model_filename))
joblib.dump(DTC, model_filename)

На этом этапе вы уже выполнили рабочий процесс машинного обучения, а теперь нам нужно создать Flask API. Flask - это фреймворк для веб-разработки на Python. Мы будем использовать его здесь, чтобы создать api для нашей модели, и мы развернем его локально.

Flask API

Прежде чем приступить к этому этапу, убедитесь, что у вас не установлена ​​библиотека Flask. Затем создайте файл в своем любимом текстовом редакторе и назовите этот файл filename.py

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

# importing the libraries
from flask import Flask, request, jsonify
from sklearn.externals import joblib
#Creating our FlaskAPP
app = Flask(__name__)
# Load the model
MODEL = joblib.load('carDTC.pkl')
MODEL_LABELS = ['unacc', 'acc', 'vgood', 'good']

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

@app.route('/predict')
def predict():
    # Retrieve query parameters related to this request.
    Buying = request.args.get('Buying')
    Maint = request.args.get('Maint')
    doors = request.args.get('doors')
    persons = request.args.get('persons')
    lug_boot = request.args.get('lug_boot')
    safety = request.args.get('safety')
# Our model expects a list of records
    features = [[Buying, Maint, doors, persons, lug_boot, safety]]
# predict the class and probability of the class
    label_index = MODEL.predict(features)
    
    # get the probabilities list for the prediction
    label_conf = MODEL.predict_proba(features)
# list down each class with the probabilty value
    probs = ' Unacceptable = {}, Acceptable = {}, Very Good = {}, Good = {}'.format(label_conf[0][0], label_conf[0][1], label_conf[0][2], label_conf[0][3])
# Retrieve the name of the predicted class
    label = MODEL_LABELS[label_index[0]]
# Create a JSON and send a response 
    return jsonify(status='complete', label=label, confidence = ''.join(str(label_conf)), probabilities = probs)

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

Поздравляем, у вас есть готовый API, встроенный во флягу, просто добавьте основную функцию.

if __name__ == '__main__':
    app.run(debug=True)

Теперь сохраните этот скрипт и запустите его со своего терминала:

filename.py

Теперь, чтобы протестировать свой API, вы можете позвонить из браузера следующим образом:

http://127.0.0.1:5000/predict?Buying=1&Maint=1&doors=1&persons=1&lug_boot=1&safety=1

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

Вы также можете позвонить из записной книжки jupyter:

import requests
response = requests.get('http://127.0.0.1:5000/predict?Buying=1&Maint=1&doors=1&persons=1&lug_boot=1&safety=1')
print(response.text)

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

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