blobs
de Résumé: Les méthodes de discrimination sont comparées sur un jeu de données fictif obtenu par la commande make_blobs
de Scikit-learn. L'objectif est de mettre en évidence le rôle des paramètres de complexité de différentes méthodes (régression logistique, k-nn, réseaux de neurones, arbre de décision, bagging, svm) et de comparer les formes spécifiques des frontières estimées par chacune d'elle. Cela permet d'illustrer les principales méthodes d'apprentissage de Scikit-learn
Les données se présentent sous la forme de nuages de points dans R2 plus présentant des groupes plu sou moins distincts ou mélangés. L'objectif est d'apprendre ces données très particulières afin de discriminer les deux classes. Les données étant simplement dans R2, il est facile de prévoir la classe de chaque point du plan et ainsi de visualiser la frontière entre les prévisions des deux classes. L'intérêt est de représenter ainsi facilement le rôle jouer par les paramètres de complexité de chaque méthode et de comparer les formes des frontières obtenues et donc la plus ou moins bonne adéquation d'une méthode à la spécificité de ces données simulées.
In [ ]:
%matplotlib inline
from matplotlib import pyplot as plt
# option d'impression
import numpy as np
np.set_printoptions(precision=3)
In [ ]:
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=1000, centers=20, random_state=123)
labels = ["b", "r"]
y = np.take(labels, (y < 10))
print(X)
print(y[:5])
Représentation des données dans le plan.
In [ ]:
plt.figure()
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.xlim(-10, 10)
plt.ylim(-10, 10)
plt.show()
Tous les algorithmes et méthodes de Scikit-learn se présentent sous la forme d'une combinaison de 3 "interfaces":
Celles-ci peuvent être facilement combinées et enchaînées en un pipeline.
In [ ]:
# Importation de la fonction
from sklearn.neighbors import KNeighborsClassifier
# Détermination des paramètres et définition de l'estimateur
knnF = KNeighborsClassifier(n_neighbors=5)
# Apprentissage ou estimation du modèle sur l'échantillon d'apprentissage
# mais il ne se passe rien dans le cas de *k*-nn avant en dehors de la phase de prévision.
knnF.fit(X, y)
# Les options de cet algorithmes:
In [ ]:
print(knnF.predict(X[:5]))
Ou de la probabilité des classes.
In [ ]:
print(knnF.predict_proba(X[:5]))
La fonction définie ci-dessous prévoit chaque point d'une grille du plan et trace un graphe de contour des probabilités.
In [ ]:
def plot_surface(clf, X, y, xlim=(-10, 10), ylim=(-10, 10), n_steps=250):
fig = plt.figure()
xx, yy = np.meshgrid(np.linspace(xlim[0], xlim[1], n_steps), np.linspace(ylim[0], ylim[1], n_steps))
if hasattr(clf, "decision_function"):
z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
else:
z = clf.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 1]
z = z.reshape(xx.shape)
plt.contourf(xx, yy, z, alpha=0.8, cmap=plt.cm.RdBu_r)
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.xlim(*xlim)
plt.ylim(*ylim)
plt.show()
In [ ]:
knnF = KNeighborsClassifier(n_neighbors=70)
knnF.fit(X, y)
plot_surface(knnF, X, y)
Ce qui donne une bonne idée de la forme des frontières estimées entre les classes.
Faire varier le paramère n_neighbors
(1 à 500) et observer l'impact sur la forme des classes.
Les frontières sont construites à partir de parallèles aux axes. Faire varier la profondeur maximale max_depth
de l'arbre.
In [ ]:
from sklearn.tree import DecisionTreeClassifier
treeF = DecisionTreeClassifier(max_depth=10)
treeF.fit(X, y)
plot_surface(treeF, X, y)
Obtenues par agrégation d'arbres, une forêt arrondit les frontières. Avec seulement 2 variables (dans R2), cela revient à faire du bagging. Faire variaer le nombre d'arbres: n_estimators
(1 à 20), de la forêt.
In [ ]:
from sklearn.ensemble import RandomForestClassifier
rfF = RandomForestClassifier(n_estimators=200)
rfF.fit(X, y)
plot_surface(rfF, X, y)
SVM linéaire, pas très intéressant sur ces données, puis gaussien. Faire varier la pénalisation C
et l'étendue du noyau gaussien.
In [ ]:
# Noyau linéaire
from sklearn.svm import SVC
svmF = SVC(kernel="linear",C=1) # try kernel="rbf" instead
svmF.fit(X, y)
plot_surface(svmF, X, y)
Faire varier C de 10-5 à 10^5, gamma de 0.001 à 100
In [ ]:
# Noyau gaussien avec valeurs par défaut de C et gamma
from sklearn.svm import SVC
svmF = SVC(kernel="rbf", C=1, gamma='auto')
svmF.fit(X, y)
plot_surface(svmF, X, y)
Faire varier le nombre de couches cachées, le nombe de neurones sur ces couches, la pénalisation l2 alpha
.
In [ ]:
# Trois couches de 100 neurones avec alpha par défaut
from sklearn.neural_network import MLPClassifier
nnetF = MLPClassifier(hidden_layer_sizes=(100, 100, 100),alpha=0.0001)
nnetF.fit(X, y)
plot_surface(nnetF, X, y)
Consulter la doc en ligne.
In [ ]:
from sklearn.gaussian_process import GaussianProcessClassifier
pgF = GaussianProcessClassifier()
pgF.fit(X, y)
plot_surface(pgF, X, y)