[PYTHON] L'apprentissage automatique appris avec Pokemon

introduction

Le mois dernier, le Pocket Monster Sword Shield a été lancé. Au fait, avez-vous déjà joué à Pokemon? Comme le sait tous ceux qui ont joué à Pokemon, Pokemon a des valeurs de capacité comprenant HP, Kogeki, Bougyo, Tokukou, Tokubo et Quickness. On peut dire qu'un Pokémon avec une valeur de capacité plus élevée est un Pokémon plus fort. La valeur de la capacité est calculée à partir de trois valeurs: la valeur de la course, la valeur individuelle et la valeur de l'effort. (La formule est écrite ci-dessous.) ** La valeur de course ** est la valeur donnée à chaque type de Pokémon. ** La valeur individuelle ** est une valeur donnée à chaque individu. Cela montre que le même Pokémon a des forces différentes. ** La valeur d'effort ** est une valeur acquise. Les valeurs individuelles sont déterminées à la naissance, tandis que les valeurs d'effort peuvent être augmentées par le combat. Cette fois, je voudrais déterminer le type de Pokémon à partir de la valeur de race avec python.

<Formule de calcul pour le calcul de la valeur de capacité> </ span> ・ Valeur de capacité HP = (valeur de course x 2 + valeur individuelle + valeur d'effort ÷ 4) x niveau ÷ 100 + niveau + 10 ・ Valeur de capacité autre que HP = (valeur de course × 2 + valeur individuelle + valeur d'effort ÷ 4) × niveau ÷ 100 + 5} × correction de personnalité


Environnement de développement

--CPU: Processeur Intel Core i5 Quad Core 1,4 GHz de 8e génération

Première chose que j'ai faite

Quand j'ai cherché "Pokemon Machine Learning", il y avait un site qui faisait quelque chose de similaire, donc je l'ai utilisé comme référence. https://www.hands-lab.com/tech/entry/3991.html Sur ce site, j'essayais de déterminer s'il s'agissait d'un type d'eau à partir de la valeur de la race, je l'ai donc implémenté avec copier-coller pour le moment. J'ai pensé que c'était un succès car il a été jugé avec une précision de ** 85,3% **, mais en réalité, seuls les "chanceux" et les "hapinas", qui ne sont pas de type eau, ont été jugés de type eau.

Maintenant, réglons la situation. Il existe 909 types de tous les Pokémon et 123 types de Pokémon de type eau. Il existe 785 types de Pokémon de type non aquatique. Ici, supposons un modèle qui détermine qu'il ne s'agit pas d'un type d'eau, quelle que soit la valeur de race entrée. Le taux de réponse correct pour ce modèle est 785/909 x 100 = ** 86,5 [%] **.

En d'autres termes, dans le problème de la classification binaire, il s'avère que si le nombre d'échantillons des deux classifications cibles n'est pas le même, le résultat sera étrange.

Ce que j'ai fait ensuite

Sur la base de ma réflexion, j'ai fait à peu près le même nombre d'échantillons des deux objets que je souhaite classer. Cette fois, j'aimerais créer un modèle qui détermine s'il s'agit d'un type d'épée ou d'un type d'épée. (Type Hagane: 58, type Denki: 60) Cette fois, Pokemon avec le type Denki et Hagane comme bobine rare a été compté comme type Hagane. Les données Pokemon ont été empruntées à ici .

# %%
import pandas as pd
import codecs
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

with codecs.open("data/pokemon_status.csv", "r", "Shift-JIS", "ignore") as file:
    df = pd.read_table(file, delimiter=",")

df.info()


# %%
metal1 = df[df['Type 1'] == "Hagane"]
metal2 = df[df['Type 2'] == "Hagane"]
metal = pd.concat([metal1, metal2])
print("Pokémon de type acier: %d animaux" % len(metal))

elec1 = df[df['Type 1'] == "Denki"]
elec2 = df[df['Type 2'] == "Denki"]
elec = pd.concat([elec1, elec2])
print("Pokémon de type électrique: %d animaux" % len(elec))


def type_to_num(p_type):
    if p_type == "Hagane":
        return 0
    else:
        return 1


