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

"""
Explanation: <center> Reducción de la dimensionalidad con PCA <centers/>
Librería en Python Scikit-Learn
<img src="images/sl_logo.png" />
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/#
End of explanation
"""


iris = datasets.load_iris()

iris.data[1:7,]

iris.target[1:7]

"""
Explanation: 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.
End of explanation
"""


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()

fig = plt.figure(figsize=(6, 9))
ax = Axes3D(fig)

ax.scatter(datax, datay, dataz)

"""
Explanation: 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.
End of explanation
"""


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'))

"""
Explanation: 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.
<img src="images/pca.png" />
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
End of explanation
"""


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'))


"""
Explanation: Iris con PCA
End of explanation
"""


