[Перевод] Как прогнозировать результаты спортивных матчей с помощью проекта ML на Python Pandas, Keras, Flask, Docker и Heroku
Во время Чемпионата мира по регби в 2019 году я сделал небольшой научный проект Data Science, чтобы попытаться спрогнозировать результаты матчей, написав о нем здесь. Я развил проект до примера от начала до конца, чтобы продемонстрировать, как развернуть модель машинного обучения в виде интерактивного веб-приложения.
Цель
Дать высокоуровневый обзор ключевых шагов, необходимых для перехода от необработанных данных к развёрнутому приложению машинного обучения.
После того как вы посмотрите этот обзор, выберите интересующую вас тему, найдите данные, засучите рукава и постарайтесь создать собственное приложение машинного обучения, от подготовки данных до развертывания.
Ключевые шаги
- Обработка данных с помощью Pandas и хранение данных с помощью SQLite.
- Машинное обучение (нейронная сеть) с помощью Keras.
- Разработка веб-приложения с помощью Flask (и немного CSS и HTML).
- Развёртывание приложения с помощью Docker и Heroku.
Код доступен на GitHub, приложение в действии можно посмотреть здесь. Обратите внимание, что этот код не обязательно соответствует уровню производственного, он предназначен, чтобы показать, что можно сделать, как отправная точка. Работающее приложение использует моментальный снимок данных в определённый момент.
1. Работа с данными и их хранение с помощью Pandas и SQLite
Специалисты по Data Science тратят около 45% своего времени просто на подготовку данных для разработки модели.
Работа с данными включает очистку, структуризацию и обогащение данных таким образом, чтобы они были подготовлены для модели ML.
Если вы не используете уже очищенный набор данных (что редко бывает в реальном мире), чтобы лучше понять профиль данных, вам потребуется выполнить их исследовательский анализ.
Pandas-profiling — отличный модуль для EDA. Он генерирует отчёты профилирования фреймов данных, включая квантильную и описательную статистику, корреляции, отсутствующие значения и гистограммы.
Пример вывода из Pandas-profiling для исследовательского анализа данных (EDA).
Для этого проекта мне потребовались данные из ESPN Scrum. Вы можете найти подробные инструкции по очистке в файле data_prep.py, например, определение формата даты матча с помощью метода to_datetime()
. Я также обогатил данные с помощью World Rugby Rankings и оценки навыков при помощи Microsoft TrueSkill рейтинговая система.
Если для начала вам нужны наборы данных, репозиторий UC Irvine«s Machine Learning и Kaggle хорошие источники. В качестве альтернативы можно воспользоваться BeautifulSoup.
Я сохранил фреймы данных в виде таблиц в базе данных SQLite. Это легкая база данных и она наиболее широко распространена в мире. Конечно, можно использовать простые файлы csv, это даже дает возможность изучить о SQLite. Приведенный ниже код подключается к базе данных matchresults
и в виде таблицы записывает в нее DataFrame lateststats
.
conn = sqlite3.connect ('match_results.db')
latest_stats.to_sql ('latest_stats', conn, if_exists = 'replace')
Теперь у нас есть данные — пора протестировать и обучить модель.
2. Машинное обучение — нейронные сети с Keras
Тестирование
Среднеквадратичная ошибка (MSE) использовалась как функция потерь для минимизации. Была выполнена настройка гиперпараметров (у Джейсона Браунли есть руководство), я экспериментировал с широкими (один слой с большим количеством нейронов) и глубокими (больше слоев, но меньше нейронов на слой) сетями, пока MSE не улучшилась значительно.
Хочется, чтобы модель могла хорошо работать с данными, которых не видела. Если переобучить модель, у вас может быть низкая ошибка в обучающих данных, но высокая ошибка в тестовых (которые модель не видела ранее). Когда это происходит, это означает, что модель слишком хорошо усвоила обучающие данные и не может обобщить их на новые данные. Есть разные способы избежать переобучения.
Ниже видно, что MSE быстро снижается до ~25 эпох, а затем остаётся относительно стабильным как для данных обучения, так и для данных тестирования.
MSE и количество эпох.
Обучение
У последней модели первый слой состоит из 15 нейронов, второй слой — из 8 нейронов, оба с усечённым линейным преобразованием (ReLU). Она собиралась с помощью алгоритма оптимизации Adam, эффективного алгоритма градиентного спуска.
model = Sequential ()
model.add (Dense (15, input_dim = 5, kernel_initializer = 'normal', activate = 'relu'))
model.add (Dense (8, kernel_initializer = 'normal', activate = 'relu') )
model.add (Dense (2, kernel_initializer = 'normal'))
model.compile (loss = 'mse', optimizer = 'adam')
Сохранение модели
Функция save()
применяется для сохранения окончательной модели Keras. Она сохраняет архитектуру модели и её веса и позже позволит загрузить модель в приложение, чтобы делать прогнозы на основе новых данных.
3. Веб-приложение с применением Flask (и немного CSS/HTML)
Flask — это веб-фреймворк, который можно использовать для относительно быстрой разработки веб-приложений. Руководство по быстрой разработке найдется здесь. Код ниже из app.py
по существу настраивает домашнюю страницу, предоставляя пользователю страницу index.html
:
Домашняя страница приложения с формой ввода пользователя.
Для формы используется WTForms, чтобы пользователь мог выбрать две команды по регби. Когда нажимается кнопка, входные данные отправляются в сохранённую модель ML через функцию model_predict
. Полученные прогнозы модели затем отправляются в качестве входных переменных в шаблон prediction.html
.
@app.route("/", methods=['GET', 'POST'])
def home():
form = TeamForm(request.form)
# Get team names and send to model
if request.method == 'POST' and form.validate():
team1 = request.form['team1']
team2 = request.form['team2']
return render_template('prediction.html', win_prob=model_predict(team1,team2)[0],
score=model_predict(team1, team2)[1])
# Send template information to index.html
return render_template('index.html', form=form)
Шаблон prediction.html
выполняет три ключевые функции:
- Получает вероятность выигрыша и счёт, отправленные из выходных данных модели для отображения конечному пользователю (через переменные
win_prob
иscore
). - Отображает пользователю кнопку для возврата на главную страницу.
- Ссылается на файл main.css для стилизации.
Страница результатов прогноза:
Prediction
Predictions
{% block content %}
{{win_prob}}
{{score}}
{% endblock %}