Thématiques principales

vendredi 12 avril 2019

IA : Régression non linéaire avec scikit-learn

Dans les derniers articles nous avons vu l’astuce du noyau. Maintenant, nous allons le mettre en pratique avec un problème de régression non linéaire avec l’outil scikit learn [1].

Nous allons faire comme dans la problématique linéaire [2] , nous allons produire des données non linéaire parfaites que nous allons bruiter. Ensuite nous tâcherons d’extraire un modèles pour ces deux jeux de données et nous visualisons graphiquement comment celui ci se comporte.
Les données

Ainsi commençons par construire des données. D’un côté on va se donner un plage de données avec un pas important (ça limitera la quantité de données lors de l’apprentissage). Ensuite sur la base de ce résultat, on va générer une valeur aléatoire que l’on ajoutera où on retranchera à nos précédents résultats:


print(__doc__)
import numpy as np
from sklearn.svm import SVR
import matplotlib.pyplot as plt
import math

A=0.02
B=-12
C=51
D=2*math.pow(10,8)


X=np.arange(-1000,1000,35)
SIZE=np.size(X)
print(SIZE)
Y=(A*X**3+B*X**2+C*X+D)*0.00000001
Bruit=Y + np.random.randint(0,15, size=(1,SIZE))[0]*0.005*(np.random.rand(1,SIZE)-0.5)[0]


fig = plt.figure(1,figsize=(8,8))
plt.plot(X,Y,"bo")# model lineaire
plt.plot(X,Bruit,"r.")# model lineaire bruité
plt.show()

Si l’on visualise ces données, on obtient le graphe suivant (au passage on calcule l'écart moyen au carré du résultat de la prédiction avec la vraie données initiale):


Modèles

Ensuite on construit un modèle polynomial basé sur un degré 3 (ok on triche un peu on sait que nos données sont de degré 3), au passage on se construira un modèle linéaire histoire de comparer un peu.


svr_lin = SVR(kernel='linear', C=100, gamma='scale')
svr_poly = SVR(kernel='poly', C=100, gamma='scale', degree=3, epsilon=.001, coef0=2)
X_=X.reshape(-1, 1)

On va alors d’abord vérifier sur nos données non bruités ce que nos modèles sont capable de faire:


svrs = [svr_lin,svr_poly]
model_color = ['c', 'g']

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(16, 8), sharey=True)
for index, svr in enumerate(svrs):
    PREDICT=svr.fit(X_, Y).predict(X_)
    axes[index].plot(X_, PREDICT, color=model_color[index], lw=2)
    # on affiche les points supports du SVM
    axes[index].scatter(X_[svr.support_], Y[svr.support_], facecolor="none",edgecolor=model_color[index])
    # les autres points qui ne sont pas les supports (d'ou le diff)
    axes[index].scatter(X_[np.setdiff1d(np.arange(len(X)), svr.support_)],Y[np.setdiff1d(np.arange(len(X)),
        svr.support_)],facecolor="none", edgecolor="k")
    print("eccart carré moyen : {}".format(np.square(Y-PREDICT).mean()))

plt.show()

On obtient un eccart carré moyen : 6.847129083752741e-07



On voit donc que nos données sont correctement décrits mais en soit c’est normal! Mais essayons sur les données bruitées?



svrs = [ svr_lin,svr_poly]
model_color = ['c', 'g']

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(16,8), sharey=True)
for index, svr in enumerate(svrs):
    PREDICT=svr.fit(X_, Bruit).predict(X_)
    axes[index].plot(X_, PREDICT, color=model_color[index], lw=2)
    # on affiche les points supports du SVM
    axes[index].scatter(X_[svr.support_], Bruit[svr.support_], facecolor="none",edgecolor=model_color[index])
    # les autres points qui ne sont pas les supports (d'ou le diff)
    axes[index].scatter(X_[np.setdiff1d(np.arange(len(X)), svr.support_)],Bruit[np.setdiff1d(np.arange(len(X)),
        svr.support_)],facecolor="none", edgecolor="k")
    print("eccart carré moyen : {}".format(np.square(Y-PREDICT).mean()))


plt.show()

On obtient eccart carré moyen : 3.2041407166403025e-06

Donc la on voit que malgré le bruit, on obtient une prédiction qui colle à ce qu'étaient nos données non bruité!

Sur-modèle

Alors on pourrait se dire que si l’on cherche à augmenter le degré on pourrait peut être espérer augmenter la qualité de notre modèle… sauf que ….


svrs = [ svr_lin,svr_poly]
model_color = ['c', 'g']

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(16,8), sharey=True)
for index, svr in enumerate(svrs):
    PREDICT=svr.fit(X_, Bruit).predict(X_)
    axes[index].plot(X_, PREDICT, color=model_color[index], lw=2)
    # on affiche les points supports du SVM
    axes[index].scatter(X_[svr.support_], Bruit[svr.support_], facecolor="none",edgecolor=model_color[index])
    # les autres points qui ne sont pas les supports (d'ou le diff)
    axes[index].scatter(X_[np.setdiff1d(np.arange(len(X)), svr.support_)],Bruit[np.setdiff1d(np.arange(len(X)),
        svr.support_)],facecolor="none", edgecolor="k")
    print("eccart carré moyen : {}".format(np.square(Y-PREDICT).mean()))


plt.show()

On obtient eccart carré moyen : 0.002954915450864114


Ce que l’on constate ici est ce que l’on appelle de l’overfiting, c’est à dire un sur-apprentissage, cela arrive lorsque l’on pousse le modèle à vouloir trop coller au données. Au lieu d'être une bonne approximation de l’ensemble des données, le modèle devient  une surreprésentation de celles ci et sera incapable d’en prédire de nouvelles.

Conclusion

Pour conclure la-dessus je ferai surtout un point sur notre avancement dans l’IA. Ainsi on peut remarquer que la nous sommes sur la fin des régressions non linéaires (et les linéaires). Bien sur on ne dira pas que l’on en a fait le tour car il serait encore possible de traiter aussi des algo de type lasso, ridge, ou même elastic-net cependant dans le principe, ces approches restent proches de ce que l’on pu voir jusque maintenant (de plus la littérature sur ces modèles de régression est plus que riche et vous laisserai donc chercher).

De même nous avons vu des classifications binaires mais aussi des classifications multi-étiquettes (souvenez vous du dataset iris) et nous avons la aussi fait un peu le tour! Nous nous attacherons quand même à conclure sur une problématique classique du domaine qu’est Mnist car ce problème est tellement un classique qu’il ne serait pas normal de ne pas en parler.

Mais du coup ça y est on a fini avec l’IA? bien sur que non… il reste encore plein de sujet!

Rassurez vous!! c’est loin d'être fini! Sans vouloir trop entrer dans ces sujets ou spoiler, le machine learning compte encore d’autres approches comme les arbres de décisions ou les forêts aléatoire et bien sur, après cela, les réseaux de neurones (ça y est on y arrive!!).

Cependant, il faudra un peu de patience… car d’autres sujets surprises vont s’intercaler entre tout ça…. enfin vous verrez!

Références

Aucun commentaire:

Enregistrer un commentaire