Teaching - RFIDEC


RFIDEC

Examen de milieu de semestre:

Voir la page de C. Gonzales:

http://webia.lip6.fr/~gonzales/teaching/rfidec/index.php

Examen de fin de semestre:

  • Droit aux notes de cours et aux slides
  • Le programme commence aux cours de P. Gallinari.
  • Les slides sont sur la page de P. Gallinari ainsi que l'exam corrigé de l'an dernier.

http://www-connex.lip6.fr/~gallinar/Enseignement/Enseignement.html

Retour vers le tutoriel complet

Ressources

dataset.py fonctions pour générer/afficher des jeux de données jouet.

frontiere.py fonctions pour tracer une frontière de décision sur des exemples jouet 2D

tutoFront.py Explication sur un exemple simple du fonctionnement des deux méthodes précédentes.

Tracés en 3D, isocontour et fonctionnalités avancées

Soit une fonction de deux variables f(w_1,w_2). Si on cherche à apprendre f qui approxime des étiquettes y \in \{-1,1\}, on va s'intéresser de près à la frontière de décision: dans quelle partie de l'espace décide-t-on 1 et dans quelle partie décide-t-on -1...

Exemple de tracé:


Figure 1 Frontière de décision au sens des moindres carrés entre 2 classes gaussiennes.

Obtenir une telle courbe n'est pas trivial, voici la liste des étapes à suivre:

  1. créer une grille de points pour mailler l'ensemble de l'espace
  2. évaluer votre modèle sur tous les points de la grille
  3. en déduire où se trouve la frontière de décision

0. Soit un problème de classification binaire

Code du tutoriel joint;

from frontiere import *
from dataset import *
from ml import *
import matplotlib.pyplot as pl

x,y,xtest,ytest = dataset("gaussian", 100, 100, 0.3) # génération des données

pl.figure(1)
plotset(x,y,1) # affichage des données

Figure 2 Problème de classification 2D à deux classes.

1. Générer une grille de points maillant tout l'espace à décrire

La fonction mesh effectue cette opération pour vous: vous donnez x et (optionnellement) la densité du maillage en argument. Cette fonction permet de générer un maillage couvrant l'ensemble de l'espace de la figure 2:


Figure 3 maillage de l'espace.

Code associé:

 # construction d'une grille réguliere de point sur l'espace 2D
 ngrid = 30               # finesse de la grille
 xgrid = mesh(x,ngrid)    # ou simplement xgrid = mesh(x)

 # affichage de la grille
 pl.figure(2)
 pl.plot(xgrid[:,0],xgrid[:,1],'+') # on voit que l'espace est entièrement couvert

3. Evaluer le modèle sur la grille

Sur les données étiquetées, un modèle est appris:

 # fonction de decision linéaire au sens du perceptron
 w = perceptron(x,y,0.1,1000)
 # OU fonction de décision au sens des moindres carrés
 w = np.linalg.solve((x.T.dot(x)), (x.T.dot(y)))

Le modèle (ici linéaire) est ensuite appliqué sur les points de la grille:

 # application du modele sur la grille
 ygrid = xgrid.dot(w);

Puis affiché (ATTENTION, il faut afficher un nuage de point en 3D)

import matplotlib.pyplot as pl
from mpl_toolkits.mplot3d import Axes3D

fig = pl.figure(3)
ax = fig.gca(projection='3d')    # déclarer la 3D
ax.scatter(xgrid[:,0],xgrid[:,1], ygrid) # fonction d'affichage d'un nuage de point

Figure 4 Evaluation du modèle sur les points de la grille.

La figure est en 3D: 2 dimensions xgrid_1 et xgrid_2 pour les données et une dimension z=\hat y pour l'évaluation du modèle.

4. Affichage(s) avancé(s)

Une fois dans cette configuration, plusieurs affichages sont possibles.

  1. soit on reste en 3D et on trace la fonction de décision (c'est à dire le score pour chaque point de l'espace)
  2. soit on passe en 2D et on trace la frontière de décision (moins clinquant mais souvent plus parlant)

Solution 1:


Figure 5 Evaluation du modèle sur les points de la grille, affichage sous forme de surface + rappel des points d'apprentissage.
import matplotlib.pyplot as pl
from mpl_toolkits.mplot3d import Axes3D