pokemon_m_e = pd.concat([metal, elec], ignore_index=True)
type1 = pokemon_m_e["Type 1"].apply(type_to_num)
type2 = pokemon_m_e["Type 2"].apply(type_to_num)
pokemon_m_e["type_num"] = type1*type2
pokemon_m_e.head()


# %%
X = pokemon_m_e.iloc[:, 7:13].values
y = pokemon_m_e["type_num"].values

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=0)
lr = LogisticRegression(C=1.0)
lr.fit(X_train, y_train)


# %%
print("score pour les données de train: %.3f" % lr.score(X_train, y_train))
print("score pour les données de test: %.3f" % lr.score(X_test, y_test))


# %%
i = 0
error1 = 0
success1 = 0
error2 = 0
success2 = 0
print("[Liste des Pokémon jugés de type pelage]")
print("----------------------------------------")
print("")
while i < len(pokemon_m_e):
    y_pred = lr.predict(X[i].reshape(1, -1))
    if y_pred == 0:
        print(pokemon_m_e.loc[i, ["Nom du Pokémon"]])
        if pokemon_m_e.loc[i, ["type_num"]].values == 0:
            success1 += 1
            print("C'est un type de pelage")
            print("")
        else:
            error1 += 1
            print("Ce n'est pas un type de pelage")
            print("")
    else:
        if pokemon_m_e.loc[i, ["type_num"]].values == 0:
            error2 += 1
        else:
            success2 += 1
    i += 1
print("----------------------------------------")
print("Nombre de Pokémon jugés du type correct: %d animaux" % success1)
print("Nombre de Pokémon correctement jugés de type Denki: %d animaux" % success2)
print("Nombre de Pokémon qui ont été jugés par erreur comme étant du type: %d animaux" % error1)
print("Nombre de Pokémon qui ont été jugés par erreur comme étant de type Denki: %d animaux" % error2)
print("")
    

Résultat de l’exécution Note pour les données du train: 0,732 score pour les données de test: 0,861

Nombre de Pokémon jugés être le type de splash correct: 48 Nombre de Pokémon correctement jugés de type Denki: 43 Nombre de Pokémon considérés comme du type qui n'est pas le type de l'épée: 13 Nombre de Pokémon qui n'ont pas été jugés de type Hagane même s'ils étaient de type Hagane: 14

Étonnamment, il a été jugé correctement, donc je pense qu'il a généralement été un succès. Rotom a été jugé comme étant du type pelage (rires).

Ce que j'ai fait de plus

Dans l'exemple ci-dessus, le type Denki et le type Hagane ont été comparés. Il existe 18 types de Pokémon en tout, mais j'aimerais essayer quelle combinaison donne la meilleure précision de jugement.

# %%
import pandas as pd
import codecs
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')

with codecs.open("data/pokemon_status.csv", "r", "Shift-JIS", "ignore") as file:
    df = pd.read_table(file, delimiter=",")

df.info()


# %%
def lr_model_pokemon(type1, type2, test_size=0.3, random_state=0, C=1.0):
    df_type1_1 = df[df['Type 1'] == type1]
    df_type2_1 = df[df['Type 2'] == type1]
    df_type_1 = pd.concat([df_type1_1, df_type2_1])

    df_type1_2 = df[df['Type 1'] == type2]
    df_type2_2 = df[df['Type 2'] == type2]
    df_type_2 = pd.concat([df_type1_2, df_type2_2])

    def type_to_num(p_type):
        if p_type == type1:
            return 0
        else:
            return 1

    pokemon_concat = pd.concat([df_type_1, df_type_2], ignore_index=True)
    type_num1 = pokemon_concat["Type 1"].apply(type_to_num)
    type_num2 = pokemon_concat["Type 2"].apply(type_to_num)
    pokemon_concat["type_num"] = type_num1 * type_num2

    X = pokemon_concat.iloc[:, 7:13].values
    y = pokemon_concat["type_num"].values

    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=test_size, random_state=random_state)
    lr = LogisticRegression(C=C)
    lr.fit(X_train, y_train)

    return [lr.score(X_train, y_train), lr.score(X_test, y_test)]


