Comment créer un nuage de points PCA interactif en Python?

11

La bibliothèque matplotlib est très performante mais manque d'interactivité, en particulier à l'intérieur de Jupyter Notebook. Je voudrais une bonne ligne de traçage outil comme plot.ly .

scottlittle
la source
3
Je ne connais pas très bien de telles choses, donc je ne peux pas vraiment écrire une bonne réponse, mais vous pouvez jeter un œil à ipywidgets(exemples sur github.com/ipython/ipywidgets/blob/master/docs/source/examples /… ) Ou bokeh( bokeh.pydata.org/en/latest ).
Torbjørn T.

Réponses:

10

Il existe une bibliothèque impressionnante appelée MPLD3 qui génère des tracés interactifs D3.

Ce code produit un tracé HTML interactif de l'ensemble de données iris populaire compatible avec Jupyter Notebook. Lorsque le pinceau est sélectionné, il vous permet de sélectionner un sous-ensemble de données à mettre en surbrillance parmi tous les tracés. Lorsque la flèche croisée est sélectionnée, elle vous permet de survoler le point de données et de voir des informations sur les données d'origine. Cette fonctionnalité est très utile lorsque vous effectuez une analyse exploratoire des données.

import matplotlib.pyplot as plt
import numpy as np
importer des pandas en tant que pd
importer seaborn comme sb
importer mpld3
des plugins d'importation mpld3
% matplotlib inline

iris = sb.load_dataset ('iris')
à partir de sklearn.preprocessing import StandardScaler
X = pd.get_dummies (iris)
X_scal = StandardScaler (). Fit_transform (X)

dim = 3
à partir de sklearn.decomposition importation PCA
pca = PCA (n_components = dim)
Y_sklearn = pca.fit_transform (X_scal)

# Définissez du CSS pour contrôler nos étiquettes personnalisées
css = "" "
table
{
  border-collapse: effondrement;
}
e
{
  couleur: #ffffff;
  couleur de fond: # 000000;
}
td
{
  couleur de fond: #cccccc;
}
table, th, td
{
  famille de polices: Arial, Helvetica, sans-serif;
  bordure: 1px noir uni;
  alignement du texte: à droite;
}
"" "

fig, ax = plt.subplots (dim, dim, figsize = (6,6))
fig.subplots_adjust (hspace = .4, wspace = .4)
info-bulle = [Aucun] * dim

N = 200
index = np.random.choice (range (Y_sklearn.shape [0]), size = N)

pour m dans la plage (dim):
    pour n dans la plage (m + 1):
        ax [m, n] .grid (Vrai, alpha = 0,3)
        scatter = ax [m, n] .scatter (Y_sklearn [index, m], Y_sklearn [index, n], alpha = .05)

        labels = []
        pour i dans l'index:
            label = X.ix [[i],:]. T.astype (int)
            label.columns = ['Row {0}'. format (X.index [i])]
            labels.append (str (label.to_html ()))

        ax [m, n] .set_xlabel ('Composant' + str (m))
        ax [m, n] .set_ylabel ('Composant' + str (n))
        #ax [m, n] .set_title ('info-bulles HTML', taille = 20)

        info-bulle [m] = plugins.PointHTMLTooltip (scatter, labels,
                                           voffset = 20, hoffset = 20, css = css)
        plugins.connect (fig, info-bulle [m])

plugins.connect (fig, plugins.LinkedBrush (scatter))
test = mpld3.fig_to_html (fig = fig)

avec open ("Output.html", "w") comme fichier_texte:
    text_file.write (test)

Voyez-le en action sur mon blog .

Mise à jour [9 juillet 2016]: Je viens de découvrir que Plot.ly a un mode hors ligne et est maintenant open source. Il a beaucoup de cloches et de sifflets préemballés, mais MPLD3 peut toujours être approprié dans certains cas.

scottlittle
la source
3

Je préférerais que ce soit un commentaire plutôt qu'une réponse, car mon intention n'est pas de brancher / faire de la publicité, mais je travaille actuellement sur ma thèse qui peut vous intéresser car elle fait ce que vous voulez. En réalité, c'est un outil de visualisation en cluster, mais si vous utilisez k-means avec k = 1, vous avez un tracé interactif où vous pouvez rechercher des termes, sélectionner une zone et voir le contenu de chaque nœud, et d'autres choses. Jetez un oeil et voyez si cela fonctionne pour vous!

https://github.com/Lilykos/clusterix

Lilykos
la source
Cool! Je vais regarder.
scottlittle
0

Un très bon choix, complot est ...

Dans mon cas, j'essayais de tracer une désignation similaire basée sur les compétences, où les compétences étaient un mot2vec incorporant 300 dimensions; l'a amené à un espace vectoriel en 3 dimensions, et en utilisant Scatter3D, j'ai pu tracer un nuage de points 3D pour le même.

Et Viola !! Vous avez un impressionnant graphique en 3 dimensions, avec des fonctionnalités de survol et d'agrandissement. Et la meilleure partie est qu'il peut être exporté sous forme de fichier html, ce qui en fait un plug and play adapté à tout autre PC, il suffit de le glisser-déposer dans un navigateur (inclus dans le code ci-dessous).

Est-ce que quelque chose peut être plus simple

from plotly.offline import plot
from plotly.graph_objs import *
import numpy as np

# x = np.random.randn(2000)
# y = np.random.randn(2000)

# Instead of simply calling plot(...), store your plot as a variable and pass it to displayHTML().
# Make sure to specify output_type='div' as a keyword argument.
# (Note that if you call displayHTML() multiple times in the same cell, only the last will take effect.)

p = plot(
  [
    Scatter3d(x=skills_df[0], y=skills_df[1], z=skills_df[2], text= skills_df['designation'], mode='markers', marker=Marker(color=skills_df['cluster_number'], size=3, opacity=0.5, colorscale='Viridis'))
  ],
  output_type='div'
#   filename='/dbfs/FileStore/tables/lnkdn_jobroles_viridis.html' turn it on to save the file
)
Itachi
la source