<jupyter_start><jupyter_text>Simulación de Sistemas y LaboratorioUdeA2019-I  Profesor: <NAME> Material introductorio para los laboratorios de Machine LearningEste material explica el manejo del entorno de trabajo de jupyter notebooks, librerías y dinámica para los laboratorios del curso incluye referencias, tips y buenas prácticas. Este material cubre los siguiente temas:1. Instalación y manejo de jupyter2. Manejo de vectores y matrices en NumPy3. Manejo de gráficas en matplotlib4. Manejo de dataframes en pandas3. Ejercicios![alt](jupyter_python_numpy.png)***  1. Instalación de jupyterExisten 3 formas muy populares de correr notebook de jupyter:- Distribuición de [Anaconda](https://www.anaconda.com/). (Recomendado para Windows y macOs)- Administrador de paquetes pip. (Recomendado para Linux)- Contenedor en docker  Manejo de JupyterEs un entorno de trabajo que permite integrar en un mismo "notebook" código por defecto en Python (también aplica para otros lenguajes), texto, gráfica e imágenes a cada bloque se conoce como *celda*. Es utilizado ampliamente en análisis numérico, estadística y machine learning, entre otros campos de la informática y las matemáticas.> Las celdas de texto: está escrita con *Markdown*, un lenguaje de etiquetado más legible para la decoración de texto, se puede hacer desde encabezados, LaTeX, simbolos matematicos hasta listas enumeradas, entre otros.  > Las celdas de código: son ejecutables, es decir, se pueden correr individualmente (con ctrl + enter o desde el menu Cell -> Run Cells)Para saber cuándo una celda se ha ejecutado, está en ello o ya ha terminado, podemos mirar la cabecera de la celda:- Si solamente aparece In [ ], quiere decir que aún no se ha ejecutado.- Si lo que tenemos es In [\*], entonces está en ejecución.- Si aparece un número entre los corchetes, ya ha terminado de ejecutar. Por último, sabemos que cada se ejecuta por separado esto implica que **la ejecución se realiza de arriba hacia abajo en orden**, de este modo ya están cargadas las librerías o variables previamente. Es así como evitamos problemas de importación de librerías o variables sin definir.<jupyter_code>print(x)
x = np.zeros(10)<jupyter_output><empty_output><jupyter_text>!Ahora es tu turno!Haz click en la opción + y añade una celda de texto, observa que sea en Markdown. Luego ejecutamos una celda de código con lo siguiente:    import numpy as np    x = np.zeros(10)    print(x) Hola mundo<jupyter_code>import numpy as np
x = np.zeros(10)
print(x)<jupyter_output>[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]<jupyter_text>2. Manejo vectores y matrices en NumPyNumPy es un paquete que proporciona herramientas y técnicas para manipular estructuras de datos con matrices, es mucho mejor que las listas de Python, tiene acceso y escritura más rápida. Posee una amplia colección de herramientas y técnicas que se pueden utilizar para resolver problemas mátematicos, además de que contiene todas las funciones para trabajar con matrices.A continuación encontrá algunas funciones muy útiles para los laboratorios, tales como:- Creación de matrices- Suma y resta de vectores- Producto de dos vectores- Producto de dos matrices- Multiplicación matricial- Indexación de matrices  Creación de matrices El paquete NumPy introdujo los arrays N-dimensionales, acontinuación se mostrará las rutinas más utilizadas en los laboratorios. (Más rutinas [aquí](https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html))<jupyter_code>#Creacion de array de ceros y unos
zeros=np.zeros(10)
print("Array de 10 ceros:", zeros)
ones=np.ones(10)
print("Array de 10 unos:", ones)
array1 = np.arange(5)  # Array de 5 enteros contando el 0
print("Array de 5 enteros: ",array1)
line = np.linspace(0.0, 1.0, 5) #start, stop, num de puntos
print("Array organizados unif.: ",line)
v1 = np.array([8,6,-5,76,9.7]) #Array de una lista
print("Array de una lista: ",v1)<jupyter_output>Array de 10 ceros: [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
Array de 10 unos: [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
Array de 5 enteros:  [0 1 2 3 4]
Array organizados unif.:  [0.   0.25 0.5  0.75 1.  ]
Array de una lista:  [ 8.   6.  -5.  76.   9.7]<jupyter_text>Ejercicio:  Crear array de ceros con dimension 3x2:<jupyter_code>ceros2x3 = np.zeros((3,2))
print(ceros2x3)
# Inicializar un vector manualmente de 1D
v1 = np.array([3,-1,2]) #Array de una lista
v2= np.array([2,-1,3])
print("v1: ",v1)
print("v2: ",v2)
# Suma y resta de vectores
suma1 = v1 + v2 #(para la resta usamos -)
print(suma1)

# producto elemento a elemento
prod1 = v1*v2
print (prod1)

#Producto matricial
prod1 = np.dot(v1,v2)
print (prod1)

prod2 = v1 @ v2
print(prod2)

# Indexar una matriz manualmente 2x3
m1 = np.array([[1,2,3],[0.5,0.3,2.1]])
print (m1)<jupyter_output>[[1.  2.  3. ]
 [0.5 0.3 2.1]]<jupyter_text>¿Cuántas filas y columnas tiene la variable m1?<jupyter_code>print("Shape m1",m1.shape)
m2 = np.array([[1,2],[2,1],[3,1]]) # [3x2]
print ("Shape m2",np.shape(m2))
print(m2)
#Producto de dos matrices
print (np.dot(m1,m2))
print(m1@m2)
#Producto elemento a elemento
m3 = np.array([[1,2],[2,1]]) # [3x2]
print (np.shape(m3))
print(m3*m3)<jupyter_output>(2, 2)
[[1 4]
 [4 1]]<jupyter_text>¿Por qué el siguiente código produce error?<jupyter_code>print (m1*m2)<jupyter_output><empty_output><jupyter_text>Se debe organizar las dimensiones de la matriz para hacer la multiplicación elemento a elemento correctamente. ¿Cómo se puede solucionar?<jupyter_code>m1_new = m1.T
print("New shape m1", m1_new.shape)
print(m1_new*m2)
m1_new2 = m1.reshape((3,2))
print("New shape m1", m1_new2.shape)
print(m1_new2*m2)
m1_new2 = m1.reshape((3,-1))
print("New shape m1", m1_new2.shape)
print(m1_new2*m2)<jupyter_output>New shape m1 (3, 2)
[[ 1.  18. ]
 [ 6.   0.5]
 [ 0.9  2.1]]<jupyter_text>- ¿Hay alguna diferencia con la matriz m1 después de hacer el reshape? _Reshape_: Asigna una nueva forma a la matriz ya sea un entero para una dimensión o una tupla para N-Dimensiones<jupyter_code>a = np.arange(6).reshape((3, 2))
a
b = np.arange(6).reshape((3,1,2))
b
b = b.reshape((6))
b
c = np.arange(24).reshape((3,2,2,2))
c<jupyter_output><empty_output><jupyter_text>¡Cuidado con la asignación de variables! Python usa variables referenciadas. Si se requiere hacer una copia se debe usar el método ".copy". Dependiendo de si se trabaja con python 2.7 o 3, la sintaxis puede ser diferente.<jupyter_code>m4 = m1
m4[0,1] = 9
print (m1)
print ("---")
m5 = np.copy(m1)
m5[1,1] = 9
print (m4)
print ("---")
print (m5)<jupyter_output>[[1.  9.  3. ]
 [0.5 0.3 2.1]]
---
[[1.  9.  3. ]
 [0.5 0.3 2.1]]
---
[[1.  9.  3. ]
 [0.5 9.  2.1]]<jupyter_text>IndexaciónPara hacer una indexación en matrices se accede con los corchetes y siempre se define así: [filas,columnas]. Observa que la separación se realiza con una coma ( , )    x = matrix[filas, columnas]    Si deseo escoger entre la fila x hasta y debe ser separado por dos puntos **:**, de la siguiente forma:    x = matrix[x:y,]    De la misma forma aplica para las columnas, si quiero la primera columna:    x = matrix[0:2,0:1]    Acceder a los últimas posiciones:    x = matrix[0:-1,0:-1]<jupyter_code>print("Original m2")
print(m2)
print("----")
new_m2 = m2[0:2,]
print("Nuevo m2, dos primeras filas")
print(new_m2)
new_m2 = m2[0:2,0:1]
print("Nuevo m2, dos primeras filas y primera columna")
print(new_m2)
m1[0,:]*m2[:,0]
b = m2[:,0][:, np.newaxis]
print (b)
print ("----")
print( m1[0,:]*b)<jupyter_output>[[1]
 [2]
 [3]]
----
[[ 1.  9.  3.]
 [ 2. 18.  6.]
 [ 3. 27.  9.]]<jupyter_text>Ejercicio: Obtener las últimas dos filas de siguiente vector:    m4 = np.arange(5,25).reshape((10,2))    m4<jupyter_code>m4 = np.arange(5,25).reshape((10,2))
m4
last_m2 =  m4[-2:,-1:]
last_m2<jupyter_output><empty_output><jupyter_text>Concatenar vectores y matrices<jupyter_code>a = np.array([[1,5,9], [2,6,10]])
b = np.array([[3,7,11], [4,8,12]])
print(a)
print("---")
print(b)
np.concatenate((a,b), axis=0)
np.concatenate((a, b), axis=1)
np.vstack((a, b))
np.concatenate((a.reshape(2,3), b.reshape(2,3)))<jupyter_output><empty_output><jupyter_text>Inicializar vectores aleatorios<jupyter_code>a = np.random.rand(10,8)
b = np.array([[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18]])
print (a[0:3,4:8])
print ("----")
print (b[0:2,0:6:2])
 a[np.ix_([1,3,4],[0,2])]
v = np.random.permutation(8)
print (a[:,v>4])<jupyter_output>[[0.95177349 0.25354801 0.42724629]
 [0.7277892  0.95225475 0.56657978]
 [0.5756655  0.02240131 0.86683036]
 [0.52163831 0.15949993 0.46048097]
 [0.97855744 0.88353337 0.90836715]
 [0.12126599 0.98253881 0.47558899]
 [0.03225071 0.54943183 0.63218104]
 [0.22250915 0.991721   0.62608233]
 [0.2240619  0.46583278 0.32011008]
 [0.96649129 0.23602054 0.77531428]]<jupyter_text>Métodos importantes<jupyter_code>print (m1.max())

print (m1.max(0))

print (m1.max(1))

#similar con min
for x in m1:
    print(x)
#ones

#diag

#unique

#linalg.inv #Inversa de matriz

#linalg.svd #Descomposición en valores singulares

#logical_and #Elemento a elelemto

#logical_or #Elemento a elelemto

print(np.mean(a, axis=0))
print ("----")
print (np.mean(a, axis=1))<jupyter_output><empty_output><jupyter_text>----------------------------------  3. Manejo de gráficas en Matplotlib Ahora utilizaremos la librería matplotlib para hacer algunos ejemplos de gráficas básicas:$$ y = x $$$$ y = x^2 $$$$ y = x^3 $$Observemos que la variable x solo se carga en la primera celda de código. En adelante se puede usar sin necesidad de ser cargada de nuevo. En la gráfica de $y=x^3$ incluimos el título de la gráfica y los label para los ejes de la misma.<jupyter_code>## Importar la librería de matplotlib
import matplotlib.pyplot as plt
#x = np.array([-2,-1,0,1,2])
x = np.linspace(-10,10,100)
#print x
#f = "hola"
#print f
#Función y = ax + b
y = 0.5*x
plt.plot(x,y)
plt.ylim(0,10)
plt.xlim(0,10)
plt.ylabel('y = x')
plt.xlabel('x')
plt.title(u"Gráfica de una función lineal\n")
plt.show()
#y = x^2
y = x**2
plt.plot(x,y, c='green')
#plt.xlim(-150,150)
plt.show()
y = x**3
plt.plot(y)

plt.ylabel(r'$y = x^3$')
plt.xlabel(u'x - 100 números entre -10 y 10')
plt.title(u'Ejemplos de introducción para el curso de Simulación de Sistemas - UdeA\n')
plt.show()<jupyter_output><empty_output><jupyter_text>Generando gráfica punteada<jupyter_code>y = x**3
plt.plot(x,y, 'r--')
plt.ylabel('y = x^3')
plt.xlabel(u'x - 100 números entre -10 y 10')
plt.title(u'Ejemplos de introducción para el curso de Simulación de Sistemas - UdeA\n')
plt.show()
y = np.sin(x)
plt.plot(y, 'bo')
plt.ylabel('y = seno(x)')
plt.xlabel(u'x - 100 números entre -10 y 10')
plt.title(r'$s(t) = \mathcal{A}\sin(2 \omega t)$', fontsize=16, color='r')
plt.show()<jupyter_output><empty_output><jupyter_text>Dos gráficas en el mismo plano<jupyter_code>y2 = x
y = np.sin(x)
y1 = np.cos(x)
plt.plot(y, 'r--', y1, 'b-')
plt.ylabel('y = seno(x)')
plt.xlabel(u'x - 100 números entre -10 y 10')
plt.title(u'Ejemplos de introducción para el curso de Simulación de Sistemas - UdeA\n')
plt.show()<jupyter_output><empty_output><jupyter_text>Agregando el legend al gráfico<jupyter_code>y = np.sin(x)
y1 = np.cos(x)
plt.plot(y, 'r-', label='Seno')
plt.plot(y1, 'b-', label='Coseno')
plt.ylabel('y = seno(x)')
plt.xlabel(u'x - 100 números entre -10 y 10')
plt.title(u'Ejemplos de introducción para el curso de Simulación de Sistemas - UdeA\n')
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>Diferentes gráficos<jupyter_code>values = np.array([1, 10, 100])
ind = np.arange(3)
plt.figure(1, figsize=(9, 3))

plt.subplot(131)
plt.bar(ind+1, values*np.random.rand(3))

plt.subplot(132)
plt.bar(ind+1, np.flipud(values))

plt.subplot(133)
plt.bar(ind+1, values)

plt.suptitle(u'Ejemplos - Simulación de Sistemas y Lab.')
plt.show()<jupyter_output><empty_output><jupyter_text>Gráficos para problemas de clasificación en Machine learning. Scatter plots<jupyter_code>#Creamos los datos artificiales

mu1, sigma1 = 1.5, 0.1
mu2, sigma2 = 1, 0.1
N = 100

x1 = mu1 + sigma1 * np.random.randn(N)
x1line = np.linspace(0,2,N)
x2 = mu2 + sigma2 * np.random.randn(N)
x2line = np.linspace(3,5,N)

#Decision boundary
b = -2
m = 3.5
v = np.linspace(0,100,100)
t = v*m + b

plt.scatter(x1, x1line, c='b')
plt.scatter(x2, x2line, c='r')
plt.plot(v, t, 'c-')
plt.ylim(-0.5, 6, 1)
plt.xlim(0.5, 1.8, 0.2)
plt.show()<jupyter_output><empty_output><jupyter_text>Distribución de probabilidad normal univariada$P(x; \mu, \sigma) = \frac{1}{\sqrt{2\pi}\sigma }exp-\frac{1}{2}\frac{(x-\mu)^2}{\sigma^2}$Recordar que lo anterior conforma una familia paramétrica con todos los posibles valores de los parámetros $\mu$ y $\sigma$.Veamos la gráfica de la distribución de la función de densidad de probabilidad normal:<jupyter_code>mu, sigma = 0, 2

#Generamos un conjunto de valores x

x = np.linspace(-3,3,100)
#los llevamos a la función de densidad de probabilidad normal
p = ( 1/(np.sqrt(2*np.pi)*sigma) ) * np.exp( (-1/2) * ( ((x - mu) ** 2) / (sigma ** 2) ) )

plt.plot(x, p, 'r--')
plt.show()<jupyter_output><empty_output><jupyter_text>Notar que:1. El domino de la función de densidad de probabilidad normal es cualquier valor real, es decir, $(-\infty, \infty)$2. La gráfica es simétrica respecto a la media $\mu$3. Tiene un máximo en la media $\mu$4. Crece hasta la media $\mu$ y decrece a partir de ella.5. En los puntos $\mu - \sigma$ y $\mu + \sigma$ presenta puntos de inflexión6. El eje de abscisas es una asíntota de la curva.El área bajo la curva es igual a la unidad.La probabilidad equivale al área encerrada bajo la curva.$p(\mu - \sigma \lt X \leq \mu + \sigma) = 0.6826 = 68.26\%$$p(\mu - 2\sigma \lt X \leq \mu + 2\sigma) = 0.954 = 95.4\%$$p(\mu - 3\sigma \lt X \leq \mu + 3\sigma) = 0.997 = 99.7\%$ Ahora vamos a mirar otros tipos de gráficas muy interesantes.<jupyter_code>p = np.random.randn(1000)
plt.hist(p, color = 'b')
plt.show()
from sklearn import datasets
iris = datasets.load_iris()
X, y = iris.data, iris.target
print (np.shape(X))
print (np.size(y))

import matplotlib.pyplot as plt
plt.title('Problema de 3 clases', fontsize=14)
plt.xlabel(u'Característica 1')
plt.ylabel(u'Característica 2')
plt.scatter(X[:,0], X[:,3], c=y);
plt.show()<jupyter_output>(150, 4)
150<jupyter_text>Leyendo una base de datos desde un archivo de texto plano!<jupyter_code>#db = np.loadtxt('DB.txt',delimiter='\t')  # Assuming tab-delimiter
#X = db[:,0:12] # fila1 = db[4,0:12]
#Y = db[:,12]
#np.mean(Y)
#np.std(Y)
# StringIO behaves like a file object
#c = StringIO("0 1\n2 3")
#print np.loadtxt(c)
c = StringIO("1,0,2\n3,0,4")
z = np.loadtxt(c, delimiter=',')
print (z)
print ('---')
c = StringIO("1,0,2\n3,0,4")
x, y = np.loadtxt(c, delimiter=',', usecols=(0, 2), unpack=True)
print (x,y)<jupyter_output><empty_output><jupyter_text>Estructuras de datos en Python<jupyter_code># Tuplas
tup = (1, "hola", 3)
print (tup[0])
#tup[1] = 2    #Esto es un error

# Listas

lista = [2, 3, 2.5, "Hola"]
print (lista[2])
lista[2] = "nuevo"
print (lista[2])
# Diccionarios

dic = {"clave": "valor", "1": 324, "2": "Hola"}
print (dic["clave"])

#Conjuntos

conjunto = {1, 3, "hola"}
print(conjunto)<jupyter_output><empty_output><jupyter_text>Condicionales, ciclos y funciones  IF, Else If, Else<jupyter_code>age=18
if age>18:
    
    print("you can enter" )
elif age==18:
    print("go see Pink Floyd")
else:
    print("go see Meat Loaf" )
    

print("move on")<jupyter_output><empty_output><jupyter_text>Ciclo For<jupyter_code>range(5)

dates = [1982,1980,1973]
N=len(dates)

for i in range(N):
     
    print(dates[i])<jupyter_output><empty_output><jupyter_text>identacion<jupyter_code>for i in range(0,8):
    print(i)<jupyter_output>0
1
2
3
4
5
6
7<jupyter_text>Ciclo While<jupyter_code>dates = [1982,1980,1973,2000]

i=0;
year=0
while(year!=1973):
    year=dates[i]
    i=i+1
    print(year)
    
    
print("it took ", i ,"repetitions to get out of loop")<jupyter_output><empty_output><jupyter_text>Lectura y escritura de archivos<jupyter_code>example1="Example1.txt"
file1 = open(example1,"r")

for line in file1:
    print (line)
file1.close()
with open(example1,"r") as file1:
    FileContent=file1.read()
    print(FileContent)
## Ejercicio. Escritura y concatenación de un texto en un archivo .txt<jupyter_output><empty_output><jupyter_text>Reto: estudiar la librería Pandas para manejo de Datos<jupyter_code>#df = pd.read_csv<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14962562906591384, 'fraction_numerical': 0.06358168651037191, 'mean_word_length': 4.725579761068166, 'pattern_counts': {'":': 3, '<': 112, '<?xml version=': 0, '>': 117, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '30', 'dir': 'jupyter-structured-clean-dedup', 'id': '326011', 'license': 'MIT', 'n_tokens_mistral': 7357, 'n_tokens_neox': 6881, 'n_words': 1867, 'path': '.ipynb_checkpoints/Jupyter-Intro-checkpoint.ipynb', 'repo_name': 'deiry/Machine-Learning-Intro', 'size': '16311'}