Curso de matemáticas para Data Science: Calculo Básico
Funciones y Limites
Como programar funciones algebraicas
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# función lineal --> f(x) = mx+b
def f(m,x,b):
return m*x+b
m = 7
b = 5
# Con .linspace() generaremos un vector con una serie de puntos en un rango determinado.
x = np.linspace(-10.0, 10.0, num=100)
# Ahora pasaremos los valores a nuestra función
y = f(m,x,b)
# Ahora graficaremos el comportamiento de la funcion con los datos entregados.
fig, ax = plt.subplots()
ax.plot(x,y) #Graficamos la función
ax.grid() # Con .grid() le ponemos cuadros, para apreciar mejor el comportamiento de la función.
#Agregaremos unas lineas horizontales(h) y verticales(v) rojas, para representar un plano cartesiano.
ax.axhline(y = 0, color='r')
ax.axvline(x = 0, color='r')
# funcion polinomica --> f(x) = ax**n + ax**n-1 + ... + ax**2 + ax + a
# funcion cuadratica
def f(x):
return x**2
# Con .linspace() generaremos un vector con una serie de puntos en un rango determinado.
x = np.linspace(-10.0, 10.0, num=100)
# Ahora pasaremos los valores a nuestra función
y = f(x)
# Ahora graficaremos el comportamiento de la funcion con los datos entregados.
fig, ax = plt.subplots()
ax.plot(x,y) #Graficamos la función
ax.grid() # Con .grid() le ponemos cuadros, para apreciar mejor el comportamiento de la función.
#Agregaremos unas lineas horizontales(h) y verticales(v) rojas, para representar un plano cartesiano.
ax.axhline(y = 0, color='r')
ax.axvline(x = 0, color='r')
# funcion polinomica --> f(x) = ax**n + ax**n-1 + ... + ax**2 + ax + a
def f(x):
return 2*x**8 - x**4 + 3*x**2 + 4
# Con .linspace() generaremos un vector con una serie de puntos en un rango determinado.
x = np.linspace(-10.0, 10.0, num=100)
# Ahora pasaremos los valores a nuestra función
y = f(x)
# Ahora graficaremos el comportamiento de la funcion con los datos entregados.
fig, ax = plt.subplots()
plt.xlim(-15, 15) # con los metodos xlim() y ylim() de matplotlib podemos establecer una especie de zoom
plt.ylim(-5, 20) # o rangos para ver el comportamiento de nuestra función.
ax.plot(x,y) #Graficamos la función
ax.grid() # Con .grid() le ponemos cuadros, para apreciar mejor el comportamiento de la función.
#Agregaremos unas lineas horizontales(h) y verticales(v) rojas, para representar un plano cartesiano.
ax.axhline(y = 0, color='r')
ax.axvline(x = 0, color='r')
Cómo programar funciones trascendentes
# Numpy ya tiene definida las funciones trigonometricas, por lo que basta con solo mencionarlas.
# funcion coseno
def f(x):
return np.cos(x)
# Con .linspace() generaremos un vector con una serie de puntos en un rango determinado.
x = np.linspace(-10.0, 10.0, num=100)
# Ahora pasaremos los valores a nuestra función
y = f(x)
# Ahora graficaremos el comportamiento de la funcion con los datos entregados.
fig, ax = plt.subplots()
ax.plot(x,y) #Graficamos la función
ax.grid() # Con .grid() le ponemos cuadros, para apreciar mejor el comportamiento de la función.
#Agregaremos unas lineas horizontales(h) y verticales(v) rojas, para representar un plano cartesiano.
ax.axhline(y = 0, color='r')
ax.axvline(x = 0, color='r')
# funcion seno
def f(x):
return np.sin(x)
# Con .linspace() generaremos un vector con una serie de puntos en un rango determinado.
x = np.linspace(-10.0, 10.0, num=100)
# Ahora pasaremos los valores a nuestra función
y = f(x)
# Ahora graficaremos el comportamiento de la funcion con los datos entregados.
fig, ax = plt.subplots()
ax.plot(x,y) #Graficamos la función
ax.grid() # Con .grid() le ponemos cuadros, para apreciar mejor el comportamiento de la función.
#Agregaremos unas lineas horizontales(h) y verticales(v) rojas, para representar un plano cartesiano.
ax.axhline(y = 0, color='r')
ax.axvline(x = 0, color='r')
# funcion exponencial euler --> Numpy ya lo tiene integrado.
def f(x):
return np.e**x
# Con .linspace() generaremos un vector con una serie de puntos en un rango determinado.
x = np.linspace(-5.0, 5.0, num=100)
# Ahora pasaremos los valores a nuestra función
y = f(x)
# Ahora graficaremos el comportamiento de la funcion con los datos entregados.
fig, ax = plt.subplots()
plt.ylim(-1,20) # Cambiamos el zoom de la grafica a que nos muestre esos valores en el eje Y.
ax.plot(x,y) #Graficamos la función
ax.grid() # Con .grid() le ponemos cuadros, para apreciar mejor el comportamiento de la función.
#Agregaremos unas lineas horizontales(h) y verticales(v) rojas, para representar un plano cartesiano.
ax.axhline(y = 0, color='r')
ax.axvline(x = 0, color='r')
# funcion logaritmo --> Numpy ya lo tiene integrado.
def f(x):
return np.log2(x)
# Con .linspace() generaremos un vector con una serie de puntos en un rango determinado.
x = np.linspace(0.01, 256.0, num=100) # Lo dejamos hasta el 256 para que alcance el 8 (2**8=256)
# Ahora pasaremos los valores a nuestra función
y = f(x)
# Ahora graficaremos el comportamiento de la funcion con los datos entregados.
fig, ax = plt.subplots()
plt.ylim(-5,9) # Cambiamos el zoom de la grafica a que nos muestre esos valores en el eje Y.
ax.plot(x,y) #Graficamos la función
ax.grid() # Con .grid() le ponemos cuadros, para apreciar mejor el comportamiento de la función.
#Agregaremos unas lineas horizontales(h) y verticales(v) rojas, para representar un plano cartesiano.
ax.axhline(y = 0, color='r')
ax.axvline(x = 0, color='r')
# funcion de Heaviside
def H(x):
y = np.zeros(len(x)) # Creamos un vector del largo de x (100 datos) con ceros.
for idx,x in enumerate(x):
if x>=0:
y[idx] = 1.0
return y
# Con .linspace() generaremos un vector con una serie de puntos en un rango determinado.
x = np.linspace(-10.0, 10.0, num=100)
# Ahora pasaremos los valores a nuestra función
y = H(x)
# Ahora graficaremos el comportamiento de la funcion con los datos entregados.
fig, ax = plt.subplots()
#plt.ylim(-1,20) # Cambiamos el zoom de la grafica a que nos muestre esos valores en el eje Y.
ax.plot(x,y) #Graficamos la función
ax.grid() # Con .grid() le ponemos cuadros, para apreciar mejor el comportamiento de la función.
¿Cómo manipular funciones?
Funciones dentro de otras funciones
# Crearemos 2 funciones para entender mejor como funciona
def f(x):
return x**2
def g(x):
return np.sin(x)
x = np.linspace(-10, 10, 100) # Un vector de 100 numeros en un intervalo de [-10,10]
# En matplotlib podemos pasarle como primer parametro los datos que queremos graficar y en
# el segundo la funcion o comportamiento que queremos que tengan esos datos.
plt.ylim(-1,5)
plt.plot(x, g(x))
plt.plot(x, f(x))
# Aqui lo que hacemos primero es calcular el seno de todos los valores del vector x y luego
# elevarlos al cuadrado
f_o_g = f(g(x))
#plt.ylim()
plt.plot(x, f_o_g)
# Aqui lo que hacemos es elevar al cuadrado todos los valores del vector x y luego calcular
# el seno de ellos.
g_o_f = g(f(x))
plt.plot(x, g_o_f)
Características de las funciones
¿Cómo se compone una neurona?
Funciones de activación en una neurona
Función de coste: calcula qué tan erradas son tus predicciones
¿Qué es un limite?
Calculo diferencial
¿De donde surge la derivada?
Notación de la derivada
Máximos y Mínimos
¿Cómo optimizar una función?
Más dimensiones para tus funciones
Derivadas parciales
Ejemplos de derivadas parciales
Regla de la cadena y su utilidad en cálculo multivariable
Subamos con el gradiente
Proyecto: descenso del gradiente
¿Qué es el descenso del gradiente?
Graficando nuestra función de coste
from matplotlib import cm
import numpy as np
import matplotlib.pyplot as plt
def f(x,y):
return x**2 + y**2
fig, ax = plt.subplots(subplot_kw={"projection":"3d"})
res = 100
x = np.linspace(-4, 4, res)
y = np.linspace(-4, 4, res)
X, Y= np.meshgrid(x,y)
Z = f(X,Y)
surf = ax.plot_surface(X, Y, Z,cmap=cm.cool)
fig.colorbar(surf)
level_map =np.linspace(np.min(Z),np.max(Z),res)
plt.contourf(X,Y,Z,level_map, cmap=cm.cool)
plt.colorbar()
plt.title("Descenso del gradiente")
p = np.random.rand(2)*8 -4 # Creamos el punto o vector aleatorio para comenzar.
# Graficaremos este punto
plt.plot(p[0], p[1], 'o', c='k')
h = 0.01 # la variación que tendran los puntos
lr = 0.01 # learning rate --> ver definición más arriba.
def derivate(cp,p):
return (f(cp[0], cp[1]) - f(p[0], p[1])) / h # Derivando aplicando la def. de limite.
def gradient(p):
grad = np.zeros(2) # creamos un vector de ceros de 2D
for idx, val in enumerate(p):
cp = np.copy(p) # Hacemos una copia de nuestro punto aleatorio.
cp[idx] = cp[idx] + h
dp = derivate(cp, p) # derivada parcial
grad[idx] = dp
return grad
# Ahora iteraremos consecutivamente para obtener el resultado deseado. El minimo global.
for i in range(1000):
p = p - lr*gradient(p)
if i%10==0:
plt.plot(p[0], p[1], 'o', c='r') #cada 10 graficaremos un punto rojo para ver donde esta
# Graficaremos el ultimo punto en blanco para ver en donde finaliza.
plt.plot(p[0], p[1], 'o', c='w')
print(p)
def f(x,y):
return np.sin(x) + np.cos(y)
fig, ax = plt.subplots(subplot_kw={"projection":"3d"})
res = 100
x = np.linspace(-4, 4, res)
y = np.linspace(-4, 4, res)
X, Y= np.meshgrid(x,y)
Z = f(X,Y)
surf = ax.plot_surface(X, Y, Z,cmap=cm.cool)
fig.colorbar(surf)
level_map =np.linspace(np.min(Z),np.max(Z),res)
plt.contourf(X,Y,Z,level_map, cmap=cm.cool)
plt.colorbar()
plt.title("Descenso del gradiente")
p = np.random.rand(2)*8 -4 # Creamos el punto o vector aleatorio para comenzar.
# Graficaremos este punto
plt.plot(p[0], p[1], 'o', c='k')
h = 0.01 # la variación que tendran los puntos
lr = 0.001 # learning rate --> ver definición más arriba.
def derivate(cp,p):
return (f(cp[0], cp[1]) - f(p[0], p[1])) / h # Derivando aplicando la def. de limite.
def gradient(p):
grad = np.zeros(2) # creamos un vector de ceros de 2D
for idx, val in enumerate(p):
cp = np.copy(p) # Hacemos una copia de nuestro punto aleatorio.
cp[idx] = cp[idx] + h
dp = derivate(cp, p) # derivada parcial
grad[idx] = dp
return grad
# Ahora iteraremos consecutivamente para obtener el resultado deseado. El minimo global.
for i in range(1000):
p = p - lr*gradient(p)
if i%10==0:
plt.plot(p[0], p[1], 'o', c='r') #cada 10 graficaremos un punto rojo para ver donde esta
# Graficaremos el ultimo punto en blanco para ver en donde finaliza.
plt.plot(p[0], p[1], 'o', c='w')
print(p)