Начиная

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

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

Сообщение Юаня было очень подробным и проницательным, и моя методика очистки страницы статистики во многом была вдохновлена ​​тем, как он структурировал свои парсеры. Спасибо, Юань!

В предсказателе Юаня он использовал данные боя, которые будут доступны перед боем, со статистикой, которую я назвал «статической статистикой боя», например, возраст, досягаемость, вес, рекорд W / L и т.д. поединки, такие как нанесенные удары, тейкдауны, попытки подчинения и передачи защитника.

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

  • Первая модель использует статическую статистику в качестве независимых переменных для бойца 1 и бойца 2, а затем предсказывает зависимые переменные, динамическую статистику боя. ( Задача многоцелевой регрессии ) .
  • Затем мы передаем статическую и динамическую статистику боя модели общего победителя, которая предсказывает, победит ли боец ​​1 или боец ​​2. (Проблема бинарной классификации) .

Сбор статистики UFC

Скребки для этого проекта разбиты на двух пауков Scrapy, которые просматривают два раздела UFC Fight Stats:

  • Бут скребок
  • Истребитель Скребок

Паук Bout сканирует раздел событий UFC Fight Stats и записывает конкретную статистику боя, такую ​​как str_stat_f1 (статистика ударов для бойца 1) для каждого бойца, многие из которых станут нашими зависимыми переменными для задачи регрессии с несколькими целями. Fighter1 и Fighter2 — это имена бойцов, участвующих в схватке, и мы объединяем данные о бойцах по этим значениям.

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

Я сохраняю оба этих объекта данных в виде таблиц в базе данных SQLite и имею небольшой скрипт для создания CSV-файла комбинированных боев, в котором каждая строка представляет собой бой с добавленными индивидуальными характеристиками бойца fighter1 и fighter2. Этот CSV, а также CSV-представление только объекта данных бойцов будут двумя файлами, которые мы будем использовать для построения обеих моделей.

Если вам интересно увидеть фактическую логику очистки для каждого паука, посмотрите здесь .

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

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

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

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

Одним из самых сложных аспектов предварительной обработки было изменение порядка статистики fighter1 и fighter2.

Причина, по которой мне пришлось перетасовать этот порядок, заключалась в том, что данные о боях UFC всегда упорядочивались таким образом, что боец ​​1 является победителем, поэтому мне пришлось найти способ случайным образом выбрать половину набора данных и поменять местами статистические позиции бойца 1 и бойца 2 друг с другом так что окончательный набор данных аккуратно разбит так, что 50% fighter1 являются победителями, а 50% fighter2 являются победителями.

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

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

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

Моделирование

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

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

Модель статистики

Модель статистики принимает масштабированное числовое представление всех характеристик, доступных для обоих бойцов перед боем, а ее выходной слой состоит из 8 характеристик.

Поскольку это проблема регрессии, последний слой модели статистики имеет линейную активацию (активация по умолчанию). Для потерь я использовал mse с R² в качестве метрики модели для оценки производительности.

R² для этой модели обычно составляет около 0,63–64 в наборе проверки, что неплохо, но стоит отметить, что R² всегда будет увеличиваться по мере добавления дополнительного предиктора (вывода), и некоторые из них могут быть отнесены на счет к случайному шуму, который случайно выравнивается. Чтобы противостоять этому, я добавлю скорректированный R², чтобы наказывать модель за каждый новый вывод, добавленный в новой версии.

Модель прогноза победителя

Как и модель статистики, она следует за базовой единой полностью связанной архитектурой скрытого уровня. Зависимая переменная — это либо 0 (боец1), либо 1 (боец2), поэтому я добавляю простую активацию сигмоида на последнем слое, чтобы предсказать один из этих результатов.

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

Изображение для публикации

Обслуживание моделей через API

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

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

Конвейер обрабатывает фрейм данных для каждого бойца, а затем объединяет их в правильную форму и порядок для прогнозирования статистики. После того, как значения прогноза статистики возвращены, они добавляются в виде столбцов с соответствующими именами и позициями в фрейм данных и передаются модели прогнозирования победителя, возвращающей результат, связанный либо с бойцом 1, либо с бойцом 2.

React Front End

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

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

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

Заключение

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

PS: Может быть, пока не стоит ставить дом на все предсказанные модели.