# %%
max_score_train = 0
max_score_test = 0
train_type1 = ""
test_type1 = ""
train_type2 = ""
test_type2 = ""
type_list = ["Kusa", "Hono", "Mizu", "insecte", "Ordinaire", "Mal", "Iwa", "Hagane",
             "Denki", "fantôme", "Dragon", "Esper", "finalement", "Doku", "Fée", "Jimen", "vol", "Koori"]

for type1 in type_list:
    for type2 in type_list:
        if type1 == type2:
            continue
        score = lr_model_pokemon(type1=type1, type2=type2)
        if (score[0] >= max_score_train):
            max_score_train = score[0]
            train_type1 = type1
            train_type2 = type2
        if (score[1] >= max_score_test):
            max_score_test = score[1]
            test_type1 = type1
            test_type2 = type2

print("%s, %Lorsque s, le score des données d'entraînement est maximisé: score = %.3f" %
      (train_type1, train_type2, max_score_train))
print("%s, %Lorsque s, le score des données de test est maximisé: score = %.3f" %
      (test_type1, test_type2, max_score_test))

Résultat de l’exécution Hagane, lorsqu'il est normal, maximise le score des données d'entraînement: score = 0,942 Quand c'est normal, le score des données de test est maximisé: score = 0,962

Il semble que la précision du modèle qui distingue le type de pelage et le type normal est la plus élevée. Voyons maintenant quel genre de jugement est fait.

# %%
def poke_predict(type1, type2):
    type1_1 = df[df['Type 1'] == type1]
    type2_1 = df[df['Type 2'] == type1]
    type_1 = pd.concat([type1_1, type2_1])
    print("%Pokémon de type s: %d animaux" % (type1, len(type_1)))

    type1_2 = df[df['Type 1'] == type2]
    type2_2 = df[df['Type 2'] == type2]
    type_2 = pd.concat([type1_2, type2_2])
    print("%Pokémon de type s: %d animaux" % (type2, len(type_2)))

    def type_to_num(p_type):
        if p_type == type1:
            return 0
        else:
            return 1

    poke_concat = pd.concat([type_1, type_2], ignore_index=True)
    type1_c = poke_concat["Type 1"].apply(type_to_num)
    type2_c = poke_concat["Type 2"].apply(type_to_num)
    poke_concat["type_num"] = type1_c*type2_c
    poke_concat.head()

    X = poke_concat.iloc[:, 7:13].values
    y = poke_concat["type_num"].values

    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.3, random_state=0)
    lr = LogisticRegression(C=1.0)
    lr.fit(X_train, y_train)

    i = 0
    error1 = 0
    success1 = 0
    error2 = 0
    success2 = 0
    print("")
    print("[%Liste des Pokémon jugés de type S]" % type1)
    print("----------------------------------------")
    print("")
    while i < len(poke_concat):
        y_pred = lr.predict(X[i].reshape(1, -1))
        if y_pred == 0:
            print(poke_concat.loc[i, ["Nom du Pokémon"]])
            if poke_concat.loc[i, ["type_num"]].values == 0:
                success1 += 1
                print("%type de s" % type1)
                print("")
            else:
                error1 += 1
                print("%Pas de type" % type1)
                print("")
        else:
            if poke_concat.loc[i, ["type_num"]].values == 0:
                error2 += 1
            else:
                success2 += 1
        i += 1
    print("----------------------------------------")
    print("Correctement%Nombre de Pokémon jugés de type s: %d animaux" % (type1, success1))
    print("Correctement%Nombre de Pokémon jugés de type s: %d animaux" % (type2, success2))
    print("Accidentellement%Nombre de Pokémon jugés de type s: %d animaux" % (type1, error1))
    print("Accidentellement%Nombre de Pokémon jugés de type s: %d animaux" % (type2, error2))
    print("")


# %%
poke_predict("Hagane", "Ordinaire")

Résultat de l’exécution Pokémon de type Hagane: 58 Pokémon de type normal: 116

