Reducción de la dimensionalidad con PCA

Librería en Python Scikit-Learn

Para este ejemplo se usó la librería scikit-learn, la cual contiene una gran cantidadmodelos de aprendizaje de máquina en Python y es muy usada dentro de la comunidad de Machine Learning. La página de la librería es: http://scikit-learn.org/stable/#


In [19]:
import matplotlib.pyplot as plt #Para graficar
from sklearn import datasets #Para importar la base de datos de prueba
from sklearn.decomposition import PCA #Para reducir la dimensionalidad
from mpl_toolkits.mplot3d import Axes3D #Para graficas 3D
import numpy as np

Base de datos usada

Se usa la base de datos de Iris. Esta base contiene 50 muestras con cuatro características: ancho y largo de los sépalos y los pétalos. Las muestras de la base de datos corresponden a tres tipos de Iris.


In [3]:
iris = datasets.load_iris()

In [4]:
iris.data[1:7,]


Out[4]:
array([[ 4.9,  3. ,  1.4,  0.2],
       [ 4.7,  3.2,  1.3,  0.2],
       [ 4.6,  3.1,  1.5,  0.2],
       [ 5. ,  3.6,  1.4,  0.2],
       [ 5.4,  3.9,  1.7,  0.4],
       [ 4.6,  3.4,  1.4,  0.3]])

In [5]:
iris.target[1:7]


Out[5]:
array([0, 0, 0, 0, 0, 0])

La maldición de la dimensionalidad

Cuando aumenta la dimensionalidad de los datos (la cantidad de variables), el volumen del espacio aumenta exponencialmente, haciendo que los datos disponibles se encuentren más dispersos.


In [27]:
datax = np.asarray([0.0, 1.0, 0.0, 1.0])
datay = np.asarray([0.0, 0.0, 1.0, 1.0])
dataz = np.asarray([0.0, 0.0, 0.0, 50.0])

plt.scatter(datax, datay)
plt.show()



In [38]:
fig = plt.figure(figsize=(6, 9))
ax = Axes3D(fig)

ax.scatter(datax, datay, dataz)


Out[38]:
<mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7f73801ff710>

La distancia euclidiana entre los puntos en tres dimensiones es mayor que la distancia euclidiana de los puntos en dos dimensiones. Para poder enfrentar este problema tenemos dos opciones:

  • Aumentar el número de muestras
  • Reducir la dimensionalidad del problema

Reducción de la dimensionalidad con Análisis de Componentes Principales (PCA)

Supongamos que queremos reducir el problema a dos dimensiones (en la práctica sólo se jusitifica para dimensionalidades muy altas). Se podría simplemente tomar dos de las cuatro variales.

El análisis de componentes principales selecciona las direcciones con mayor variabilidad. Permitiendo eliminar las direcciones con menor variabilidad, pues estas tienen menos información.

Iris sin PCA


In [12]:
plt.scatter(iris.data[:, 0], iris.data[:, 1], c=iris.target)
plt.xlabel(unicode('Longitud del sépalo', 'utf-8'))
plt.ylabel(unicode('Longitud del sépalo', 'utf-8'))


Out[12]:
<matplotlib.text.Text at 0x7f73829efad0>

Iris con PCA


In [13]:
iris_reducido = PCA(n_components=2).fit_transform(iris.data)
plt.scatter(iris_reducido[:, 0], iris_reducido[:, 1], c=iris.target)
plt.xlabel(unicode('Primer vector propio', 'utf-8'))
plt.ylabel(unicode('Segundo vector propio', 'utf-8'))


Out[13]:
<matplotlib.text.Text at 0x7f73827771d0>

En este caso PCA captura logra concentrar la información de las cuatro dimensiones en dos dimensiones. PCA no usa la etiqueta de la muestra. Se usó en este script para ilustrar mejor.