¿Cómo hago un diagrama de dispersión de PCA interactivo en Python?


11

La biblioteca matplotlib es muy capaz pero carece de interactividad, especialmente dentro de Jupyter Notebook. Me gustaría una buena herramienta como fuera de línea trazado plot.ly .


3
No estoy muy versado en tales cosas, así que realmente no puedo escribir una buena respuesta, pero puedes echar un vistazo a ipywidgets(ejemplos en github.com/ipython/ipywidgets/blob/master/docs/source/examples / ... ) o bokeh( bokeh.pydata.org/en/latest ).
Torbjørn T.

Respuestas:


10

Hay una biblioteca impresionante llamada MPLD3 que genera diagramas interactivos D3.

Este código produce una trama interactiva HTML del popular conjunto de datos de iris que es compatible con Jupyter Notebook. Cuando se selecciona el pincel, le permite seleccionar un subconjunto de datos para resaltar entre todos los gráficos. Cuando se selecciona la flecha cruzada, le permite pasar el mouse sobre el punto de datos y ver información sobre los datos originales. Esta funcionalidad es muy útil al hacer análisis de datos exploratorios.

importar matplotlib.pyplot como plt
importar numpy como np
importar pandas como pd
import seaborn como sb
importar mpld3
desde plugins de importación mpld3
% matplotlib en línea

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

tenue = 3
de sklearn.decomposition import PCA
pca = PCA (n_components = dim)
Y_sklearn = pca.fit_transform (X_scal)

# Define un poco de CSS para controlar nuestras etiquetas personalizadas
css = "" "
mesa
{
  colapso del borde: colapso;
}
th
{
  color: #ffffff;
  color de fondo: # 000000;
}
td
{
  color de fondo: #cccccc;
}
tabla, th, td
{
  Familia tipográfica: Arial, Helvetica, sans-serif;
  borde: 1px negro sólido;
  alineación de texto: derecha;
}
"" "

fig, ax = plt.subplots (dim, dim, figsize = (6,6))
fig.subplots_adjust (hspace = .4, wspace = .4)
información sobre herramientas = [Ninguno] * tenue

N = 200
index = np.random.choice (rango (Y_sklearn.shape [0]), tamaño = N)

para m en rango (tenue):
    para n en rango (m + 1):
        ax [m, n] .grid (Verdadero, alfa = 0.3)
        dispersión = ax [m, n]. dispersión (Y_sklearn [índice, m], Y_sklearn [índice, n], alfa = .05)

        etiquetas = []
        para i en el índice:
            etiqueta = X.ix [[i],:]. T.astype (int)
            label.columns = ['Fila {0}'. formato (X.index [i])]
            labels.append (str (label.to_html ()))

        ax [m, n] .set_xlabel ('Componente' + str (m))
        ax [m, n] .set_ylabel ('Componente' + str (n))
        #ax [m, n] .set_title ('Información sobre herramientas HTML', tamaño = 20)

        información sobre herramientas [m] = plugins.PointHTMLTooltip (dispersión, etiquetas,
                                           voffset = 20, hoffset = 20, css = css)
        plugins.connect (fig, información sobre herramientas [m])

plugins.connect (fig, plugins.LinkedBrush (dispersión))
prueba = mpld3.fig_to_html (fig = fig)

con abierto ("Output.html", "w") como archivo_texto:
    text_file.write (prueba)

Véalo en acción en mi blog .

Actualización [9 de julio de 2016]: acabo de descubrir que Plot.ly tiene un modo fuera de línea y ahora es de código abierto. Tiene muchas de las campanas y silbatos preempaquetados, pero MPLD3 aún puede ser apropiado en algunos casos.


3

Preferiría que esto fuera un comentario en lugar de una respuesta, ya que mi intención no es conectar / anunciar, pero actualmente estoy trabajando en mi tesis que puede ser de su interés, ya que hace lo que quiere. En realidad, es una herramienta de visualización de agrupamiento, pero si usa k-means con k = 1, tiene un diagrama interactivo donde puede buscar términos, seleccionar un área y ver el contenido de cada nodo y otras cosas. ¡Eche un vistazo y vea si funciona para usted!

https://github.com/Lilykos/clusterix


¡Frio! Le echaré un vistazo.
scottlittle

0

Una muy buena elección, plotly es ...

En mi caso, estaba tratando de trazar una designación similar basada en habilidades, donde las habilidades eran una incrustación de word2vec de 300 dimensiones; lo llevé a un espacio vectorial de 3 dimensiones, y usando plotly Scatter3D, pude trazar un diagrama de dispersión 3D para el mismo.

Et Viola !! Obtuve un impresionante gráfico de 3 dimensiones, con funcionalidad de desplazamiento y ampliación. Y la mejor parte es que se puede exportar como un archivo html, lo que lo convierte en un plug and play adecuado para cualquier otra PC, simplemente arrastre y suelte en un navegador (incluido en el código a continuación).

¿Puede algo ser más 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
)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.