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é
--CPU: Processeur Intel Core i5 Quad Core 1,4 GHz de 8e génération
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.
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("")
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).
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))
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")
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.
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