Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение.
В этом процессе мы будем использовать неконтролируемое обучение, чтобы сгруппировать или классифицировать выступления этих игроков MLB во время их новичков.
Об обучении без учителя:
В машинном обучении есть две категории: обучение с учителем и обучение без учителя. Обучение с учителем обычно используется, когда специалист по данным хочет делать прогнозы на основе набора данных. В этих моделях алгоритму дается «ответ», а также входные данные, и он пытается создать модель, которая сможет предсказать правильный ответ, когда ему будут предоставлены новые данные.
С другой стороны, неконтролируемое обучение — это скорее ненаправленная форма машинного обучения, которая пытается создать логику из кажущихся хаотичными данных. Цель состоит не в том, чтобы предсказать результат или неизвестную переменную на основе нашего выбора данных, а в том, чтобы поместить имеющиеся у нас данные в группы, которые имеют схожие характеристики. Эта кластеризация может помочь выявить закономерности в данных и позволяет нам проводить аналогии между точками данных.
Модель в этом приложении использует алгоритм KMeans для классификации поступающих данных. Алгоритм KMeans достигается путем определения небольшого количества центроидов (относительно размера данных) и последующего уменьшения расстояния между каждой точкой данных до ближайшего к ней центроида. Ближайший центроид определяет группу, в которую попадает каждая точка данных.
В конечном счете, неконтролируемое обучение позволяет улавливать структуры и закономерности, которые иначе люди не смогли бы распознать.
Анализ 1000 лучших нападающих MLB и сезонов их новичков:
Чтобы изучить это приложение и сделать его своим, прочитайте раздел Процесс. Чтобы просмотреть результаты, перейдите к разделу Результаты.
В этом анализе рассматривались 1000 лучших нападающих MLB (по летучим мышам) и извлекались данные из их сезонов-новичков. Затем данные были разделены на 3 кластера с помощью неконтролируемого алгоритма машинного обучения KMeans.
Это приложение было запущено в Google Colaboratory с использованием ноутбука Jupyter для анализа данных и запуска наших алгоритмов машинного обучения.
Весь блокнот можно посмотреть по адресу: https://colab.research.google.com/drive/1za9oElCw2cTWOYQLagztB7sgQcnbHpL2?usp=sharing
Для запуска блокнота необходимо загрузить функции зависимостей из скрипта Python scraping_player_data.py по следующей ссылке Github: https://github.com/miltiades-the-general/mlb_player_classification/tree/main/web_scraping.
Процесс:
Сначала мы импортируем наши служебные функции из scraping_player_data.py. Этот сценарий управляет процессом извлечения статистических таблиц из справочника по бейсболу для 1000 лучших игроков с помощью at-bats.
Сначала мы собираем ссылки для лучших игроков и сохраняем их в объекте под названием «ссылки». Затем мы перебираем эти ссылки и извлекаем данные таблицы из конечной точки ссылки на бейсбол «игрок». Мы можем использовать pandas, чтобы превратить эти таблицы в фреймы данных, которые мы будем хранить в списке под названием «df_list».
Мы также очищаем имена игроков в верхней части страницы каждого игрока и сохраняем их в name_list. (Мы используем time.sleep(.5) на каждой итерации, чтобы быть в безопасности и быть уверенными, что нас не помечает Baseball Reference).
При этом у нас есть список фреймов данных, каждый из которых хранит данные игрока среди трех различных вариантов и каждый содержит множество категорий. Одна категория — это стандартные данные об ударах, вторая категория — данные о ценности игрока, а третья категория — расширенные данные об ударах. Все эти таблицы объединяются в функции scrape.scrape_statistic_tables(). Затем нам нужно взять эти трехмерные таблицы, которые были возвращены, и объединить их в одну строку, чтобы они стали двумерными. Нам также нужно очистить данные, чтобы они были в типе данных, который мы можем передать в наш алгоритм машинного обучения.
Во-первых, давайте определим категории, которые мы хотим включить в нашу модель.
категории = ['Age_x', 'G_x', 'PA_x', 'AB', 'R', 'H', '2B', '3B', 'HR', 'RBI', 'SB', 'CS' , «BB», «SO», «BA», «OBP», «SLG», «OPS», «OPS+», «TB», «rOBA», «Rbat+», «BAbip», «ISO», « HR%», «SO%», «BB%», «WPA», «cWPA», «RE24», «RS%», «SB%», «XBT%», «Rbat», «Rbaser», « Rdp», «Rfield», «Rpos», «RAA», «WAA», «Rrep», «RAR», «WAR», «waaWL%», «162WL%», «oWAR», «dWAR», « оRAR']
Мы также должны определить категории, которые идут со знаком процента (%), потому что мы должны обрабатывать их особым образом в нашей очистке данных.
pct_cats = ["HR%", "SO%", "BB%", "RS%", "SB%", "XBT%", "cWPA"]
Следующая функция clean_df возьмет категории, содержащие «%», и вернет их как числа с плавающей запятой без знака. Значения NaN сохраняются через эту функцию.
Функция flatten_df вернет трехмерный фрейм данных как двумерный фрейм данных. Он также удаляет расширенные категории, которых нет в старых данных игрока. Эта функция достигает своей цели, превращая фрейм данных в стек, а затем переименовывая индекс, чтобы включить год и статистическую категорию. Это означает, что каждой точке данных присваивается индекс. Наконец, кадр данных транспонируется, чтобы принять 2-мерную форму.
Двумерные фреймы данных затем добавляются друг к другу для создания единого фрейма данных, содержащего каждого игрока.
Далее мы импортируем зависимости, необходимые для нашей модели машинного обучения, используя библиотеку обучения Sci-Kit. Чтобы узнать больше о кластеризации, обратитесь к их документации: https://scikit-learn.org/stable/modules/clustering.html#clustering.
Затем мы масштабируем наши данные с помощью метода sklearn.StandardScaler(). Мы создаем новый фрейм данных из этих масштабированных данных. Стандартный масштабатор уравняет масштаб данных, чтобы стандартное отклонение каждой категории было равно 1,0. Это поможет гарантировать, что в нашей модели ни одна категория не будет иметь слишком большого или легкого веса.
Наши данные могут содержать несколько столбцов, которые не содержат никаких данных для определенных игроков, потому что статистика не велась, когда игрок играл, или по другим причинам. Кроме того, этот фрейм данных зависит от года, а это означает, что число в начале имени столбца (т. е. 0_Age_x) соответствует 0-му году для игрока. Есть несколько способов решить эти проблемы, но для целей этого анализа мы удалим значения NaN, оставив для этих игроков только год новичка или 0-й год.
Далее мы определим оптимальное количество кластеров для использования в нашей модели. Это можно сделать с помощью «метода локтя», когда мы попробуем конечное число кластеров, а затем будем наблюдать график их инерции. Инерция определяется расстоянием между точками данных и их центроидом. Мы перебираем диапазон нашего кластера (0, 11), а затем отслеживаем значение инерции, предоставляемое каждой моделью. Мы предпринимаем этот шаг, чтобы гарантировать, что мы не применяем слишком много кластеров к нашим данным и что мы не ограничиваем нашу модель слишком небольшим количеством кластеров.
Далее нам нужно построить наши значения инерции для оценки «локтя». Это может потребовать от вас установки hvplot, если вы используете Google Colaboratory.
Импортируйте библиотеку hvplot.pandas и укажите расширение «bokeh», чтобы Google Colaboratory могла отображать объект hvplot. Затем мы строим инерцию по их значениям k. Выбор оптимального значения k с помощью этого метода может быть несколько субъективным, но обычно аналитик данных наблюдает последний заметный изгиб на графике и использует его в качестве значения k. Для этого приложения 3 кластера соответствуют последнему основному крику. Кроме того, вы увидите обесценивающуюся отдачу от увеличения количества кластеров.
Мы создаем экземпляр модели, используя 3 кластера.
Мы делаем прогнозы для наших данных, используя метод .predict() в нашем фрейме данных. Затем мы создаем словарь, который будет связывать наш список игроков с группами, найденными моделью. Создайте пустой фрейм данных с указанными ниже столбцами и назовите его predicts_df.
Столбец «имя» и столбец «группа» заполняются нашим списком имен и массивом прогнозов соответственно.
Мы берем исходный список фреймов данных из справочника по бейсболу и добавляем данные от каждого игрока в первый год к фрейму данных predicts_df.
Затем мы создаем фреймы данных каждой группы, найденной моделью. (Чтобы увидеть полный список каждой группы, созданной моделью, просмотрите каталог csv_files в исходном коде этого проекта. Каждая группа содержится в файлах csv и json).
Модель машинного обучения алгоритма KMeans организовала этих игроков в группу 1 на основе особенностей, которые могут быть неочевидны для человеческой интуиции. Тем не менее, алгоритм обнаружил закономерности и особенности в статистике года новичков этих игроков, которые близко классифицируют их друг с другом.
Повторите эту группировку для group_2 и group_3.
Результаты:
Чтобы просмотреть полные результаты классификации наших моделей машинного обучения, изучите CSV-файлы по следующей ссылке: https://github.com/miltiades-the-general/mlb_player_classification/tree/main/web_scraping/csv_files.
Мы можем провести быстрый анализ, чтобы увидеть, как эти группы различаются по основным показателям. Мы можем видеть, например, что группа 2 (где «группа» == 1, для ясности) имеет самый высокий средний выигрыш выше замены (WAR) в 3,46. Это означает, что у этой группы были более продуктивные годы новичка, чем у двух других групп. У всех трех групп были одинаковые хоум-раны. Группа 3 показала самые низкие показатели по всем трем показателям. У группы 1 был второй самый низкий показатель WAR, но самый высокий показатель по базе плюс пробкам (OPS). Необходимы дополнительные исследования, чтобы раскрыть причину этого несоответствия, но одно из предположений состоит в том, что эти игроки показали хорошие результаты в небольшой выборке, что указывает на то, почему процентная статистика, такая как OPS, высока, а кумулятивная статистика, такая как WAR, не так высока.
Наконец, давайте рассмотрим эти группы более внимательно. Возможно, если мы посмотрим на случайных людей из них, мы сможем выявить общие черты, которые уловила модель. Мы можем найти случайного игрока из каждой группы и добавить его в список, используя следующий метод.
Из случайных игроков из группы 1 давайте взглянем на Дэйва Филли, Майка Мустакаса и Джейсона Джамби. Из-за причудливого способа сбора данных бейсбольной справкой статистика года новичка игрока будет также включать его статистику низшей лиги, если он играл в низшей лиге в течение этого года. Мы включим эти данные в наш анализ.
Дэйв Филли:
Майк Мустакас:
Джейсон Джамби:
Группа 1 показала низкую, но положительную продуктивность в первый год. У каждого из них был OPS в диапазоне 0,700–0,800 за весь сезон. У Джейсона Джамби, похоже, была более высокая производительность на тарелке с 33 хоумранами между низшей и высшей лигами в том году, однако эта результативность в атаке могла быть компенсирована тем, что он играл на 1-й базе, а также играл потенциально плохую защиту, что могло повредить его игроку. значение в целом. Эти игроки, вероятно, классифицируются как имеющие хорошую процентную статистику с плохой кумулятивной статистикой и общим производством. Это согласуется с выводом о том, что у игроков в этой группе был самый высокий OPS, но только второй по величине WAR.
Из группы 2 давайте посмотрим на Джейсона Хейворда, Юнель Эскобар и Чика Штала.
Джейсон Хейворд:
Юнель Эскобар:
Чик Стал:
Все эти игроки из группы 2 показали результат выше среднего в первые годы своей карьеры в высшей лиге с показателями WAR 6,4, 2,4 и 3,0 соответственно. Каждый из них добился этого результата по-разному, поскольку Джейсон Хейворд совершил больше хоумранов, чем два других игрока вместе взятых, однако у всех трех игроков были очень похожие пробивные удары и ОПС. Этот вывод имеет смысл с выводами, которые мы обнаружили в группе 2, у которой был самый высокий средний показатель WAR.
Наконец, давайте взглянем на Фредди Пэрента из группы 3, Эноса Кейбелла и Роджера Пекинпо.
Фредди Родитель:
Энос Кэбелл:
Роджер Пекинпо:
У всех троих этих игроков были плохие результаты на уровне высшей лиги в первые сезоны. Все они имели отрицательный WAR и значительно ниже уровня замены OPS+. Следует отметить, что Энос Кэбелл был продуктивен на уровне низшей лиги, но этого было недостаточно, чтобы компенсировать его низкую ценность игрока, которая отслеживается только на уровне высшей лиги.
Основываясь на этом наблюдательном анализе, я бы классифицировал эти группы следующим образом:
Группа 1: Продуктивно при небольшом размере выборки
Группа 2: новички-суперзвезды
Группа 3. Плохие показатели
Вывод:
Модель хорошо показала себя при классификации этого списка из 1000 игроков на 3 отдельные категории с идентифицируемыми различиями. Интересно посмотреть, как машина видит эти 3 отдельные группы по их производству в первые сезоны.