# Создание веб-приложения для использования ML модели В этом уроке вы обучите ML модель на уникальном наборе данных: _наблюдения НЛО за последний век_, взятые из базы данных NUFORC. Вы узнаете: - Как "запаковать" обученную модель - Как использовать эту модель в приложении Flask Мы продолжим использовать ноутбуки для очистки данных и обучения модели, но вы сможете сделать шаг дальше, исследуя использование модели "в реальных условиях", так сказать: в веб-приложении. Для этого вам нужно создать веб-приложение с использованием Flask. ## [Тест перед лекцией](https://ff-quizzes.netlify.app/en/ml/) ## Создание приложения Существует несколько способов создания веб-приложений для использования моделей машинного обучения. Ваша веб-архитектура может повлиять на способ обучения модели. Представьте, что вы работаете в компании, где группа специалистов по данным обучила модель, которую они хотят, чтобы вы использовали в приложении. ### Важные вопросы Есть множество вопросов, которые нужно задать: - **Это веб-приложение или мобильное приложение?** Если вы создаете мобильное приложение или вам нужно использовать модель в контексте IoT, вы можете использовать [TensorFlow Lite](https://www.tensorflow.org/lite/) и интегрировать модель в приложение для Android или iOS. - **Где будет находиться модель?** В облаке или локально? - **Поддержка оффлайн-режима.** Должно ли приложение работать без подключения к интернету? - **Какая технология использовалась для обучения модели?** Выбранная технология может повлиять на инструменты, которые вам нужно использовать. - **Использование TensorFlow.** Если вы обучаете модель с помощью TensorFlow, эта экосистема предоставляет возможность конвертировать модель TensorFlow для использования в веб-приложении с помощью [TensorFlow.js](https://www.tensorflow.org/js/). - **Использование PyTorch.** Если вы создаете модель с использованием библиотеки, такой как [PyTorch](https://pytorch.org/), у вас есть возможность экспортировать ее в формате [ONNX](https://onnx.ai/) (Open Neural Network Exchange) для использования в веб-приложениях на JavaScript, которые могут использовать [Onnx Runtime](https://www.onnxruntime.ai/). Этот вариант будет рассмотрен в будущем уроке для модели, обученной с помощью Scikit-learn. - **Использование Lobe.ai или Azure Custom Vision.** Если вы используете ML SaaS (Software as a Service) систему, такую как [Lobe.ai](https://lobe.ai/) или [Azure Custom Vision](https://azure.microsoft.com/services/cognitive-services/custom-vision-service/?WT.mc_id=academic-77952-leestott) для обучения модели, этот тип программного обеспечения предоставляет способы экспортировать модель для различных платформ, включая создание индивидуального API для запросов в облаке вашим онлайн-приложением. Вы также можете создать полноценное веб-приложение Flask, которое сможет обучать модель прямо в веб-браузере. Это также можно сделать с использованием TensorFlow.js в контексте JavaScript. Для наших целей, поскольку мы работали с ноутбуками на основе Python, давайте рассмотрим шаги, которые нужно предпринять, чтобы экспортировать обученную модель из такого ноутбука в формат, читаемый веб-приложением, созданным на Python. ## Инструменты Для этой задачи вам понадобятся два инструмента: Flask и Pickle, оба работают на Python. ✅ Что такое [Flask](https://palletsprojects.com/p/flask/)? Определяемый его создателями как "микро-фреймворк", Flask предоставляет базовые функции веб-фреймворков с использованием Python и движка шаблонов для создания веб-страниц. Ознакомьтесь с [этим модулем обучения](https://docs.microsoft.com/learn/modules/python-flask-build-ai-web-app?WT.mc_id=academic-77952-leestott), чтобы попрактиковаться в создании приложений с Flask. ✅ Что такое [Pickle](https://docs.python.org/3/library/pickle.html)? Pickle 🥒 — это модуль Python, который сериализует и десериализует структуру объекта Python. Когда вы "запаковываете" модель, вы сериализуете или упрощаете ее структуру для использования в вебе. Будьте осторожны: Pickle не является безопасным по своей природе, поэтому будьте внимательны, если вас попросят "распаковать" файл. Файл Pickle имеет суффикс `.pkl`. ## Упражнение - очистка данных В этом уроке вы будете использовать данные о 80,000 наблюдениях НЛО, собранных [NUFORC](https://nuforc.org) (Национальный центр сообщений о НЛО). Эти данные содержат интересные описания наблюдений НЛО, например: - **Длинное описание.** "Человек выходит из луча света, который освещает травяное поле ночью, и бежит к парковке Texas Instruments". - **Короткое описание.** "огни преследовали нас". Электронная таблица [ufos.csv](../../../../3-Web-App/1-Web-App/data/ufos.csv) включает столбцы о `городе`, `штате` и `стране`, где произошло наблюдение, форме объекта (`shape`) и его `широте` и `долготе`. В пустом [ноутбуке](../../../../3-Web-App/1-Web-App/notebook.ipynb), включенном в этот урок: 1. Импортируйте `pandas`, `matplotlib` и `numpy`, как вы делали в предыдущих уроках, и импортируйте таблицу ufos. Вы можете посмотреть пример набора данных: ```python import pandas as pd import numpy as np ufos = pd.read_csv('./data/ufos.csv') ufos.head() ``` 1. Преобразуйте данные ufos в небольшой датафрейм с новыми заголовками. Проверьте уникальные значения в поле `Country`. ```python ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']}) ufos.Country.unique() ``` 1. Теперь вы можете уменьшить объем данных, с которыми нужно работать, удалив любые пустые значения и импортировав только наблюдения длительностью от 1 до 60 секунд: ```python ufos.dropna(inplace=True) ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)] ufos.info() ``` 1. Импортируйте библиотеку `LabelEncoder` из Scikit-learn для преобразования текстовых значений стран в числа: ✅ LabelEncoder кодирует данные в алфавитном порядке ```python from sklearn.preprocessing import LabelEncoder ufos['Country'] = LabelEncoder().fit_transform(ufos['Country']) ufos.head() ``` Ваши данные должны выглядеть так: ```output Seconds Country Latitude Longitude 2 20.0 3 53.200000 -2.916667 3 20.0 4 28.978333 -96.645833 14 30.0 4 35.823889 -80.253611 23 60.0 4 45.582778 -122.352222 24 3.0 3 51.783333 -0.783333 ``` ## Упражнение - создание модели Теперь вы можете подготовиться к обучению модели, разделив данные на тренировочную и тестовую группы. 1. Выберите три признака, на которых вы хотите обучать модель, в качестве вектора X, а вектор y будет `Country`. Вы хотите иметь возможность вводить `Seconds`, `Latitude` и `Longitude` и получать идентификатор страны. ```python from sklearn.model_selection import train_test_split Selected_features = ['Seconds','Latitude','Longitude'] X = ufos[Selected_features] y = ufos['Country'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) ``` 1. Обучите модель с использованием логистической регрессии: ```python from sklearn.metrics import accuracy_score, classification_report from sklearn.linear_model import LogisticRegression model = LogisticRegression() model.fit(X_train, y_train) predictions = model.predict(X_test) print(classification_report(y_test, predictions)) print('Predicted labels: ', predictions) print('Accuracy: ', accuracy_score(y_test, predictions)) ``` Точность неплохая **(около 95%)**, что неудивительно, так как `Country` и `Latitude/Longitude` коррелируют. Созданная вами модель не является очень революционной, так как вы должны быть в состоянии определить `Country` по его `Latitude` и `Longitude`, но это хорошее упражнение для обучения на сырых данных, которые вы очистили, экспортировали, а затем использовали эту модель в веб-приложении. ## Упражнение - "запаковка" модели Теперь пришло время _запаковать_ вашу модель! Вы можете сделать это в несколько строк кода. После того как модель будет _запакована_, загрузите ее и протестируйте на примере массива данных, содержащего значения для секунд, широты и долготы. ```python import pickle model_filename = 'ufo-model.pkl' pickle.dump(model, open(model_filename,'wb')) model = pickle.load(open('ufo-model.pkl','rb')) print(model.predict([[50,44,-12]])) ``` Модель возвращает **'3'**, что является кодом страны для Великобритании. Удивительно! 👽 ## Упражнение - создание приложения Flask Теперь вы можете создать приложение Flask, чтобы вызывать вашу модель и возвращать аналогичные результаты, но в более визуально привлекательной форме. 1. Начните с создания папки **web-app** рядом с файлом _notebook.ipynb_, где находится ваш файл _ufo-model.pkl_. 1. В этой папке создайте еще три папки: **static**, с папкой **css** внутри нее, и **templates**. Теперь у вас должны быть следующие файлы и директории: ```output web-app/ static/ css/ templates/ notebook.ipynb ufo-model.pkl ``` ✅ Обратитесь к папке с решением, чтобы увидеть готовое приложение 1. Первый файл, который нужно создать в папке _web-app_, это файл **requirements.txt**. Как _package.json_ в приложении на JavaScript, этот файл перечисляет зависимости, необходимые для приложения. В **requirements.txt** добавьте строки: ```text scikit-learn pandas numpy flask ``` 1. Теперь выполните этот файл, перейдя в _web-app_: ```bash cd web-app ``` 1. В вашем терминале введите `pip install`, чтобы установить библиотеки, перечисленные в _requirements.txt_: ```bash pip install -r requirements.txt ``` 1. Теперь вы готовы создать еще три файла, чтобы завершить приложение: 1. Создайте **app.py** в корневой папке. 2. Создайте **index.html** в папке _templates_. 3. Создайте **styles.css** в папке _static/css_. 1. Заполните файл _styles.css_ несколькими стилями: ```css body { width: 100%; height: 100%; font-family: 'Helvetica'; background: black; color: #fff; text-align: center; letter-spacing: 1.4px; font-size: 30px; } input { min-width: 150px; } .grid { width: 300px; border: 1px solid #2d2d2d; display: grid; justify-content: center; margin: 20px auto; } .box { color: #fff; background: #2d2d2d; padding: 12px; display: inline-block; } ``` 1. Далее, заполните файл _index.html_: ```html
According to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?
{{ prediction_text }}