Nombre de Pokémon jugés être le type de splash correct: 50 Nombre de Pokémon correctement jugés de type normal: 115 Nombre de Pokémon qui ont été identifiés par erreur comme un type de splash: 1 Nombre de Pokémon identifiés par erreur comme de type normal: 8

Bien qu'il y ait une différence dans le nombre d'échantillons, la précision de 94,8% peut être considérée comme assez bonne. De ce résultat, on peut dire que les caractéristiques de la valeur de race sont différentes entre le type normal et le type d'épée.

À la fin

Je suis un débutant moins d'une semaine après avoir commencé à apprendre le machine learning, mais je pense que j'ai pu réfléchir profondément. Si vous avez des idées fausses dans cet article, je vous serais reconnaissant de bien vouloir les signaler.

Recommended Posts

L'apprentissage automatique appris avec Pokemon
Apprentissage automatique à partir de zéro (apprentissage automatique appris avec Kaggle)
Apprentissage automatique avec Python! Préparation
Démineur d'apprentissage automatique avec PyTorch
Commencer avec l'apprentissage automatique Python
Pokemon Machine Learning Nth décoction
Essayez le machine learning à la légère avec Kaggle
Générez des Pokémon avec Deep Learning
Apprentissage automatique
[Python] Programmation orientée objet apprise avec Pokemon
J'ai essayé l'apprentissage automatique avec liblinear
Apprentissage automatique par python (1) Classification générale
Expérience d'apprentissage Perceptron apprise avec Python
SVM essayant l'apprentissage automatique avec scikit-learn
Machine learning d'inspiration quantique avec des réseaux de tenseurs
Démarrez avec l'apprentissage automatique avec SageMaker
Mémo d'apprentissage "Scraping & Machine Learning avec Python"
Prédire la demande de puissance avec l'apprentissage automatique, partie 2
Amplifiez les images pour l'apprentissage automatique avec Python
Sklearn de données déséquilibrées avec apprentissage automatique k-NN
Apprentissage automatique avec python (2) Analyse de régression simple
Une histoire sur l'apprentissage automatique avec Kyasuket
[Shakyo] Rencontre avec Python pour l'apprentissage automatique
Apprentissage automatique avec Pytorch sur Google Colab
[Memo] Apprentissage automatique
Classification de l'apprentissage automatique
Construction d'environnement AI / Machine Learning avec Python
Exemple d'apprentissage automatique
Code source pour la séparation des sources sonores (série de pratiques d'apprentissage automatique) appris avec Python
[Python] Introduction facile à l'apprentissage automatique avec python (SVM)
Apprentissage automatique à partir de Python Personal Memorandum Part2
Apprentissage automatique à partir de Python Personal Memorandum Part1
[Python] Collectez des images avec Icrawler pour l'apprentissage automatique [1000 feuilles]
Vue d'ensemble des techniques d'apprentissage automatique apprises grâce à scikit-learn
J'ai commencé l'apprentissage automatique avec le prétraitement des données Python
Créer un environnement d'apprentissage automatique Python avec des conteneurs
Résumé du didacticiel d'apprentissage automatique
Apprendre Python avec ChemTHEATER 03
"Orienté objet" appris avec python
Apprentissage automatique sur le surapprentissage
Apprendre Python avec ChemTHEATER 05-1
Apprentissage automatique ⑤ Résumé AdaBoost
Apprentissage automatique: supervisé - AdaBoost
Régression logistique d'apprentissage automatique
Machine de vecteur de support d'apprentissage automatique
Étudier l'apprentissage automatique ~ matplotlib ~
Apprendre Python avec ChemTHEATER 02
Régression linéaire d'apprentissage automatique
Mémo du cours d'apprentissage automatique
Bibliothèque d'apprentissage automatique dlib
Apprendre Python avec ChemTHEATER 01
Apprentissage automatique (TensorFlow) + Lotto 6
Apprenez en quelque sorte le machine learning
Bibliothèque d'apprentissage automatique Shogun
Défi de lapin d'apprentissage automatique
Introduction à l'apprentissage automatique
Apprentissage automatique: k-voisins les plus proches
Qu'est-ce que l'apprentissage automatique?
Ce que j'ai appris sur l'IA / l'apprentissage automatique avec Python (1)