n = np.sqrt(xgrid.shape[0])
xgrid1 = xgrid[:,0:1].reshape((n,n)); # Dim1: retour à une forme de grille
xgrid2 = xgrid[:,1:2].reshape((n,n)); # Dim2: retour à une forme de grille  
ygridS = ygrid.reshape((n,n));        # Eval: retour à une forme de grille  

fig = pl.figure(4)
ax = fig.gca(projection='3d')         # déclarer la 3D
ax.plot_surface(xgrid1,xgrid2, ygridS, rstride=1, cstride=1, cmap=cm.coolwarm,
                    linewidth=0, antialiased=False) # tracé de la fonction de décision
                                                    # seuls les 3 premiers args sont obligatoires
ax.scatter(x[np.where(y[:,0]==1),0],x[np.where(y[:,0]==1),1],0,s=10,c='r')   # pts classe 1
ax.scatter(x[np.where(y[:,0]==-1),0],x[np.where(y[:,0]==-1),1],0,s=10,c='b') # pts classe -1

Solution 2:

On s'intéresse seulement au moment où la surface croise le plan z=0 et on trace un isocontour d'équation f(w_1,w_2)=0


Figure 6 Evaluation du modèle sur les points de la grille, affichage de l'isocontour f(w_1,w_2)=0.

Code correspondant:

import matplotlib.pyplot as pl

n = np.sqrt(xgrid.shape[0])
xgrid1 = xgrid[:,0:1].reshape((n,n)); # Dim1: retour à une forme de grille
xgrid2 = xgrid[:,1:2].reshape((n,n)); # Dim2: retour à une forme de grille  
ygridS = ygrid.reshape((n,n));        # Eval: retour à une forme de grille  

fig = pl.figure(5)
indC1,buf = np.where(y==1)
indC2,buf = np.where(y==-1)
pl.plot(x[indC1,0], x[indC1,1], 'r+')
pl.plot(x[indC2,0], x[indC2,1], 'b+')
pl.contour(xgrid1,xgrid2,ygridS,[0])  # comme pour un tracé 3D mais on ajoute l'isocontour qui nous intéresse

(pas vraiment une) Application

On souhaite dans cet exercice tracer des courbes en 3D f(x,y) puis la dessiner dans la question.

On souhaite créer la fonction f(x,y) = x^2 + y^2, pour x \in [1,3] et y \in [-1,1]. Afin d'exploiter les vecteurs et matrices d'Octave, on discrétise cet espace en n'en sélectionnant que 5 valeurs par axe~:

 x = np.array([  1.0000    1.5000    2.0000    2.5000    3.0000 ]) # définir l'axe des x
 y = np.array([ -1.00000  -0.50000   0.00000   0.50000   1.00000]) # définir l'axe des y

 xgrid, ygrid = np.meshgrid(x, y) # création des combinaisons

Résultat :

 xgrid =                                         ygrid =
   1.0000   1.5000   2.0000   2.5000   3.0000     -1.00000  -1.00000  -1.00000  -1.00000  -1.00000
   1.0000   1.5000   2.0000   2.5000   3.0000     -0.50000  -0.50000  -0.50000  -0.50000  -0.50000
   1.0000   1.5000   2.0000   2.5000   3.0000      0.00000   0.00000   0.00000   0.00000   0.00000
   1.0000   1.5000   2.0000   2.5000   3.0000      0.50000   0.50000   0.50000   0.50000   0.50000
   1.0000   1.5000   2.0000   2.5000   3.0000      1.00000   1.00000   1.00000   1.00000   1.00000

Création de la fonction f:

 f = xgrid * xgrid + ygrid * ygrid

Pour pouvoir tracer f en 3D, la variable f doit avoir les mêmes dimensions que xgrid et ygrid.

import matplotlib.pyplot as pl
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

fig = pl.figure(1)
ax = fig.gca(projection='3d')
ax.plot_surface(xgrid1,xgrid2, ygridS)
# ou pour faire plus joli
# ax.plot_surface(xgrid, ygrid, f, rstride=1, cstride=1, cmap=cm.coolwarm,
#                    linewidth=0, antialiased=False)

fig = pl.figure(2)

pl.contour(xgrid, ygrid, f) # affiche les courbes de niveau de f