On va faire un peu d'analyse de données, avec ou sans numpy et ses matrices.
Au passage, on va voir comment faire un peu de visualisation en Python, en utilisant le module matplotlib (librairie en plus, mais disponible avec tous les outils scientifiques)
La commande essentielle, plot, prend deux listes de coordonnées (abscisses et ordonnées), et trace la courbe correspondante reliant les points. Spyder gère automatiquement l'affichage dans sa console IPython.
import matplotlib
matplotlib.use("TkAgg",warn=False, force=True)
from IPython.display import Image
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot([1,2,3,4,5],[1,4,9,16,25])
print "Parabole:"
En option, on peut définir une couleur et une forme avec une chaine en 3e argument ("r" pour red, "o" pour un point)
plt.plot([1,2,3,4,5],[1,4,9,16,25],"ro")
print "Parabole"
Pour contrôler un peu l'affichage, on peut fixer les extrémités des axes, et les forcer à être à la même échelle
plt.xlim(0,25)
plt.ylim(0,25)
plt.axes().set_aspect('equal')
plt.plot([1,2,3,4,5],[1,4,9,16,25],"ro")
print "Parabole encore"
Passons maintenant aux choses sérieuses. On va considérer que l'on a des données de deux types différents (appelons les "rouge" et "bleu"), caractérisées par deux valeurs entre 0 et 1. On pourrait alors avoir une visualisation comme ceci:
Le but de ce TP est de définir un moyen de "classer" une nouvelle donnée pour dire si elle est plutôt de la classe bleue ou rouge. Pour cela, un moyen simple (voire simplet, mais vous creuserez la question au 2e semestre), est de calculer le barycentre (centre de gravité) des points de chaque classe, ici en jaune:
Puis de considérer leur médiatrice:
En enfin de considérer que tout ce qui est du même côté que le groupe bleu/rouge doit être bleu/rouge:
Evidemment, ça ne marchera pas pour tout type de données:
Cette méthode nécessite que les données soit séparables linéairement. Mais passons. Votre tâche:
en utilisant la fonction random.random(), faire une fonction qui génère un "nuage" de n points autour d'une position donnée ($x_0$,$y_0$), avec un étalage réglable (distance maxi par rapport à la position donnée). Par exemple, les points de la figure initiale ont été générés avec deux appels avec les paramètres (vous être libre du nom de la fonction):
g1 = blob(0.3,0.6,20,scale=0.1)
g2 = blob(0.6,0.4,15,scale=0.15)
Une fonction qui détermine le centre d'un groupe
Vous pouvez maintenant utiliser le fichier "iris.txt", en annexe du sujet. Celui-ci contient des caractéristiques de différentes fleurs de l'espèce iris, réparties en trois sous-espèces "setosa", "virginica", "versicolor".
Vous pouvez utiliser numpy pour lire directement les données:
import numpy as np
data = np.genfromtxt('iris.txt', dtype=None,delimiter=',',names=True,encoding="utf8")
Si on regarde le résultat, on voit que cela donne une matrice de tuples, avec les caractéristiques et la classe de chaque instance. On a aussi une liste de noms des "colonnes" de ces données:
data[:4]
On peut alors récupérer les colonnes par leur nom:
data["classe"][:10]
data["sepal_l"][:10]
Rappel: on peut filtrer des éléments d'une matrice numpy avec des conditions booléennes, par exemple pour garder les instances d'une classe particulière:
setosa = data[data["classe"]=="Iris-setosa"]
print(setosa[:5])
A vous de jouer, pour:
Et voilà, vous avez fait votre premier programme qui apprend automatiquement ...