Je travaille actuellement sur le projet TTC au sein de mon équipe. Je suis chargé de développer un classifieur de pages Web selon leurs intentions de communication. S'il existe bon nombre de travaux sur la classification des documents Web, dans notre cas nous cherchons une approche indépendante de la langue. Nous travaillons en effet sur sept langues différentes plus ou moins éloignées (français, anglais, allemand, espagnol, letton, russe et chinois). Voilà le contexte et le problème posé.

J'explore un certain nombre de traits qui pourraient s'avérer pertinent pour ladite tâche (URL, structure HTML, n-grammes caractères...). Il est cependant compliqué d'évaluer qualitativement si les traits retenus permettent de différencier les "intentions de communication" auxquelles nous nous intéressons. Une manière très subjective, mais également très efficace, de mesurer cette capacité est de visualiser les clusters formés par les documents dans l'espace vectoriel défini par nos traits. Chaque document est représenté par un vecteur des valeurs correspondant aux différents traits sélectionnés. Ces traits sont cependant très nombreux et l'espace vectoriel correspondant ne peut pas être directement représenté sous forme graphique.

Afin d'aisément visualiser les documents dans ces espaces vectoriels j'effectue une projection sur seulement trois dimensions et je visualise le résultat sous forme d'un graphique de type "nuage de points". Les trois combinaisons sont en réalité des combinaisons algébriques de l'ensemble des dimensions de mon espace vectoriel obtenues par une approche en composantes principales.

Il est assez aisé de mettre en œuvre une telle approche avec scikit-learn :

# Importation de l'approche par composantes principales
from scikits.learn.pca import PCA
 
# On utilise un ensemble de données exemple classique : Iris
from scikits.learn import datasets
iris = datasets.load_iris()
 
# Préparation de la méthode PCA pour une projection sur 3 dimensions
pca = PCA(n_components=3)
# Calcul de la projection à partir des données exemples
pca.fit(iris.data)
# Application de la projection aux données
newdata = pca.transform(iris.data)

La variable newdata contient alors une projection de nos données sur le nouvel espace vectoriel en 3 dimensions. Je peux ainsi visualiser les documents dans ce nouvel espace en utilisant Pylab issue de matplotlib :

# Utilisation de Pylab et de mplot3d intégré à matplotlib
import pylab as pl
import mpl_toolkits.mplot3d.axes3d as p3
 
# Création de la figure dans laquelle nous allons représenté notre nuage de points
# qui sera composée de 3 dimensions (Axes3D)
fig=pl.figure()
ax = p3.Axes3D(fig)
# Les données Iris se répartissent entre 3 classes (0, 1 et 2), nous allons coloré chacune de
# ces classes différemment afin de les visualiser
# Nous utilisons également le nom réel (iris.target_names) des classes dans la légende
for color, classe, nom_classe in zip("rgb", [0, 1, 2], iris.target_names):
	# newdata[iris.target==classe,0] permet de récupérer la première colonne (0) de la 
	# sous-matrice correspondant aux instances de la classe "classe"
	ax.scatter3D(newdata[iris.target==classe,0], 
	  newdata[iris.target==classe,1], newdata[iris.target==classe,2], 
	  c=color, label=nom_classe)
# On ajoute les données à la figure et on dessine le tout
fig.add_axes(ax)
pl.show()

Et voici le résultat :

Projection 3D des instances de la base iris

La projection en 3D permet très facilement (et très subjectivement) d'identifier les trois clusters correspondant aux trois classes et d'ainsi valider les traits retenus pour représenter les instances.