Франко Гарсия Педрегал

В этой статье представлена ​​реализация двух подходов, которые я использую для прогнозирования руки с 5 картами с использованием алгоритмов машинного обучения случайного леса и деревьев решений.

Введение

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

Состав этой колоды из 52 карт состоит из следующих

Говоря о вероятности

  • Вероятность вытягивания данной руки рассчитывается путем деления количества способов вытягивания руки (Частота) на общее количество рук из 5 карт, чтобы мы могли иметь 2 598 960 возможных комбинаций с 5 картами.
  • Например, есть 4 разных способа собрать флеш-рояль (по одному на каждую масть), поэтому вероятность составляет 4/2 598 960, или один из 649 740. Тогда можно было бы ожидать, что эта рука будет вытягиваться примерно один раз из каждых 649 740 розыгрышей, или почти 0,000154% случаев.

Рейтинг рук

С 5 картами у нас есть 10 разных рук, и мы можем упорядочить их по силе, начиная с флеш-рояля.

Набор данных

Набор данных, который мы будем изучать в этом посте, — это данные о покерных раздачах из репозитория машинного обучения UCI.

Каждая запись в наборе данных представляет собой пример руки, состоящей из пяти игральных карт, взятых из стандартной колоды из 52 карт. Каждая карта описывается с использованием двух атрибутов (мать и ранг), всего 10 атрибутов прогнозирования. Целевая колонка описывает раздачу с возможными вариантами:

Информация об атрибутах:

1) S1 «Масть карты №1»
Порядковый номер (1–4), представляющий {червы, пики, бубны, трефы}

2) C1 «Ранг карты №1»
Числовое значение (1–13), представляющее (туз, 2, 3, … , дама, король)

3) S2 «Масть карты № 2»
Порядковый номер (1–4), представляющий {червы, пики, бубны, трефы}

4) C2 «Ранг карты №2»
Числовое значение (1–13), представляющее (туз, 2, 3, … , дама, король)

5) S3 «Масть карты № 3»
Порядковый номер (1–4), представляющий {червы, пики, бубны, трефы}

6) C3 «Ранг карты №3»
Числовое значение (1–13), представляющее (туз, 2, 3, … , дама, король)

7) S4 «Масть карты № 4»
Порядковый номер (1–4), представляющий {червы, пики, бубны, трефы}

8) C4 «Ранг карты №4»
Числовое значение (1–13), представляющее (туз, 2, 3, … , дама, король)

9) S5 «Масть карты № 5»
Порядковый номер (1–4), представляющий {червы, пики, бубны, трефы}

10) C5 «Ранг карты 5»
Числовое значение (1–13), представляющее (туз, 2, 3, … , дама, король)

11) КЛАСС «Покерная рука»
Порядковый номер (0–9)

0: Ничего в руках; не признанная покерная комбинация
1: Одна пара; одна пара одинаковых рангов из пяти карт
2: две пары; две пары одинаковых рангов в пяти картах
3: Тройка; три равных ранга в пяти картах
4: Straight; пять карт, расположенных последовательно без пропусков
5: Флеш; пять карт одной масти
6: Фулл-хаус; пара + тройка разного ранга
7: Каре; четыре равных ранга на пяти картах
8: Стрит-флеш; стрит + флеш
9: флеш-рояль; {туз, король, дама, валет, десятка} + флеш

Баланс классов

Модельное предложение

Для этой задачи мы будем использовать 2 подхода с 2 моделями в каждом подходе:

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

Второй подход мы объединим 3 сильнейшие руки в один класс под названием «Покер или лучше», а затем создадим те же 2 модели: случайный лес и третье решение.

Вспомогательные функции

Мы начнем тренировать Решение Три. Преимущество этого набора данных в том, что мы уже разделили его на обучение и тестирование, нам просто нужно указать, какие «X» и наши «Y».

X_train_pre = предварительные_данные (поезд)

X_test_pre = предварительные_данные (тест)

X_train = X_train_pre.loc[:,X_train_pre.columns != ‘Рука’]

X_test = X_test_pre.loc[:,X_test_pre.columns != ‘Рука’]

Если бы мы тренировались с такими данными, у нас были бы очень низкие показатели точности ниже 0,50, но почему?

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

def preprocess_data (данные: pd.DataFrame):

ДФ = data.copy ()

dfc = df[['C1', 'C2', 'C3', 'C4', 'C5']]

dfc.values.sort()

df[['C1', 'C2', 'C3', 'C4', 'C5']] = dfc

df = df[[‘C1’, ‘C2’, ‘C3’, ‘C4’, ‘C5’, ‘S1’, ‘S2’, ‘S3’, ‘S4’, ‘S5’, ‘Рука’]]

вернуть дф

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

Это кривые ROC или ROCAUC (рабочая характеристика приемника/площадь под кривой) отображают истинную положительную скорость по оси Y и ложноположительную скорость по оси X как в глобальном среднем, так и для каждого класса. Таким образом, идеальной точкой является верхний левый угол графика: ложные срабатывания равны нулю, а истинные срабатывания — единице.

Как мы видим, все руки выше флеша имеют проблемы с нашими тремя

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

Уникальная функция подсчета

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

Это самый большой пример, потому что у нас есть 5 разных мастей карт.

def add_unique_count(df:pd.DataFrame):

tmp = df[['S1', 'S2', 'S3', 'S4', 'S5']]df['UniqueS'] = tmp.apply(lambda x: len(np.unique(x )) , ось=1)

Разностная функция

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

определение add_diffs(df:pd.DataFrame):

df[‘Diff1’] = df[‘C5’] — df[‘C4’]

df[‘Diff2’] = df[‘C4’] — df[‘C3’]

df[‘Diff3’] = df[‘C3’] — df[‘C2’]

df[‘Diff4’] = df[‘C2’] — df[‘C1’]

Для второго предложения мы собираемся сократить еще 3 руки Силы в один вызов класса Poker or Better, поэтому нам понадобится эта функция для изменения данных.

poker_df.loc[poker_df[‘Рука’] ›= 7, ‘Рука’] = 7

test.loc[test[‘Рука’] ›= 7, ‘Рука’] = 7

Чтобы увидеть реализацию обоих предложений, проверьте mi репозиторий

Чтобы увидеть Результаты

Ссылки

Выбор правильного оценщика — документация scikit-learn 0.23.2. (2020). Получено 12 ноября 2020 г. с https://scikit-learn.org/stable/tutorial/machine_learning_map/

Отчет о классификации — документация Yellowbrick v1.2. (2020). Получено 12 ноября 2020 г. с https://www.scikit-yb.org/en/latest/api/classifier/classification_report.html.

Как старый добрый алгоритм сортировки помогает отличной технике машинного обучения. (2020). Получено 12 ноября 2020 г. с сайта https://towardsdatascience.com/how-the-good-old-sorting-algorithm-helps-a-great-machine-learning-technique-9e744020254b.

ROCAUC — Документация по Yellowbrick v1.2. (2020). Получено 12 ноября 2020 г. с https://www.scikit-yb.org/en/latest/api/classifier/rocauc.html.

Классификация набора данных UCI Poker. (2020). Получено 12 ноября 2020 г. с https://www.kaggle.com/rasvob/uci-poker-dataset-classification/comments.

Визуальное машинное обучение с помощью Yellowbrick. (2020). Получено 12 ноября 2020 г. с https://www.coursera.org/projects/machine-learning-visualization.