Для этого проекта мне было интересно поработать с библиотекой svm scikit-learn и попытаться применить модель классификатора Support Vector Machine к чему-то, что меня также интересует: League of Legends. Вот краткий обзор того, что такое SVM:

SVM — это модель машинного обучения, реализующая концепцию классификатора опорных векторов. Во-первых, у вас есть два набора разных ярлыков, и вы пытаетесь их классифицировать. Как показано на рисунке выше, красный и синий цвета разбросаны по двухмерной плоскости и разделены линией. Эта линия является границей решения, и именно ее ищет модель, чтобы классифицировать, является ли точка красной или синей. Так как же модель ищет такую ​​линию? Во-первых, модель рисует два опорных вектора, параллельных границе решения, которая касается точки данных, ближайшей к границе решения на рисунке. Затем модель пытается максимизировать ортогональное расстояние между двумя опорными векторами, и граница решения рисуется посередине. Поля между границей решения и каждым из векторов поддержки называются мягкими полями. Затем классификатор опорных векторов выполняет нечто, называемое перекрестной проверкой, когда модель определяет наилучшее место для размещения опорного вектора. Как видно выше на диаграмме мягкого поля, есть красная точка данных, которая была бы неправильно классифицирована как синяя, если бы модель следовала построенной границе решения. Однако, если модель обновится, чтобы нарисовать опорные векторы в том месте, где находилась самая дальняя красная точка данных, тогда было бы еще четыре синих точки данных, которые будут неправильно классифицированы как красные. Модель оценивает точки, которые находятся в пределах мягких полей, и выбирает наилучшее место для размещения опорных векторов, чтобы свести к минимуму неправильные классификации.

Однако существуют некоторые ограничения для следования строгому классификатору опорных векторов. Что, если бы данные выглядели как на картинке выше? Для человеческого глаза мы можем легко нарисовать круг вокруг красных квадратов, чтобы разделить два класса; машина не может провести линейное разделение для них двоих. Вот чем SVM отличается от простого SVC. К каждой точке данных применяется функция ядра для преобразования данных в более высокое измерение, чтобы можно было провести линейную границу решения. Функция применяется только во время выполнения при сравнении точек, поэтому исходные данные не изменяются. Полиномиальное ядро ​​может визуализировать точки вдоль линии как двумерную полиномиальную функцию. Другая функция ядра — это радиальное ядро, как показано выше, которое может работать с бесконечным числом измерений.

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

Моя первая цель — получить обучающие данные. Если бы я хотел накормить SVM многими функциями, определяющими позицию, мне нужно было бы взять их откуда-то, кто мог бы предоставить мне такие детали, как счет крипов по минутам, процент доли золота, убийства, смерти, помощь, нанесенный урон и т. д. Riot API может предоставить такую ​​информацию, и это будет самый большой набор данных, но игры с одиночной очередью, как правило, более непредсказуемы. С такими сырными стратегиями, как воронка, подергивание джунглей, отсутствие ADC CS Senna или запатентованная Zilean top 0/10 моего друга Патрика, некоторые данные могут быть неточным представлением того, что влечет за собой роль. Поэтому свои тренировочные данные я взял из киберспорта, где есть более последовательные данные для тренировки модели. Поскольку API нет, я получил свою статистику с https://lol.gamepedia.com, где я использовал BeautifulSoup для очистки статистики в вектор. Теперь уже есть много недостатков в использовании этих данных для прогнозирования позиций.

Во-первых, League of Legends не ограничивается только традиционными ролями. В каждом из них существуют разные классы, такие как Маги против Ассасинов на средней линии, Танки против Чародеев в роли поддержки или Бойцы против Керри в джунглях. У разных ролей могут быть одни и те же классы, которые будут иметь схожие характеристики, например, Tank Sion в середине против Tank Sion на вершине. Во-вторых, роль мидлейна и роль рекламного керри также имеют схожие характеристики, как правило, они являются керри команды, имеют большое количество убийств или крипов. Наконец, метод, с помощью которого я преобразовал свой набор данных в векторы признаков, немного ошибочен. Поскольку в Gamepedia нет отдельных игр, а есть статистика чемпионов, усредненная по всем их играм, одна игра, сыгранная на вершине Kalista, будет иметь такой же вес в обучении модели, как и двадцать игр, сыгранных Aatrox, у которых статистика усреднена. Но на данный момент данные, которые я использовал для обучения, рассматривают статистику каждого чемпиона как единый вектор характеристик, который я смогу изучить позже.

