modifications des tp, exercices, ajouts d'indications en JS, d'exemples en gloutons, 3 semaines de boulot enfin voilà
This commit is contained in:
@@ -1,38 +1,128 @@
|
||||
# Imports regroupés en haut du fichier (PEP 8)
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
# Chargement des données
|
||||
pokemons = pd.read_csv('pokemons.csv')
|
||||
|
||||
# Afficher les premières lignes pour vérification
|
||||
print("=== Aperçu des données ===")
|
||||
print(pokemons.head())
|
||||
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Filtrons les données pour n'avoir que les Pokémon de type Eau
|
||||
eau_pokemons = pokemons.dropna(subset=['Pokemons de type Eau'])
|
||||
|
||||
# Création du graphe
|
||||
plt.scatter(eau_pokemons['points de vie'], eau_pokemons['Pokemons de type Eau'])
|
||||
plt.title('Points de vie vs Attribut Eau des Pokémon')
|
||||
plt.xlabel('Points de vie')
|
||||
plt.ylabel('Attribut Eau')
|
||||
plt.show()
|
||||
# Restructuration des données pour avoir une colonne "type" explicite
|
||||
def restructurer_donnees(df):
|
||||
"""
|
||||
Transforme le DataFrame pour avoir des colonnes : nom, points_de_vie, attaque, type
|
||||
"""
|
||||
donnees = []
|
||||
for _, row in df.iterrows():
|
||||
if pd.notna(row['Pokemons de type Eau']):
|
||||
donnees.append({
|
||||
'nom': row['nom'],
|
||||
'points_de_vie': row['points de vie'],
|
||||
'attaque': row['Pokemons de type Eau'],
|
||||
'type': 'Eau'
|
||||
})
|
||||
elif pd.notna(row['Pokemons de type Psy']):
|
||||
donnees.append({
|
||||
'nom': row['nom'],
|
||||
'points_de_vie': row['points de vie'],
|
||||
'attaque': row['Pokemons de type Psy'],
|
||||
'type': 'Psy'
|
||||
})
|
||||
return pd.DataFrame(donnees)
|
||||
|
||||
|
||||
import numpy as np
|
||||
pokemons_clean = restructurer_donnees(pokemons)
|
||||
print("\n=== Données restructurées ===")
|
||||
print(pokemons_clean.head(10))
|
||||
|
||||
# Ajoutons un Pokémon "mystère"
|
||||
pokemon_mystere = [70, 65]
|
||||
|
||||
# Visualisation des données
|
||||
def afficher_graphique(df, pokemon_mystere=None):
|
||||
"""
|
||||
Affiche un nuage de points des Pokémon par type
|
||||
"""
|
||||
plt.figure(figsize=(10, 6))
|
||||
|
||||
# Pokémon de type Eau
|
||||
eau = df[df['type'] == 'Eau']
|
||||
plt.scatter(eau['points_de_vie'], eau['attaque'], color='blue', label='Type Eau', s=100)
|
||||
|
||||
# Pokémon de type Psy
|
||||
psy = df[df['type'] == 'Psy']
|
||||
plt.scatter(psy['points_de_vie'], psy['attaque'], color='purple', label='Type Psy', s=100)
|
||||
|
||||
# Pokémon mystère si fourni
|
||||
if pokemon_mystere:
|
||||
plt.scatter(pokemon_mystere[0], pokemon_mystere[1], color='red', marker='X', s=200, label='Mystère')
|
||||
|
||||
plt.title('Classification des Pokémon par type')
|
||||
plt.xlabel('Points de vie')
|
||||
plt.ylabel('Attaque')
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
|
||||
# Fonction de calcul de distance euclidienne
|
||||
def calculer_distance(pokemon1, pokemon2):
|
||||
"""
|
||||
Calcule la distance euclidienne entre deux Pokémon
|
||||
pokemon1 et pokemon2 sont des listes [points_de_vie, attaque]
|
||||
"""
|
||||
return np.sqrt(np.sum(np.square(np.array(pokemon1) - np.array(pokemon2))))
|
||||
|
||||
# Calculons la distance de chaque Pokémon de type Eau au Pokémon "mystère"
|
||||
distances = eau_pokemons.apply(lambda row: calculer_distance([row['points de vie'], row['Pokemons de type Eau']], pokemon_mystere), axis=1)
|
||||
|
||||
# Ajoutons ces distances au DataFrame
|
||||
eau_pokemons['Distance au mystère'] = distances
|
||||
# Algorithme KNN complet
|
||||
def knn(df, pokemon_mystere, k=5):
|
||||
"""
|
||||
Algorithme des k plus proches voisins
|
||||
|
||||
# Affichons les Pokémon triés par leur distance au mystère
|
||||
print(eau_pokemons.sort_values(by='Distance au mystère').head())
|
||||
Paramètres:
|
||||
df : DataFrame contenant les Pokémon avec colonnes points_de_vie, attaque, type
|
||||
pokemon_mystere : liste [points_de_vie, attaque] du Pokémon à classifier
|
||||
k : nombre de voisins à considérer
|
||||
|
||||
Retourne:
|
||||
Le type prédit pour le Pokémon mystère
|
||||
"""
|
||||
# Calcul des distances pour chaque Pokémon
|
||||
df_copy = df.copy()
|
||||
df_copy['distance'] = df_copy.apply(
|
||||
lambda row: calculer_distance([row['points_de_vie'], row['attaque']], pokemon_mystere),
|
||||
axis=1
|
||||
)
|
||||
|
||||
# Tri par distance croissante et sélection des k premiers
|
||||
k_voisins = df_copy.sort_values(by='distance').head(k)
|
||||
|
||||
print(f"\n=== Les {k} plus proches voisins ===")
|
||||
print(k_voisins[['nom', 'type', 'distance']])
|
||||
|
||||
# Vote majoritaire
|
||||
type_majoritaire = k_voisins['type'].value_counts().idxmax()
|
||||
votes = k_voisins['type'].value_counts()
|
||||
|
||||
print(f"\n=== Votes ===")
|
||||
print(votes)
|
||||
|
||||
return type_majoritaire
|
||||
|
||||
|
||||
# Exemple d'utilisation
|
||||
if __name__ == "__main__":
|
||||
# Définir un Pokémon mystère (points_de_vie, attaque)
|
||||
pokemon_mystere = [65, 40]
|
||||
|
||||
# Afficher le graphique avec le Pokémon mystère
|
||||
afficher_graphique(pokemons_clean, pokemon_mystere)
|
||||
|
||||
# Appliquer l'algorithme KNN avec k=5
|
||||
type_predit = knn(pokemons_clean, pokemon_mystere, k=5)
|
||||
|
||||
print(f"\n=== Résultat ===")
|
||||
print(f"Le Pokémon mystère ({pokemon_mystere[0]} PV, {pokemon_mystere[1]} attaque) est probablement de type : {type_predit}")
|
||||
|
||||
Reference in New Issue
Block a user