Во-первых, я взял свои данные из Gamepedia и у меня было 109 тренировочных образцов для пяти ролей, что, вероятно, недостаточно, но с этим стоит поработать в начале. Я выбираю параметры Kill, Death, Assist, Creep Score per min, Gold per min, Kill share и Gold share в качестве своих параметров. Я запустил модель с тестовой выборкой размером 9, что определенно недостаточно, чтобы свидетельствовать о точности SVM, но позволяет быстро взглянуть на функциональность модели SVM.

Хотя точность может показаться низкой, есть много вещей, которые можно изменить в выборе функций и внутренних недостатков, связанных с попыткой классифицировать позиции исключительно на основе статистики. Я предпочитаю использовать тестовые образцы из статистики саппортов весеннего плей-офф 2020, поскольку их не было в тренировочных выборках, а статистика саппорта больше всего отличается от пяти ролей. Тем не менее, точность 58,3% лучше, чем при броске игральной кости с треугольными гранями. После изучения данных обнаружилась явная разница между правильными классификациями и ошибками: количество убийств. Хотя модель действительно давала правильные классификации при попытке протестировать выборку статистики чемпионов с большим количеством сыгранных игр, данные давали ошибку для точек данных только с одной игрой, например, игра Blitzcrank, где было два убийства, в отличие от других правильно классифицированных данные тестирования, в которых было [0, 1] убийств, усредненных по многим другим играм.

После запуска модели на статистике верхней дорожки весеннего плей-офф я получил низкую точность в 16%. Тенденция, которую я начал замечать, заключалась в том, что многие из ложных классификаций неправильно классифицировали статистику поддержки как среднюю линию. Когда я запускал модель с тестовыми образцами средней полосы, точность была все еще низкой, но немного выше — 30%. Поскольку статистика чемпионов ADC и Mid была очень похожей, и было больше тренировочных данных для мида, поскольку пул чемпионов средней полосы был более разнообразным, модель, как правило, была на стороне мида, а не ADC, когда происходила ложная классификация. После запуска модели через всю статистику весенних плей-офф почти все тестовые образцы были классифицированы как лучшие, средние или поддерживающие, поскольку их характеристики были наиболее тангенциальными по сравнению с остальными данными.

Некоторые улучшения, над которыми я могу поработать, чтобы улучшить эту модель, — это разделение границ решений для классификации разных классов, таких как танк, маг, ассасин, поскольку между ними существует больший разрыв. Еще одна вещь, которую я мог бы изменить, — попытаться обучить модель SVM с отдельными играми, чтобы каждая игра имела одинаковый вес в модели. Быстрым решением проблемы было бы дублирование каждого вектора характеристик по количеству сыгранных игр, но это просто увеличило бы вес характеристик более популярных чемпионов в каждой роли, а не получило бы уникальные данные. Наконец, я мог бы изменить параметр модели, такой как C, который определяет, сколько выбросов данных может игнорировать модель, функцию ядра, которая по умолчанию является радиальным ядром, использующим «трюк ядра» для разделения нелинейных данных, и гамму. , который влияет на то, насколько одна обучающая выборка влияет на модель. Наконец, я мог бы использовать многоклассовую функцию SVC scikit-learn, которая использует подход OVO к обучающим данным, который сравнивает каждую функцию «один против одного» с другой функцией, а не с OVR по умолчанию, сравнивая одну функцию с остальными.

Первоначально опубликовано на http://noviceprogramming667661022.wordpress.com 16 апреля 2020 г.