Introducción Al Curso de Machine Learning Aplicado Con Python

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 62

1- Introducción al curso de Machine Learning Aplicado con Python

https://platzi.com/clases/1178-scikit/8822-introduccion-al-curso-de-machine-learning-aplica-6/

Introducción al curso de Machine Learning Aplicado con Python


Bienvenidos al Curso de Machine Learning Aplicado con Python, en este curso veremos cómo
utilizar Machine Learning con distintas librerías de Python. Particularmente estaremos utilizando Scikit-
Learn, que es una de las más utilizadas de la industria.
En este curso también nos enfocaremos es en entender todo el flujo de trabajo que se hace cuando se
resuelve un problema de Machine Learning.
Además de entender muy bien los algoritmos de Machine Learning que estaremos viendo, veremos otras
disciplinas que son tanto o más importantes como el Feature Engineering y la selección de modelos.

2- Importancia de definir el problema en Machine Learning


https://platzi.com/clases/1178-scikit/8823-importancia-de-definir-el-problema-en-machine-le-3/
Errores comunes que se ven cuando no se define bien el problema y se comienza a codear:
 No hay problemas por resolver.
 Existen soluciones más simples.
 No se puede medir el impacto del modelo.
 No se sabe si el problema ya ha sido resuelto antes.
 El problema es imposible de resolver.
Preguntas clave para reconocer el tipo de aprendizaje que se necesita:
 ¿Qué beneficio se puede generar y para quién?
 ¿Cuál de las siguientes funcionalidades sería más útil para lograr el objetivo?
a) Predecir alguna métrica (Aprendizaje supervisado)
b) Predecir una etiqueta (Aprendizaje supervisado)
c) Agrupar elementos similares.
d) Optimizar un proceso con prueba y error.
Preguntas clave para aterrizar el problema de aprendizaje supervisado:
 ¿De qué tipo es el valor que se quiere predecir?
a) Continuo
b) Discreto
 ¿Cuál es la definición de éxito en una predicción?
 ¿Con qué datos se contaría para hacer esa predicción?
 ¿La pregunta que se está tratando de resolver pertenece a alguna disciplina en particular?
 Considerando nuestra intuición en la disciplina ¿Los datos nos permiten predecir el objetivo?
Preguntas clave para aterrizar el problema de aprendizaje supervisado:

¿De qué tipo es el valor que se quiere predecir?


- Continuo: Pueden tomar cualquier valor ‘real’ (infinito).
- Discreto: Corresponden a un rango finito de posibles valores.

¿Cuál es la definición de éxito en una predicción? Establecer una métrica de rendimiento (calificación).
Ejemplo, evaluar la precisión de una predicción.

¿Con qué datos se contaría para hacer esa predicción? Establecer con claridad con que datos contamos y
cuales necesitamos.

¿La pregunta que se está tratando de resolver pertenece a alguna disciplina en particular?
Considerando nuestra intuición en la disciplina ¿Los datos nos permiten predecir el objetivo? Entre más
conozcamos la disciplina o el negocio (modelo del dominio) mejor resultado dará el modelo de ML que
diseñemos para resolver el problema (pregunta).

Problemas clásicos de Machine Learning: -Predecir métrica -Predecir etiqueta (clasificar) -Agrupar
elementos similares -Optimizar con ensayo error

3- PREDECIR EL INGRESO DE PELÍCULAS DE IMDB

https://platzi.com/clases/1178-scikit/8824-predecir-el-ingreso-de-peliculas-de-im-2/

https://www.youtube.com/watch?v=_OcLeySukXA&feature=youtu.be

CONTEXTO ejemplo:
Somos un ente gubernamental que quiere definir sus políticas de financiamiento de producciones
cinematográficas nacionales
1- Ayudar a la producción de películas de calidad que no logran ser autosustentables
2- Nos sería útil saber que películas tiene mas dificultad para recuperar en sus presupuestos. Por

01 La importancia de definir tu problema.ipynb


02 Predecir el ingreso de películas con IMDB.ipynb
03 Un poco de terminología de ML.ipynb
04 Ciclo de trabajo del Machine Learning.ipynb
05 Docker.ipynb
06 Construir la imagen.ipynb
07 Instanciar el contenedor.ipynb
08 Introducción a Python Científico.ipynb
09 Preparación de los datos.ipynb
10 Primera Iteración - Modelamiento y Evaluación.ipynb
11 Como diseñar buenas features y maldición de la dimensión.ipynb
12 Análisis y selección de Features.ipynb
13 Creación y transformación de features.ipynb
14 Cross Validation y Selección de Modelos.ipynb
15 Ensembles y Optimización de Hiperparámetros.ipynb

3- consiguiente, queremos predecir una métrica: el ingreso mundial generado por una película.
ATERRIZA TU PROBLEMA DE APRENDIZAJE SUPERVISADO
 Los ingresos de una película corresponden a valores continuos
 Mi éxito será “que tan cerca estoy del valor real de ingreso generado por la película “
 Me basare en bases de datos públicas de internet
 El dominio de trabajo es la industria de cine, en particular de la distribución de películas
 Si de forma general existen bastantes características que me pueden ayudar a saber que película
será exitosa como: calidad, actores, presupuesto ect--
Quiero predecir ingresos de péliculas, para tomar mejores decisiones de financiamiento, con base a una
regresión sobre datos de películas extraídos de internet.
Mi evaluación del éxito será la precisión de mis predicciones.
Podré apoyarme en conocimientos específicos de la industria.

4- Terminología de Machine Learning

https://platzi.com/clases/1178-scikit/8825-terminologia-de-machine-learni-7/
Terminología
Datos tabulares = Datos en dos dimensiones.
Líneas = Ejemplos
Columna = Feature. Éstas son importantes porque nos van a ayudar a predecir cosas gracias a los modelos
que usemos de Machine Learning.
Cantidad de columnas = Dimensión de los datos
Output de un algoritmo de Machine Learning (ML) = Modelo
Variable objetivo = Target

Ejemplo
Linea = ejemplo (Película)
Columna = Feature (nos ayudan a precedir cosas gracias a los modelos de ML) (Características de cada
película)
**Cantidad de columnas **= dimensión de datos
Variable objetivo = target (Lo que se quiere predecir) (Ingreso de cada película)
Output de un algoritmo de ML = Modelo

5- MATERIALES DEL CURSO:


NOTEBOOKS DE JUPYTER

En este material te comparto los notebooks de Jupyter utilizados por el profesor durante el curso, recuerda
que lo ideal es que tú mismo desarrolles estos ejercicios, pero este material te servirá como apoyo y punto de
comparación en caso de que te encuentres con alguna dificultad en el camino.
https://github.com/JuanPabloMF/machine-learning-platzi/tree/master
Espero que sigas disfrutando este curso y no olvides al final tomar el examen y obtener tu certificación.
¡Mucho éxito

5.1- Este repositorio contiene los notebooks del curso "Machine Learning Aplicado con Python" que dicté
en platzi.
El objetivo de este curso es entregar los skills prácticos necesarios para implementar algoritmos de ML en
un contexto profesional.
El curso incluye:
 Introducción a Numpy, para manejo de algebra lineal.
 Introducción a Pandas, para manejo de los datos en un formato de DataFrames (tablas).
 Docker files para setup de ambientes limpios y poderosos de trabajo de Machine Learning.
 Estudio completo del ciclo de ingeniería del Machine Learning.
o Preparación de datos: Cleaning, Imputation, Merging.
o Feature Engineering: One-hot encode, Scaling, Feature Design
o Entrenamiento de modelos: Sklearn API (train_test_split, fit, predict, score)
o Evaluación de modelos: sklearn.model_selection, Cross Validation, Grid Search.
 Algoritmos de Machine Learning: Regresión Lineal, Regresión Lasso, KNN, Random Forest, Gradient
Boosting Trees.
El curso sigue un flujo de resolución real de un problema de predicción de ingreso de peliculas con la base de
datos de IMDB con 1000+ ejemplos de entrenamiento.

6 - CICLO DE TRABAJO DEL MACHINE LEARNING

https://platzi.com/clases/1178-scikit/8828-iteraciones-y-la-navaja-de-occ-8/

Muchas veces pensamos que hacer Machine Learning corresponde solamente a implementar un algoritmo


de cualquiera de las librerías y con ello ya existe la solución a un problema. Pero en realidad existe todo un
ciclo de trabajo donde los algoritmos de Machine Learning son solo una etapa, sin embargo, las demás
etapas también son muy importantes y toman su tiempo para lograr los resultados que esperamos.
Hacer Machine Learning corresponde a trabajar en un ciclo, ir trabajando varias etapas e ir iterando.
Ciclo de Machine Learning:
 Definición del problema.
 Preparación de los datos.
 Representación de los datos.
 Modelamiento / Algoritmos de ML.
 Evaluación.
Este no es el final del proceso, se debe iterar hasta que en alguna de las iteraciones salga la solución al
problema.
 Producción (Fin del proceso).
7- Configuración del ambiente de trabajo con Google Collab
Setup del curso
En este curso utilizaremos Jupyter Notebooks y el stack Pydata, que incluye las librerías Numpy, Pandas,
Matplotlib y Scikit-learn.
En lo que sigue te presento 3 opciones para trabajar con estas tecnologías:
1. Trabajar en el cloud gracias a la excelente herramienta Google Colab.
2. Trabajar en local en tu computadora gracias a Anaconda.
3. Trabajar en tu computadora virtualizando a través de contenedores con Docker.
Google Colab es la opción mas facil de usar, así que esta es la opción oficial recomendada por el
curso.
Solo lee las instrucciones para las otras opciones si por alguna razon en particular prefieres ocupar una de
ellas (Anaconda permite que trabajes en local, y Docker es bueno para usos en producción).
Google Colab
Google Colab es muy similar en su uso a Google Docs. Puedes ir directamente a su
pagina https://colab.research.google.com/ o abrir Google Drive, clickear en el botón “+ Nuevo” y desde ahí
elegir la opción “Mas” y clickear en Colaboratory (como se ve en la imagen)
Con esto tendrás un notebook de Google Colab a tu disposición!
Un notebook se compone de celdas de codigo y de texto. Una celda de codigo es ejecutable tecleando
“Control + Enter”. Para probar que todo esta ok puedes ejecutar el siguiente codigo:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sklearn
Veras arriba a la derecha que colab se esta conectando a una instancia de computo en la nube (esto colab lo
hace solo, no te preocupes!). Esta conexión la realiza solo la primera vez.

Una vez conectado, el código que ingresaste se ejecutara, y veras que efectivamente los imports se harán sin
ningún problema por lo que ya tienes todo lo que necesitas para trabajar!
Un solo punto adicional que queda por aclarar es que como estas trabajando en la nube no tienes
directamente los archivos de la clase a mano para poder leerlos desde el notebook.
Para poder acceder los archivos del curso puedes hacer lo siguiente:
1. Encuentra el link hacia el archivo que quieres cargar en el repositorio de
github https://github.com/JuanPabloMF/datasets-platzi-course
2. Con el link del archivo csv puedes llamar la función de pandas read_csv de la siguiente manera:
import pandas as pd

pd.read_csv(url)
Ya puedes entrar de llenos al curso y empezar a implementar tus primeros modelos de machine
learning!

Otras opciones
Anaconda
Para instalar Anaconda debes:
 Ir a https://www.anaconda.com/distribution/
 Elige tu sistema operativo: Windows/Linux/macOS
 Descarga el instalador gráfico para la arquitectura que corresponda a la CPU de tu computadora
(32 bits o 64 bits)

Cuando hayas descargado el instalador gráfico y lo hayas abierto se te solicitaran diversas confirmaciones,
puedes tomar las opciones por defecto.
Anaconda quedara luego de estos pasos instalado dentro de tus aplicaciones.
Abre Anaconda y en la home tendras Jupyter disponible. Abrelo con botón Launch.
El ambiente por defecto en el que Anaconda te hara trabajar se llama “base (root)” y ya contiene las
librerías esenciales de Pydata.
Crea un nuevo notebook de python 3 y estas listo para trabajar!

Docker
Te recomiendo usar Docker solo si ya tomaste alguno de los cursos de Platzi que te ensenan a usarlo, o si ya
tienes experiencia con esta herramienta.
1. Primero instala Docker en tu computador
Ve a https://www.docker.com/products/docker-desktop y haz click en descargar para tu OS.
Dale click a descargar. Esto descargara un archivo (en el caso de windows .exe) que es el instalador y pesa
914 MB.

5.3- Configurar un ambiente Pydata de trabajo


 Scikit-learn es la librería de Machine Learning estandar más popular según estadisticas de
Github.
 Saber ocupar Scikit-learn es equivalente a saber hacer Machine Learning con Python.
 Scikit-learn se apoya en una familia de librerías comunmente conocida como el ambiente
Pydata.
Para hacer machine learning de forma profesional es importante:
 Contar con librerias:
 cientificas (numpy, scipy, statsmodel),
 procesamiento de datos (pandas, dask),
 machine learning (scikit-learn, keras),
 visualizacion de datos (matplotlib, bokeh, seaborn).
 Contar con ambientes limpios y separados, que se puedan construir rapidamente y de forma
reproducible.
 Trabajar en un IDE adaptado a workflows de machine Learning
Instalar Docker
 Mac y Windows
Para estos dos sistemas operativos basta con ir a https://www.docker.com/ y descargar desde la sección
"Get Docker" el GUI installer apropiado para tu sistema operativo.
 Ubuntu (arquitectura X_86_64)
Copia y pega -una por una- estas lineas en tu terminal.
sudo apt-get remove docker docker-engine docker.io
sudo apt-get update
sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $
(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce
Para confirmar que docker quedo bien instalado en tu computador corre el comando de test siguiente, que
te deberian printear un hola mundo en tu consola:
sudo docker run hello-world

5.4- Construir las imagenes


Antes de poder crear un contenedor docker en el cual trabajaremos debemos construir una imagen. Una
imagen corresponde de cierta forma a la "receta" desde la cual se instanciara nuestro contenedor.
 Descargar Dockerfiles (Github)
Desde tu folder de trabajo (~/platzi-ml/):
[~/platzi-ml] $ git clone https://github.com/JuanPabloMF/arara-docker-stacks.git
 Crear Imagenes
[~/platzi-ml] $ cd arara-docker-stacks/ararads-base
[~/platzi-ml/arara-docker-stacks/ararads-base] $ sudo docker build -t ararads-base:1.0 .
[~/platzi-ml/arara-docker-stacks/ararads-base] $ cd ../ararads-tf-cpu
[~/platzi-ml/arara-docker-stacks/ararads-tf-cpu] $ sudo docker build -t ararads-tf-cpu:1.0 .

5.5 Instanciar el contenedor


 Crear folder que sera montado en tus contenedores Docker
[~/platzi-ml] $ mkdir vol
Importante: En este folder es donde deberas descargar/copiar tus datasets para que puedas verlos en el
contenedor que estes trabajando.
$ sudo docker run -ti --name platzi-ml -v ~/platzi-ml/vol:/home/juanpablo/work/vol -p 9000:8888
ararads-tf-cpu:1.0 start-notebook.sh --NotebookApp.token=''
Con esto solo quedaria acceder desde chrome a http://localhost:9000/ y estamos listos para trabajar!
Notas
-v es una opcion que permite conectar un archivo que tengas en tu computador con un archivo que estara
en tu contenedor. Esto es bueno para poder ingresar datos facilmente a tu contenedor, o extraerlos de forma
ordenada
-p te permite exponer un puerto interno del computador a traves de un puerto de tu maquina local. En
terminos simples por aqui es donde accederas a tu jupyter.
Las imagenes que construimos inicializan automaticamente un Jupyter que queda esperando en su puerto.

7- QUE ES Y COMO SE UTILIZA NUMPY


https://platzi.com/clases/1178-scikit/8831-3-fundamentos-de-python-cientifico-1-num-8/
Datos importantes:
 Numpy es una librería muy importante para el ecosistema de Python ya que es la base de todos los
cálculos científicos y muchas de las librerías de Machine Learning.
 Scikit-Learn con sus modelos, cuando retorna un resultado, en general lo retorna en un
formato Numpy.
 La API de Numpy tiene muchas similitudes con Pandas.
 Numpy reemplaza de forma más eficiente lo que podría ser un tipo lista. En las listas podemos
tener conjuntos de elementos numéricos. Sin embargo las listas no logran manejar datos de dos
dimensiones.
 Las listas no poseen métodos que son prácticos para hacer aritmética.
 Es importante saber que otros lenguajes de programación poseen librerías altamente optimizadas
para hacer cálculos numéricos con vectores de datos. Numpy es esa librería para el lenguaje de
programación de Python.
 np.linspace es una función que permite crear un array de una dimensión de números entre 0 y 1.
 Los array a diferencia de otros objetos en Python están fuertemente tipificados. Esta tipificación
fuerte es necesaria porque es una de las cosas que permite que esta librería sea más rápida que ocupar
listas, por ejemplo.

8- INTRODUCCION A PYTHON CIENTÍFICO.IPYNB


Porque Numpy?
 list no tiene buen manejo para los indices cuando se trabaja con listas de datos de más de dos
dimensiones.
 list no posee metodos de algebra lineal, ni de transformaciones de datos.
 En otros lenguajes encontramos estructuras de datos altamente optimizadas para poder hacer
operaciones algebraicas sobre arrays.
Por sobre Numpy se erige todo un ecosistema de librerias muy utiles que iremos viendo en el recorrido de
este curso.
Crear Arrays
In [1]:
#Importar la librería
import numpy as np

In [3]:
a1 = np.array([1,2,3]) # con una lista
type(a1)
Out[3]: numpy.ndarray

In [4]:
a2 = np.arange(10) # np.arange es un metodo similar al range del tipo list

In [5]:
a2
Out[5]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [6]:
a3 = np.zeros((2,3)) # crear un lista de dos dimensiones, pre-rellenada con zeros
a4 = np.ones((2,3)) # crear un lista de dos dimensiones, pre-rellenada con unos

In [7]:
from IPython.display import display #LIMPIA EL TIPO DE ARRAY
display(a3); display(a4)
array([[ 0., 0., 0.],
[ 0., 0., 0.]])
array([[ 1., 1., 1.],
[ 1., 1., 1.]])

np.linspace(a,b,n)
 es una función que permite crear arrays de una dimensión, de largo n, y que contienen puntos entre a y b,
distanciados de forma regular. La distancia entre cada punto sera de 
.
In [9]:
a5 = np.linspace(0,1,11) #la distancia entre numeros es el segundo # menos la entrada o sea 0
display(a5)
array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])

In [10]:
# Dtypes
a5.dtype
Out[10]: dtype('float64')

9- ARRAYS EN NUMPY
https://platzi.com/clases/1178-scikit/8832-fundamentos-de-python-cientifico-2-num-0/
https://medium.com/@steve7an/how-to-test-jupyter-notebook-from-github-via-google-colab-7dc4b9b11a19

Funtion eye ()

Parámetros: El método numpy.eye () consta de cinco parámetros, que son


los siguientes:

N: Representa el número de filas.


M: Representa el número de columnas. Es un argumento opcional y por
defecto M (número de columnas) = N (Número de filas)
K: [int, opcional, 0 por defecto] Este argumento representa la Diagonal. Por
defecto k = 0. Un valor positivo (k> 0) se refiere a una diagonal superior, y
un valor negativo (k <0) a una diagonal inferior.
dtype: es un parámetro opcional. Representa el tipo de datos de la matriz
devuelta y, de forma predeterminada, es flotante.
orden: el parámetro de orden puede ser C_contiguous o F_contiguous
Valor de retorno: El método numpy.eye () devuelve una matriz de formas, R
x C, donde todos los elementos son iguales a cero, excepto la diagonal
enésima, cuyos valores son iguales a uno.
Dimensión de un Array
In [11]:
display(a1)
array([1, 2, 3])

In [12]:
A1.shape # dimensión
Out[12]: (3,)

In [16]:
display(a3)
array([[ 0., 0., 0.],
[ 0., 0., 0.]])
In [17]:
a3.shape # dimensión
Out[17]: (2, 3)

In [20]:
a1D = np.array([1,2,3]) # DE UNA DIMENSION
a2D = np.array([[1,2,3]])
display(a1D.shape)
display(a2D.shape)
(3,)
(1, 3)

In [21]:
# Son los dos arrays iguales?
np.array_equal(a1D,a2D) # ESTO NO DICE QUE UNA ARRAYS ES IGUAL
Out[21]: False

In [23]:
# Reshaping
new_dims = (1,a1D.shape[0]) #TUPLA a1D.shape[0]) = (1,2,3) LONGITUD
a = a1D.reshape(new_dims)

In [25]:
np.array_equal(a,a2D)
Out[25]: True

Acceso a elementos y Slicing

In [26]:
a = np.array([[1,0,3],[4,3,5],[6,10,-1]])
a
Out[26]: array([[ 1, 0, 3],
[ 4, 3, 5],
[ 6, 10, -1]])

In [30]:
a[2,1] # primer elemento son las líneas (2) y el Segundo elemento son las columnas (1)
Out[30]:10

Para acceder a un elemento de un array de dimensión n, la síntaxis es  .


En este curso y frecuentemente en ML trabajaremos con arrays de dimensión 1 o dimensión 2, por lo que:

 Para un array de 1D: 


 Para un array de 2D: 

In [31]:
a = np.arange(10)
b = np.eye(3)
display(a);display(b)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])

In [34]:
a[:5] # acceder a los 5 primeros
Out[34]: array([0, 1, 2, 3, 4])

In [36]:
b[0:3,1]
Out[36]:array([ 0., 1., 0.])

In [37]:
b[2,0:3]
Out[37]: array([ 0., 0., 1.])

In [38]:
b[:,:] #cuando quiero acceder a todos los elementos
Out[38]: array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])

10- OPERACIONES ARITMÉTICAS EN NUMPY


https://platzi.com/clases/1178-scikit/8834-fundamentos-de-python-cientifico-3-numpy74-0/

In [ ]: # Slicing de arrays

# 5 primeros elementos del array a


# esta notación nos permite obtener la segunda línea del array b
# tercera columna del array b
# todo el array b.
Operaciones sobre arrays
In [39]:
# Aritmetica
a = np.arange(4)

print("a =", a)
print("a + 5 =", a + 5)
print("a - 5 =", a - 5)
print("a * 2 =", a * 2)
print("a / 2 =", a / 2)
print("a // 2 =", a // 2)
print("-a = ", -a)
print("a ** 2 = ", a ** 2)
print("a % 2 = ", a % 2)
RTA:
a = [0 1 2 3]
a + 5 = [5 6 7 8]
a - 5 = [-5 -4 -3 -2]
a * 2 = [0 2 4 6]
a / 2 = [ 0. 0.5 1. 1.5]
a // 2 = [0 0 1 1]
-a = [ 0 -1 -2 -3]
a ** 2 = [0 1 4 9]
a % 2 = [0 1 0 1]

Operato
ufunc
r
+ np.add
np.subtrac
-
t
np.multipl
*
y

In [42]:
# Otras ufuncs interesantes
a = np.arange(4)
b = np.arange(1,5)

display(np.exp(a)) # exponencial
display(np.log(b)) # logaritmo natural
display(np.sqrt(a)) # raiz cuadrada
display(np.greater(a,b)) # superior o igual punto a punto
RTA:
array([ 1. , 2.71828183, 7.3890561 , 20.08553692])
array([ 0. , 0.69314718, 1.09861229, 1.38629436])
array([ 0. , 1. , 1.41421356, 1.73205081])
array([False, False, False, False], dtype=bool)

In [44]:
a
Out[44]:
array([0, 1, 2, 3])

In [43]:
b
Out[43]: array([1, 2, 3, 4])

Rendimiento
Las ufuncs corren a velocidad de código compilado C.
De poder utilizarse se deberían preferir a el uso de for loops.
Un código Numpy solo con funciones nativas, sin bucles, se le llama código "vectorizado".
In [2]:
import numpy as np

In [5]:
%%timeit
a = np.arange(1000000)
b = np.zeros(1000000)
i=0
for el in a:
b[i] = el+el
i+=1
237 ms ± 14.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [9]:
%%timeit
a = np.arange(1000000)
a+a
1.61 ms ± 56.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [6]:
%%timeit
a+a

NameErrorTraceback (most recent call last)


<ipython-input-6-253a555a051d> in <module>()
----> 1 get_ipython().run_cell_magic('timeit', '', 'a+a')

/opt/conda/lib/python3.5/site-packages/IPython/core/interactiveshell.py in run_cell_magic(self,
magic_name, line, cell)
2101 magic_arg_s = self.var_expand(line, stack_depth)
2102 with self.builtin_trap:
-> 2103 result = fn(magic_arg_s, cell)
2104 return result
2105

<decorator-gen-61> in timeit(self, line, cell)

/opt/conda/lib/python3.5/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)


185 # but it's overkill for just that one bit of state.
186 def magic_deco(arg):
--> 187 call = lambda f, *a, **k: f(*a, **k)
188
189 if callable(arg):

/opt/conda/lib/python3.5/site-packages/IPython/core/magics/execution.py in timeit(self, line, cell)


1078 for index in range(0, 10):
1079 number = 10 ** index
-> 1080 time_number = timer.timeit(number)
1081 if time_number >= 0.2:
1082 break
/opt/conda/lib/python3.5/site-packages/IPython/core/magics/execution.py in timeit(self, number)
158 gc.disable()
159 try:
--> 160 timing = self.inner(it, self.timer)
161 finally:
162 if gcold:

<magic-timeit> in inner(_it, _timer)

NameError: name 'a' is not defined

Estadística y aleatoridad
In [48]:
# Estadística
a = np.arange(10)

display(np.mean(a)) # promedio
display(np.median(a)) # mediana
4.5
4.5

In [49]:
np.percentile(a,40) # percentil
Out[49]:
3.6000000000000001

In [50]:
np.random.random(10) # Aleatoridad

Out[50]:
array([ 0.24532752, 0.19727378, 0.70780713, 0.77635632, 0.6175905 ,
0.17239969, 0.41967961, 0.66742302, 0.8488295 , 0.60224365])

11- CARGAR LOS DATOS NECESARIOS PARA EL PROYECTO

https://platzi.com/clases/1178-scikit/8835-cargar-los-dat-9/
5.7- PREPARACIÓN DE DATOS.IPYNB

In [1]:
# Importamos las librerias
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sb

In [2]:
# Esta linea permite que los graficos sean renderizados directamente en nuestro Notebook
## Carguemos en un pandas dataframe nuestra base de datos
%matplotlib inline
Carguemos en un pandas dataframe nuestra base de datos
pd.read_csv es el metodo que nos permite importar los datos desde un CSV y cargarlo en un **DataFrame**,
que es la estructura de base de Pandas

In [3]:
movies = pd.read_csv('../desktop/datasets/peliculas.csv',encoding='utf-8')

1. from google.colab import files # otra forma de abrir el archivo


upload = files.upload() 

In [4]:
type(movies)

Out[4]:
pandas.core.frame.DataFrame

In [5]:
movies.head()

Out[5]:
d la c
m tit c as du con dir act act act im
u n o cast_t
ov le o pe ra ten ect or_ or_ or_ bu db
r g u plot_keywo otal_fa gr
ie_ _y l ct_ tio genres t_ra or_ 1_n 2_n 3_n dg _sc
at u n rds ceboo oss
tit ea o rat n. tin na am am am et or
io a tr k_likes
le r r io 1 g me e e e e
n ge y
C Action| avatar| Jam CC Joel 23 76
1 We
Av 20 o En U 17 Adventu future| es H Dav 70 05
1.7 7 PG- s
0 at 09 l gli S 8. re| marine| Ca Pou id 4834 00 7.9 05
8 8. 13 Stu
ar .0 o sh A 0 Fantasy native| mer nde Mo 00 84
0 di
r |Sci-Fi paraplegic on r ore 0.0 7.0
1Pir 20 C 2.3 1 En U 16 Action| PG- goddess| Gor Joh Orl Jac 48350 30 7.1 30
at 07 o 5 6 gli S 9. Adventu 13 marriage e nny and k 00 94
es .0 l 9. sh A 0 re| ceremony| Ver Dep o Dav 00 04
of o 0 Fantasy marriage bins p Blo enp 00 15
th r proposal| ki om ort 0.0 2.0
e pi...
Ca
rib
be
an
:
At
W
orl
d la c
m tit c as du con dir act act act im
u n o cast_t
ov le o pe ra ten ect or_ or_ or_ bu db
r g u plot_keywo otal_fa gr
ie_ _y l ct_ tio genres t_ra or_ 1_n 2_n 3_n dg _sc
at u n rds ceboo oss
tit ea o rat n. tin na am am am et or
io a tr k_likes
le r r io 1 g me e e e e
n ge y
d's
En
d
Ste
C Sa Chr Ror 24 20
1 Action| bomb| pha
Sp 20 o En 14 m isto y 50 00
2.3 4 U Adventu PG- espionage| nie
2 ect 15 l gli 8. Me ph Kin 11700 00 6.8 74
5 8. K re| 13 sequel|spy| Sig
re .0 o sh 0 nde Wa nea 00 17
0 Thriller terrorist ma
r s ltz r 0.0 5.0
n
Th
e Jose
Chr
Da C deception| Chr ph 25 44
1 isto To
rk 20 o En U 16 imprisonme isti Gor 00 81
2.3 6 Action| PG- phe m 10675
3 Kn 12 l gli S 4. nt| an don 00 8.5 30
5 4. Thriller 13 r Har 9
ig .0 o sh A 0 lawlessness Bal - 00 64
0 Nol dy
ht r |police offi... e Lev 0.0 2.0
an
Ris itt
es
St
ar
W
ar
s:
Ep
iso
de
VII Dou Do
N N N N N Rob
- Na Na Docume Na g ug Na Na Na
4 a a a a a NaN Wa 143 7.1
Th N N ntary N Wal Wa N N N
N N N N N lker
e ker lker
Fo
rc
e
A
wa
ke
ns 
...
In [6]:
# Cuantas lineas y columnas tiene nuestro dataframe
### Un dataframe es una estructura de datos que se compone de los elementos siguientes
movies.shape
Out[6]:
(5043, 19)
Un dataframe es una estructura de datos que se compone de los elementos siguientes

In [7]:
#visualizemos las columnas
movies.columns
Out[7]:
Index(['movie_title', 'title_year', 'color', 'aspect_ratio', 'duration',
'language', 'country', 'duration.1', 'genres', 'content_rating',
'plot_keywords', 'director_name', 'actor_1_name', 'actor_2_name',
'actor_3_name', 'cast_total_facebook_likes', 'budget', 'imdb_score',
'gross'],
dtype='object')
In [8]:
movies.index
Out[8]:
RangeIndex(start=0, stop=5043, step=1)
In [9]:
columna1 = movies['movie_title']
columna1.head()
Out[9]:
0 Avatar 
1 Pirates of the Caribbean: At World's End 
2 Spectre 
3 The Dark Knight Rises 
4 Star Wars: Episode VII - The Force Awakens  ...
Name: movie_title, dtype: object
In [10]:
linea = movies.loc[10,:]
linea
Out[10]:
movie_title Batman v Superman: Dawn of Justice 
title_year 2016
color Color
aspect_ratio 2.35
duration 183
language English
country USA
duration.1 183
genres Action|Adventure|Sci-Fi
content_rating PG-13
plot_keywords based on comic book|batman|sequel to a reboot|...
director_name Zack Snyder
actor_1_name Henry Cavill
actor_2_name Lauren Cohan
actor_3_name Alan D. Purwin
cast_total_facebook_likes 24450
budget 2.5e+08
imdb_score 6.9
gross 3.30249e+08
Name: 10, dtype: object
In [11]:
movies.loc[:,'movie_title'].head()
Out[11]:
0 Avatar 
1 Pirates of the Caribbean: At World's End 
2 Spectre 
3 The Dark Knight Rises 
4 Star Wars: Episode VII - The Force Awakens  ...
Name: movie_title, dtype: object

12- INSPECCIÓN DE LOS DATOS

https://platzi.com/clases/1178-scikit/8836-inspeccion-de-los-tipos-de-datos/
Inspección de los tipos de datos
Datos importantes:
 La inspección de los datos se da para tener conocimiento de la salud de los datos que tenemos,
saber si vienen limpios o no, y también porque se quiere tener un entendimiento cuantitativo de ellos.
Parte de esto es mirar gráficos estadísticos y entender diferentes propiedades numéricas de las
columnas.
 A diferencia de Numpy, Pandas no solo permite cargar datos numéricos, sino también datos de
texto.
 El método info nos va a mostrar la cantidad completa de columnas con la cantidad de elementos no
nulos que hay en esas columnas, y por último muestra el tipo de cada columna.

Intentemos inspeccionar nuestros datos y entenderlos mejor


In [12]:
movies.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5043 entries, 0 to 5042
Data columns (total 19 columns):
movie_title 5043 non-null object
title_year 4935 non-null float64
color 5024 non-null object
aspect_ratio 4714 non-null float64
duration 5028 non-null float64
language 5031 non-null object
country 5038 non-null object
duration.1 5028 non-null float64
genres 5043 non-null object
content_rating 4740 non-null object
plot_keywords 4890 non-null object
director_name 4939 non-null object
actor_1_name 5036 non-null object
actor_2_name 5030 non-null object
actor_3_name 5020 non-null object
cast_total_facebook_likes 5043 non-null int64
budget 4551 non-null float64
imdb_score 5043 non-null float64
gross 4159 non-null float64
dtypes: float64(7), int64(1), object(11)
memory usage: 748.6+ KB
A diferencia de Numpy, Pandas permite cargar no solo datos numericos pero tambien **datos de texto** que
vemos por ejemplo en las columnas de actores y **mezclar distintos tipos de datos**.
 int64 y float64 corresponden a los mismos dtypes de Numpy
 object es el dtype que permite manejar datos de texto

In [13]:
# columnas númericas y columnas de texto
movies.dtypes == float
Out[13]:
movie_title False
title_year True
color False
aspect_ratio True
duration True
language False
country False
duration.1 True
genres False
content_rating False
plot_keywords False
director_name False
actor_1_name False
actor_2_name False
actor_3_name False
cast_total_facebook_likes False
budget True
imdb_score True
gross True
dtype: bool

In [14]:
movies.dtypes == int
Out[14]:
movie_title False
title_year False
color False
aspect_ratio False
duration False
language False
country False
duration.1 False
genres False
content_rating False
plot_keywords False
director_name False
actor_1_name False
actor_2_name False
actor_3_name False
cast_total_facebook_likes True
budget False
imdb_score False
gross False
dtype: bool
In [ ]:

In [15]:
movies.dtypes == object
Out[15]:
movie_title True
title_year False
color True
aspect_ratio False
duration False
language True
country True
duration.1 False
genres True
content_rating True
plot_keywords True
director_name True
actor_1_name True
actor_2_name True
actor_3_name True
cast_total_facebook_likes False
budget False
imdb_score False
gross False
dtype: bool

In [16]:
num = (movies.dtypes == float) | (movies.dtypes == int)
num
Out[16]:
movie_title False
title_year True
color False
aspect_ratio True
duration True
language False
country False
duration.1 True
genres False
content_rating False
plot_keywords False
director_name False
actor_1_name False
actor_2_name False
actor_3_name False
cast_total_facebook_likes True
budget True
imdb_score True
gross True
dtype: bool

In [17]:
num.index
Out[17]:
Index(['movie_title', 'title_year', 'color', 'aspect_ratio', 'duration',
'language', 'country', 'duration.1', 'genres', 'content_rating',
'plot_keywords', 'director_name', 'actor_1_name', 'actor_2_name',
'actor_3_name', 'cast_total_facebook_likes', 'budget', 'imdb_score',
'gross'],
dtype='object')

In [18]:
for el in num.index:
print(el)
movie_title
title_year
color
aspect_ratio
duration
language
country
duration.1
genres
content_rating
plot_keywords
director_name
actor_1_name
actor_2_name
actor_3_name
cast_total_facebook_likes
budget
imdb_score
gross

In [19]:
num_cols = [c for c in num.index if num[c]]
In [20]:
num_cols

Out[20]:
['title_year',
'aspect_ratio',
'duration',
'duration.1',
'cast_total_facebook_likes',
'budget',
'imdb_score',
'gross']

In [21]:
movies.dtypes == object
Out[21]:
movie_title True
title_year False
color True
aspect_ratio False
duration False
language True
country True
duration.1 False
genres True
content_rating True
plot_keywords True
director_name True
actor_1_name True
actor_2_name True
actor_3_name True
cast_total_facebook_likes False
budget False
imdb_score False
gross False
dtype: bool

In [22]:
obj = (movies.dtypes == object)
obj_cols = [c for c in obj.index if obj[c]]

In [23]:
obj_cols
Out[23]:
['movie_title',
'color',
'language',
'country',
'genres',
'content_rating',
'plot_keywords',
'director_name',
'actor_1_name',
'actor_2_name',
'actor_3_name']

In [24]:
num_cols
Out[24]:
['title_year',
'aspect_ratio',
'duration',
'duration.1',
'cast_total_facebook_likes',
'budget',
'imdb_score',
'gross']

In [25]:
movies_num = movies[num_cols]

In [26]:
# Estadísticas de las columnas númericas
movies_num.describe()
Out[26]:
title_yea aspect_r duration cast_total_faceboo imdb_sc
duration budget gross
r atio .1 k_likes ore
cou 4935.000 4714.000 5028.000 5028.000 4.551000e 5043.000 4.159000e
5043.000000
nt 000 000 000 000 +03 000 +03
me 2002.470 107.2010 107.2010 3.975262e 4.846841e
2.220403 9699.063851 6.442138
an 517 74 74 +07 +07
12.47459 25.19744 25.19744 2.061149e 6.845299e
std 1.385113 18163.799124 1.125116
9 1 1 +08 +07
1916.000 2.180000e 1.620000e
min 1.180000 7.000000 7.000000 0.000000 1.600000
000 +02 +02
25 1999.000 93.00000 93.00000 6.000000e 5.340988e
1.850000 1411.000000 5.800000
% 000 0 0 +06 +06
50 2005.000 103.0000 103.0000 2.000000e 2.551750e
2.350000 3090.000000 6.600000
% 000 00 00 +07 +07
75 2011.000 118.0000 118.0000 4.500000e 6.230944e
2.350000 13756.500000 7.200000
% 000 00 00 +07 +07
ma 2016.000 16.00000 511.0000 511.0000 1.221550e 7.605058e
656730.000000 9.500000
x 000 0 00 00 +10 +08
In [27]:
# Estadísticas de las columnas de texto
Para hacer nuestro primer modelo más simple para este trabajaremos solo con las columnas númericas.

In [28]:
movies_num['duration'].hist()
Out[28]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f22bfda24a8>

In [29]:
movies_num['imdb_score'].hist()
Out[29]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f22bfd3ea58>

In [30]:
movies_num['budget'].hist()
Out[30]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f22bfc60ba8>

Para poder debuggear esta situación utilizaremos una tecnica muy tipica de pandas que se llama **boolean
filtering**. Basicamente construimos una serie de booleanos con el mismo indice que nuestro dataframe (la
serie clasicamente la llamaremos mask).

In [31]:
mask = (movies_num['budget'] > 1e9)
In [32]:
movies[mask]
Out[32]:
d c
m tit c as du con dir act act act cast_t im
u la o
ov le o pe ra ten ect or_ or_ or_ otal_f bu db gr
r ng u plot_key
ie_ _y l ct_ tio genres t_ra or_ 1_n 2_n 3_n acebo dg _sc os
at ua n words
tit ea o rat n. tin na am am am ok_lik et or s
io ge tr
le r r io 1 g me e e e es e
n y
Pri
anime| Jad
nc
C cult Hay a 2.4 22
2 ess 1 Ja Ja Min Bill
19 o 13 Adventure| film| ao Pin 00 98
3 M 1.8 3 pa p PG- nie y
97 l 4. Animation forest| Miy ket 2710 00 8.4 19
2 on 5 4. ne a 13 Dri Cru
.0 o 0 |Fantasy princess aza t 0e+ 1.
3 on 0 se n ver dup
r |studio ki Smi 09 0
ok
ghibli th
e
2 St 20 C 1.8 1 Ja Ja 10 Action| PG- 19th Kat Wil Rob Ros 991 2.1 6.9 41
3 ea 04 o 5 0 pa p 3. Adventure| 13 century| suhi lia in alin 27 03
3 m .0 l 3. ne a 0 Animation ball| ro m Atk d 52 88
4 bo o 0 se n |Family| boy| Ôto Ho in Ayr 0e+ .0
y r Sci-Fi| inventor mo otki Do es 09
Thriller |steam ns wn
d c
m tit c as du con dir act act act cast_t im
u la o
ov le o pe ra ten ect or_ or_ or_ otal_f bu db gr
r ng u plot_key
ie_ _y l ct_ tio genres t_ra or_ 1_n 2_n 3_n acebo dg _sc os
at ua n words
tit ea o rat n. tin na am am am ok_lik et or s
io ge tr
le r r io 1 g me e e e es e
n y
es
S
o daughte
C Joo Ka 1.2 22
2 Th 1 ut Comedy| r|han Ah-
20 o Ko 11 n- Do ng- 21 01
9 e 1.8 1 h Drama| river| sun
06 l re 0. R ho ona ho 1173 55 7.0 41
8 Ho 5 0. K Horror| monster g
.0 o an 0 Bon Bae Son 0e+ 2.
8 st 0 or Sci-Fi |river| Ko
r g g 10 0
e seoul
a
H
C H bus| Ma Pét 2.5
3 1 u Laj Bál 19
Fa 20 o un 13 Drama| death| rcel er 00
0 2.3 3 n os int 58
tel 05 l ga 4. Romance| R gay slur| l Fan 11 00 7.1
0 5 4. g Kolt Pén 88
ess .0 o ri 0 War hatred| Na csik 0e+
5 0 a ai tek .0
r an jewish gy ai 09
ry
based on
C manga| Kat Tak 1.1
3 1 Ja Ja Mit Tes 43
19 o 12 Action| biker suhi esh 00
4 Ak 1.8 2 pa p suo shô 91
88 l 4. Animation R gang| ro i 28 00 8.1
2 ira 5 4. ne a Iwa Gen 62
.0 o 0 |Sci-Fi gifted Ôto Kus 0e+
3 0 se n ta da .0
r child| mo ao 09
post th...
S cake|
La
o christia Cha Hye
dy C 4.2
3 1 ut n| n- Min Yeo - 21
Ve 20 o Ko 11 00
8 2.3 1 h Crime| lesbian wo -sik ng- jeo 16
ng 05 l re 2. R 907 00 7.7
5 5 2. K Drama sex|oral ok Cho ae ng 67
ea .0 o an 0 0e+
9 0 or sex| Par i Lee Ka .0
nc r 09
e pregnan k ng
e
a t s...
13- INSPECCIÓN CUANTITATIVA Y DE SALUD DE LOS DATOS

Tenemos un problema de limpieza de los datos. La BDD fue creada sin diferenciar:
 La moneda en la que se ingresaba el presupuesto y el ingreso.
 La zona (país/mundial) en la que se registro el ingreso
In [33]:
# Importar BBDD thenumbers.com## Ahora manejaremos los datos faltantes (nulos o NaN).
In [34]:
pd.read_csv('../vol/datasets/thenumbers.csv')
Out[34]:
4341 rows × 8 columns

In [35]:
financials = pd.read_csv('../vol/datasets/thenumbers.csv')
In [36]:
financials = financials[['movie_title','production_budget','worldwide_gross']]
In [37]:
gross_opening = pd.read_csv('../vol/datasets/opening_df.csv')
In [38]:
financials.shape
Out[38]:
(4341, 3)
In [39]:
movies.shape
Out[39]:
(5043, 19)
In [40]:
movies['movie_title']
Out[40]:
0 Avatar 
1 Pirates of the Caribbean: At World's End 
2 Spectre 
3 The Dark Knight Rises 
4 Star Wars: Episode VII - The Force Awakens  ...
5 John Carter 
6 Spider-Man 3 
7 Tangled 
8 Avengers: Age of Ultron 
9 Harry Potter and the Half-Blood Prince 
10 Batman v Superman: Dawn of Justice 
11 Superman Returns 
12 Quantum of Solace 
13 Pirates of the Caribbean: Dead Man's Chest 
14 The Lone Ranger 
15 Man of Steel 
16 The Chronicles of Narnia: Prince Caspian 
17 The Avengers 
18 Pirates of the Caribbean: On Stranger Tides 
19 Men in Black 3 
20 The Hobbit: The Battle of the Five Armies 
21 The Amazing Spider-Man 
22 Robin Hood 
23 The Hobbit: The Desolation of Smaug 
24 The Golden Compass 
25 King Kong 
26 Titanic 
27 Captain America: Civil War 
28 Battleship 
29 Jurassic World 
...
5013 Manito 
5014 Rampage 
5015 Slacker 
5016 Dutch Kills 
5017 Dry Spell 
5018 Flywheel 
5019 Exeter 
5020 The Ridges 
5021 The Puffy Chair 
5022 Stories of Our Lives 
5023 Breaking Upwards 
5024 All Superheroes Must Die 
5025 Pink Flamingos 
5026 Clean 
5027 The Circle 
5028 Tin Can Man 
5029 The Cure 
5030 On the Downlow 
5031 Sanctuary; Quite a Conundrum 
5032 Bang 
5033 Primer 
5034 Cavite 
5035 El Mariachi 
5036 The Mongol King 
5037 Newlyweds 
5038 Signed Sealed Delivered 
5039 The Following 
5040 A Plague So Pleasant 
5041 Shanghai Calling 
5042 My Date with Drew 
Name: movie_title, dtype: object
In [41]:
movies_num
Out[41]:
5043 rows × 8 columns
In [42]:
movies_num = pd.concat([movies_num, movies['movie_title']],axis=1)
In [43]:
gross_opening = gross_opening.drop('Unnamed: 0',axis=1)
In [44]:
movies_v2 = pd.merge(financials,movies_num,on='movie_title',how='left')
In [45]:
movies_v2 = pd.merge(movies_v2,gross_opening,on='movie_title',how='left')
In [46]:
movies_v2.shape
Out[46]:
(4385, 13)
Ahora solucionaremos el problema de los datos faltantes (nulos o NaN).
Los datos faltantes generan problemas con muchos algoritmos de ML. Es por esto que existen distintas
estrategias para lidiar con ellos.
In [47]:
help(pd.Series.value_counts)
Help on function value_counts in module pandas.core.base:

value_counts(self, normalize=False, sort=True, ascending=False, bins=None, dropna=True)


Returns object containing counts of unique values.

The resulting object will be in descending order so that the


first element is the most frequently-occurring element.
Excludes NA values by default.

Parameters
----------
normalize : boolean, default False
If True then the object returned will contain the relative
frequencies of the unique values.
sort : boolean, default True
Sort by values
ascending : boolean, default False
Sort in ascending order
bins : integer, optional
Rather than count values, group them into half-open bins,
a convenience for pd.cut, only works with numeric data
dropna : boolean, default True
Don't include counts of NaN.

Returns
-------
counts : Series
In [48]:
movies_v2.notnull().apply(pd.Series.value_counts)
Out[48]:
movi producti worldwi title aspec dur dura bu imdb gr openin scr
cast_total_fa
e_titl on_budge de_gros _yea t_rati atio tion. dg _scor os g_gros een
cebook_likes
e t s r o n 1 et e s s s
Fa
33 67 216
ls NaN NaN NaN 27 274 13 13 NaN NaN 2106
5 1 4
e
Tr 4385. 435 437 40 4385. 37 222
4385.0 4385.0 4111 4372 4385.0 2279
ue 0 8 2 50 0 14 1
In [49]:
(movies_v2 != 0).apply(pd.Series.value_counts)
Out[49]:
movi producti worldwi title aspec dur dura bu imdb gr openin scr
cast_total_fa
e_titl on_budg de_gros _yea t_rati atio tion. dg _scor os g_gros een
cebook_likes
e et s r o n 1 et e s s s
Fa
Na Na Na
ls NaN NaN 281 NaN NaN NaN NaN 27 NaN NaN
N N N
e
43 43
Tr 4385. 438 4385. 438 4385. 4385. 438
4385.0 4104 4358 85. 85. 4385.0
ue 0 5.0 0 5.0 0 0 5.0
0 0
In [50]:
available = ((movies_v2 != 0) & (movies_v2.notnull()))
In [51]:
available.all(axis=1).value_counts()
Out[51]:
False 2252
True 2133
dtype: int64
No podemos entrenar nuestro algoritmo con datos cuya variable objetivo no esta definida o sea nula (valor
falso). Eliminemos esas líneas.
In [52]:
mask = available['worldwide_gross']
In [53]:
movies_v2 = movies_v2[mask]
In [54]:
((movies_v2 != 0) & (movies_v2.notnull())).worldwide_gross.value_counts()
Out[54]:
True 4104
Name: worldwide_gross, dtype: int64
En el caso de las features que no son la variable objetivo una mejor solución para lidiar con los datos
faltantes es remplazar estos datos por otros que sean manejables y no afecten la calidad de las
predicciones. La estrategia más comun es utilizar la media de todos los ejemplos para la feature dada.
In [55]:
movies_v2 = movies_v2.drop('movie_title',axis=1)
In [56]:
movies_v2 = movies_v2.drop('duration',axis=1)
In [57]:
movies_v2 = movies_v2.drop('gross',axis=1)
In [58]:
movies_v2.head()
Out[58]:
production worldwid title_ aspect_ durati cast_total_face imdb_ opening scre
budget
_budget e_gross year ratio on.1 book_likes score _gross ens
27839189 2009. 237000 7702548 345
0 425000000 1.78 178.0 4834 7.9
82 0 000.0 1.0 2.0
20586622
1 306000000 NaN NaN NaN 143 NaN 7.1 NaN NaN
25
96342042 2007. 300000 1398021 436
2 300000000 2.35 169.0 48350 7.1
5 0 000.0 90.0 2.0
87962092 2015. 245000 7040314 392
3 300000000 2.35 148.0 11700 6.8
3 0 000.0 8.0 9.0
10844390 2012. 250000 1608872 440
4 275000000 2.35 164.0 106759 8.5
99 0 000.0 95.0 4.0
In [59]:
movies_v2 = movies_v2[available.screens]
/opt/conda/lib/python3.5/site-packages/ipykernel_launcher.py:1: UserWarning: Boolean Series key will be
reindexed to match DataFrame index.
"""Entry point for launching an IPython kernel.

In [62]:
len(movies_v2)
Out[62]:
2221

In [61]:
from sklearn.preprocessing import Imputer
imputer = Imputer(missing_values=np.nan, strategy='mean')

In [63]:
values = imputer.fit_transform(movies_v2)
X = pd.DataFrame(values)
X.columns = movies_v2.columns
X.index = movies_v2.index
X.head()
Out[63]:
production worldwid title_ aspect_ durati cast_total_face imdb_ opening scre
budget
_budget e_gross year ratio on.1 book_likes score _gross ens
425000000. 2.783919e 2009. 237000 7702548 345
0 1.78 178.0 4834.0 7.9
0 +09 0 000.0 1.0 2.0
300000000. 9.634204e 2007. 300000 1398021 436
2 2.35 169.0 48350.0 7.1
0 +08 0 000.0 90.0 2.0
production worldwid title_ aspect_ durati cast_total_face imdb_ opening scre
budget
_budget e_gross year ratio on.1 book_likes score _gross ens
300000000. 8.796209e 2015. 245000 7040314 392
3 2.35 148.0 11700.0 6.8
0 +08 0 000.0 8.0 9.0
275000000. 1.084439e 2012. 250000 1608872 440
4 2.35 164.0 106759.0 8.5
0 +09 0 000.0 95.0 4.0
275000000. 2.600021e 2013. 215000 2921084 390
5 2.35 150.0 45757.0 6.5
0 +08 0 000.0 9.0 4.0
In [64]:
len(X)
Out[64]:
2221
In [61]:
movies_v2.values
Out[61]:
array([[ 4.25000000e+08, 2.78391898e+09, 2.00900000e+03, ...,
7.90000000e+00, 7.70254810e+07, 3.45200000e+03],
[ 3.06000000e+08, 2.05866222e+09, nan, ...,
7.10000000e+00, nan, nan],
[ 3.00000000e+08, 9.63420425e+08, 2.00700000e+03, ...,
7.10000000e+00, 1.39802190e+08, 4.36200000e+03],
...,
[ 7.00000000e+03, 9.00000000e+02, 2.00500000e+03, ...,
7.80000000e+00, nan, nan],
[ 3.96700000e+03, 1.04430000e+04, 2.01200000e+03, ...,
6.30000000e+00, nan, nan],
[ 1.10000000e+03, 1.81041000e+05, 2.00400000e+03, ...,
6.60000000e+00, nan, nan]])
In [62]:
values
Out[62]:
array([[ 4.25000000e+08, 2.78391898e+09, 2.00900000e+03, ...,
7.90000000e+00, 7.70254810e+07, 3.45200000e+03],
[ 3.06000000e+08, 2.05866222e+09, 5.91165594e+08, ...,
7.10000000e+00, 5.91165594e+08, 5.91165594e+08],
[ 3.00000000e+08, 9.63420425e+08, 2.00700000e+03, ...,
7.10000000e+00, 1.39802190e+08, 4.36200000e+03],
...,
[ 7.00000000e+03, 9.00000000e+02, 2.00500000e+03, ...,
7.80000000e+00, 1.90568571e+03, 1.90568571e+03],
[ 3.96700000e+03, 1.04430000e+04, 2.01200000e+03, ...,
6.30000000e+00, 2.70237857e+03, 2.70237857e+03],
[ 1.10000000e+03, 1.81041000e+05, 2.00400000e+03, ...,
6.60000000e+00, 2.31883063e+04, 2.31883063e+04]])
In [65]:
X.to_csv('../vol/intermediate_results/X_opening.csv',index=False)

In [68]:
pd.Series(X.index).apply(lambda x: inv_map.loc[x])

NameErrorTraceback (most recent call last)


<ipython-input-68-27d06730cdf2> in <module>()
----> 1 pd.Series(X.index).apply(lambda x: inv_map.loc[x])

/opt/conda/lib/python3.5/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args,


**kwds)
2292 else:
2293 values = self.asobject
-> 2294 mapped = lib.map_infer(values, f, convert=convert_dtype)
2295
2296 if len(mapped) and isinstance(mapped[0], Series):

pandas/src/inference.pyx in pandas.lib.map_infer (pandas/lib.c:66124)()

<ipython-input-68-27d06730cdf2> in <lambda>(x)
----> 1 pd.Series(X.index).apply(lambda x: inv_map.loc[x])

NameError: name 'inv_map' is not defined


In [ ]:
X.to_csv('../vol/intermediate_results/X.csv',index=False)

5.8 PRIMERA ITERACION – MODELAMIENTO Y EVALUACIÓN IPYNB

Antes de entrenar un modelo, aprendamos sobre el funcionamiento y la API de scikit-learn


In [3]:
import numpy as np
import pandas as pd
Scikit-learn es la librería más usada de Machine Learning tradicional [Ver ranking de Github]
(https://github.com/showcases/machine-learning). La librería incluye funcionalidades de:
 Preprocesamiento de datos en  sklearn.preprocessing
 Algoritmos de Machine Learning en sklearn.linear_model, sklearn.svm, sklearn.ensemble, y muchos
más.
 Evaluación de modelos en sklearn.model_selection y sklearn.metrics
Scikit-learn sigue muy de cerca los resultados de la investigación e implementa los resultados más maduros
y probados en sus modulos. La [documentación](http://scikit-
learn.org/stable/modules/ensemble.html#forests-of-randomized-trees) extensa muestra como la librería es
un compendio de conocimiento en Machine Learning llevado a software
Una estructura de datos esencial en scikit-learn es el Estimator
Para poder escoger el estimator apropiado una excelente guia es el cheatsheet siguiente, hecho por uno de
los core-dev de scikit-learn.

Implementemos un modelo simple de regresión primero


In [4]:
X = pd.read_csv('../vol/intermediate_results/X.csv')
In [5]:
y = X['worldwide_gross']
In [6]:
X = X.drop('worldwide_gross',axis=1)
In [9]:
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.4,random_state=1)


In [10]:
print(len(X))
print(len(X_train))
print(len(X_test))
4104
2462
1642
In [11]:
X.head(1)
Out[11]:
production_bud title_ye aspect_rat duration. cast_total_facebook_li imdb_sco
budget
get ar io 1 kes re
237000000
0 425000000.0 2009.0 1.78 178.0 4834.0 7.9
.0
In [12]:
from sklearn.linear_model import Lasso

model = Lasso()
In [13]:
model.fit(X_train,y_train)
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:491:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
Out[13]:
Lasso(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute=False, random_state=None,
selection='cyclic', tol=0.0001, warm_start=False)
In [13]:
predicted = model.predict(X_test)
In [15]:
predicted.shape
Out[15]:
(1642,)
In [19]:
import matplotlib.pyplot as plt
%matplotlib inline

plt.hist([predicted,y_test]);

Evaluemos de forma más fina el comportamiento de nuestro modelo


Los estimadores y las funciones de sklearn vienen con el máximo de argumentos con valores por defecto que
suelen ser las mejores opciones si no tenemos algun conocimiento particular el problema. En este caso
particular la función estimator.score ya viene con una de las métricas de sklearn.metrics, que es la
métrica sklearn.metric.r2_score
El score R2 de una regresión es una de las formas más comunes de entender su poder predictivo.
Este mientras más cerca de 1 este, mejor es
Los valores que puede tomar son de -infinito hasta 1. Un score R2 negativo es malo, ya que esto indica que la
regresión es peor que si simplemente eligieramos un valor fijo como predicción para todos los puntos, la
media.
In [14]:
model.score(X_test,y_test)
Out[14]:
0.6021797062956975
Bastante bien para un primer modelo!
Un buen score R2 es importante para una regresión. Pero no lo es todo. De forma general los scores hay que
complementarlos con visualizaciones de los datos ya que una métrica no logra siempre encodear todas las
caracteristicas de una distribución de probabilidades. Un ejemplo es el siguiente:

Siempre visualiza tus resultados, aunque tengas un buen score de performance.


In [22]:
residuals = y_test - predicted
In [23]:
plt.scatter(y_test,residuals)
Out[23]:
<matplotlib.collections.PathCollection at 0x7f3f6930fd30>

In [24]:
ap_residuals = np.abs(residuals) / y_test
In [25]:
plt.scatter(y_test,ap_residuals)
Out[25]:
<matplotlib.collections.PathCollection at 0x7f3f6927b048>

In [26]:
lap_residuals = np.log(ap_residuals)
In [28]:
plt.scatter(y_test,lap_residuals)
Out[28]:
<matplotlib.collections.PathCollection at 0x7f3f691be1d0>

In [30]:
plt.hist(lap_residuals,bins=100, normed=1, histtype='step', cumulative=True);

In [32]:
plt.hist(lap_residuals, bins=100, normed=1, histtype='step',cumulative=True);
plt.axis([-2,0,0,1])
np.power(np.exp(1)*np.ones(5),np.linspace(-2,0,5))
Out[32]:
array([ 0.13533528, 0.22313016, 0.36787944, 0.60653066, 1. ])

In [44]:
plt.scatter(np.arange(8),model.coef_)
Out[44]:
<matplotlib.collections.PathCollection at 0x7f3f68fb8b00>

In [79]:
X = pd.read_csv('../vol/intermediate_results/X.csv')
In [78]:
X = X.drop('gross',axis=1)
In [80]:
X = X.drop('worldwide_gross',axis=1)
In [81]:
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.4)


In [82]:
model = Lasso()
model.fit(X_train,y_train)
Out[82]:
Lasso(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute=False, random_state=None,
selection='cyclic', tol=0.0001, warm_start=False)
In [83]:
model.score(X_test,y_test)
Out[83]:
0.87745681705925049
In [87]:
X.columns
Out[87]:
Index(['production_budget', 'title_year', 'aspect_ratio', 'duration.1',
'cast_total_facebook_likes', 'budget', 'imdb_score', 'gross'],
dtype='object')
In [92]:
for el in zip(list(X.columns),list(model.coef_)):
print(el)
('production_budget', 0.76287929242158148)
('title_year', 0.82847598230185637)
('aspect_ratio', 0.3963785144996036)
('duration.1', 1.5849161930072848)
('cast_total_facebook_likes', -218.60395867759215)
('budget', 0.0031745843702155035)
('imdb_score', 4426444.4687358243)
('gross', 2.1308279122355804)

5.9- COMO DISEÑAR BUENAS FEATURES Y MALDICON DE LA DIMENSION .IPYNB

Mejorar la performance de nuestros modelos no solo pasa por optimizar sus parametros.
Una de las partes clave, y según algunos expertos la más importante, es la de **diseñar la representación en
la que se entregan los datos a los modelos** para que estos los procesen.
Esto equivale, en palabras más simples, en definir de forma inteligente las features (columnas) de nuestras
tablas de datos.
Ejemplo de feature engineering:
El problema:
Supongamos que estamos tratando de resolver el problema siguiente.
 Tenemos un problema de reconocer si ciertos datos con una sola feature son de una clase 1 o de una
clase 2 (por ejemplo "el producto esta deficiente" o "el producto esta funcional").
 Por lo tanto estamos resolviendo una clasificación.
 Para esta clasificación decidimos tomar un SVM, que es un modelo poderoso que funciona buscando
la "mejor" recta que separa los puntos de cada clase.

Como podemos ver no existe un separador óptimo. Debemos para resolver el problema buscar un modelo
aún más poderoso? No necesariamente.

Agregemos una nueva feature:


Claramente con esta nueva feature vemos que existe una recta que separa los espacios de puntos.
Esta recta tendra un score ampliamente mejor que cualquier solucion al primer problema.
Principios de diseño de Features
Diseñar tus features es un arte más que una ciencia (por lo que en general te recomendamos ganar
experiencia leyendo articulos cientificos y viendo soluciones
1. Features Informativas: Tus features son más utiles mientras más correlación tengan tu variable
objetivo.
2. Features Independientes: Para no tener redudancias tus features deberían ser lo más
independientes posible entre ellas.
3. Cantidad de Features controlada: Nuestra intuición nos falla en dimensiones superiores a 3 (ver
video maldicion de la dimensionalidad). En la mayoría de los casos aumentar la cantidad de features
afecta negativamente la performance si no contamos con una gran cantidad de datos. Por ultimo
pocas features aseguran una mejor interpretabilidad de los modelos
Ejemplo de Feature informativa y Feature no informativa
Predecir el **precio de una casa** en **función de sus metros cuadrados**.
Predecir el **precio de una casa** en **función de la temperatura del mar**.
Es importante entender la correlación entre la feature y la variable objetivo. Más sobre esto en los siguientes
videos.
Visualizar interdepencia entre variables
In [4]:
import pandas as pd
X = pd.read_csv('../vol/intermediate_results/X.csv').drop('worldwide_gross',axis=1)
In [6]:
import seaborn as sns
%matplotlib inline

sns.heatmap(X.corr())
Out[6]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f4ff97f7198>
La maldición de la dimensión

Datasaurus Dozen y Anscombe's quartet:


Utilidad de la capacidad de entender los datos en 1, 2 y 3 dimensiones del ojo humano.
Maldición de la dimensionalidad:
En dimensión superior o igual a 4, nuestra capacidad de entender los datos se pierde, y aún peor
fenomenos extraños/contraproducentes ocurren

Ejemplo 1
Que largo debe tener cada arista de un hypercubo de dimension p que capture 10% del volumen de un
hypercubo de volumen 1 que lo contiene?

$$ V_{hypercubo} = a^p\ y\ si\ V_{hypercubo} = 0.1 \implies a = 0.1^{1/p}$$$$$$


In [7]:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(1,15)
y = np.power(0.1,1/x)
plt.plot(x,y)
Out[7]:
[<matplotlib.lines.Line2D at 0x7f4ff5e73438>]

En dimensión 10: Necesitamos un hypercubo que cubra 80% de cada una de las aristas para solamente
obtener 10% del volumen!
En alta dimensión es muy poco probable que tus ejemplos cubran todo el espacio de forma densa.
Por ende en **alta dimensión necesitas una cantidad de datos que crece exponencialmente para poder
entrenar tus modelos**.
Te recomendamos tener cuidado al aumentar la dimensión de tus datos, no esta prohibido, pero hacerlo de
forma exagerada te puede llevar hacia estos problemas.

5.10 ANALISIS Y SELECCIÓN DE FEATURES.IPYNB


In [1]:
import warnings
warnings.simplefilter("ignore")
In [2]:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
Feedback de tus modelos
Ciertos modelos como la regresión o los arboles se dicen **"interpretables"**. Esto quiere decir que de los
resultados de los modelos podemos sacar conclusiones o **"insights"**.
En particular la regresión Lasso es interpretable:
 mientras más grande el coeficiente para una feature, más relevante es esta para la regresión.
 la regresión Lasso trata de seleccionar un pequeño número de features relevantes.
In [3]:
X = pd.read_csv('../vol/intermediate_results/X.csv')

y = X['worldwide_gross']
X = X.drop('worldwide_gross',axis=1)
In [4]:
from sklearn.linear_model import Lasso

model = Lasso()
In [5]:
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X,y)


In [7]:
len(X_train)/len(X)
Out[7]:
0.75
In [8]:
model.fit(X_train,y_train)
Out[8]:
Lasso(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute=False, random_state=None,
selection='cyclic', tol=0.0001, warm_start=False)
In [9]:
model.score(X_test,y_test)
Out[9]:
0.53670649813230509
In [12]:
model.coef_
Out[12]:
array([ 2.89526507e+00, -1.40301472e+00, 1.66308214e-02,
3.33819964e+00, 2.15878265e+02, -8.00752044e-03,
2.53750354e+07])
In [15]:
var = np.floor(np.log10(np.abs(model.coef_)))
In [17]:
plt.rcParams["figure.figsize"] = [12,8]
plt.plot(var)
plt.xticks(np.arange(7),list(X.columns));

Esto nos guía a guardar únicamente:


 production_budget
 title_year
 duration
 cast_total_facebook_likes
 imdb_score
Correlación entre variables
In [18]:
import seaborn as sns

Z = pd.concat([X,y],axis=1)
sns.pairplot(Z)
Out[18]:
<seaborn.axisgrid.PairGrid at 0x7faf37e93400>

In [28]:
clase = pd.cut(X['production_budget'],8).cat.codes.rename('class')
Z2 = pd.concat([X,clase],axis=1)
In [29]:
sns.pairplot(Z2,hue='class')
Out[29]:
<seaborn.axisgrid.PairGrid at 0x7faf37ebc748>

In [31]:
Z3 = pd.concat([X,y],axis=1)
sns.heatmap(Z3.corr())
Out[31]:
<matplotlib.axes._subplots.AxesSubplot at 0x7faf2191fe10>

De esto concluimos, sin sorpresa, que son muy importantes:


 production_budget
 imdb_score
Metodos de selección automatica de features
Sklearn posee una serie de métodos para seleccionar las mejores features. Estos métodos los puedes
encontrar en sklearn.feature_selection
In [32]:
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import mutual_info_regression

selector = SelectKBest(mutual_info_regression, k=4)


selector.fit(X,y)
Out[32]:
SelectKBest(k=4,
score_func=<function mutual_info_regression at 0x7faf38ed7730>)
In [34]:
scores = selector.scores_
plt.rcParams["figure.figsize"] = [12,8]
plt.plot(scores)
plt.xticks(np.arange(7),list(X.columns));

Del analisis univariante obtenemos que las mejores features son:


 production_budget
 cast_total_facebook_likes
 budget
Guardaremos las 5 features entregadas por la interpretación de nuestra regresión Lasso
In [35]:
X2 = X[['production_budget','title_year','duration.1','cast_total_facebook_likes','imdb_score']]
X3 = X[['production_budget','cast_total_facebook_likes','imdb_score']]
Veamos los resultados del modelo con estas features
In [36]:
X_train, X_test, y_train, y_test = train_test_split(X,y)
In [37]:
cols2 = ['production_budget','title_year','duration.1','cast_total_facebook_likes','imdb_score']
X2_train, X2_test, y2_train, y2_test = X_train[cols2], X_test[cols2], y_train, y_test

cols3 = ['production_budget','cast_total_facebook_likes','imdb_score']
X3_train, X3_test, y3_train, y3_test = X_train[cols3], X_test[cols3], y_train, y_test
In [40]:
from sklearn.linear_model import Lasso

model1 = Lasso()
model2 = Lasso()
model3 = Lasso()

model1.fit(X_train,y_train)
model2.fit(X2_train,y2_train)
model3.fit(X3_train,y3_train)
Out[40]:
Lasso(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute=False, random_state=None,
selection='cyclic', tol=0.0001, warm_start=False)
In [41]:
print(model1.score(X_test,y_test))
print(model2.score(X2_test,y2_test))
print(model3.score(X3_test,y3_test))
0.588827166128
0.5887559341
0.564313646779
5.11- CREACIÓN Y TRANSFORMACIÓN DE FEATURES.IPYNB
In [ ]:
import warnings
warnings.simplefilter("ignore")
Escalamiento de los datos
In [ ]:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
Diversos algoritmos son sensibles a la escala en la que viene cada feature. **Re-escalarlos** puede traer
significativas mejoras de rendimiento.
Existen distintas estrategias de escalamiento de tus features, pero la más común es la
estandarización donde convertimos la variable para que la distribución de esta siga una distribución que
es Gaussiana de media 0 y de desviación estandar 1.
In [28]:
from sklearn.model_selection import train_test_split

X = pd.read_csv('../vol/intermediate_results/X.csv')
y = X['worldwide_gross']
X = X.drop('worldwide_gross',axis=1)
X_train, X_test, y_train, y_test = train_test_split(X,y)
In [ ]:
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(X_train)
In [ ]:
scaler.mean_
In [ ]:
scaler.scale_
In [ ]:
X.values
In [ ]:
scaler.transform(X_train)
In [ ]:
X_train_scaled, X_test_scaled = (scaler.transform(X_train), scaler.transform(X_test))
In [ ]:
from sklearn.linear_model import Lasso

model = Lasso()
model_scaled = Lasso()

model.fit(X_train,y_train)
model_scaled.fit(X_train_scaled,y_train)
In [ ]:
print(model.score(X_test,y_test))
print(model_scaled.score(X_test_scaled,y_test))
Los modelos de regresión no se ven afectados por el escalamiento de las features. Los de clasificación sí.
Simplificar las transformaciones con pipelines
Para hacer tu código más reproducible, y para evitar tener que aplicar multiples veces una misma
transformación te recomendamos utilizar  sklearn.pipeline.make_pipeline  que permite encadenar
transformaciones a tus modelos.
In [ ]:
from sklearn.pipeline import make_pipeline

model_scaled = make_pipeline(StandardScaler(),
Lasso())

model_scaled.fit(X_train,y_train)
In [ ]:
print(model_scaled.score(X_test,y_test))
Crear nuevas features de forma automática
In [ ]:
A = np.arange(6).reshape(3, 2)
A
In [ ]:
from sklearn.preprocessing import PolynomialFeatures

transformer = PolynomialFeatures(2)
transformer.fit_transform(A)

PolynomialFeatures transforma una matriz   a 


In [ ]:
X.shape
In [ ]:
transformer = PolynomialFeatures(2)
transformer.fit_transform(X).shape
In [25]:
model_poly = make_pipeline(PolynomialFeatures(2),
Lasso())
model_poly.fit(X_train,y_train)
model_poly.score(X_test,y_test)
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:484:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
Out[25]:
-7401097975.623044
In [27]:
model = Lasso()
model.fit(X_train,y_train)
model.score(X_test,y_test)
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:484:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
Out[27]:
0.57593747144784135
Crear features categóricas
En terminos de Machine Learning a las features que pueden tomar un número finito de valores se les llama
categóricas. Ejemplos para esto són: género, páis, grado académico, etc.

Un mapeo del tipo   tiene el problema de asignarle un ordén a los valores posibles de la categoría. Este
orden impacta de distintas maneras los algoritmos de Machine Learning, por ejemplo aquellos que
dependen de la topología de   y de la función de distancia entre puntos en este espacio, considerarán
que ciertas categorías se encuentran más cercanas unas de otras, siendo que esto es generado puramente
artificialmente por el encoding, y no por las datos per se.
Para no introducir información falsa o erronéa en nuestro modelos existen formas más inteligentes de
encodear nuestros datos.
Encoding one-hot
Este encoding consiste en asignarle una columna a cada categoría y rellenarla con 0 y 1 de la forma
siguiente:
In [29]:
d = pd.DataFrame([['Chile','Colombia','Colombia','Venezuela'],['hombre','mujer','hombre','mujer']])
d = d.T
d.columns = pd.Index(['pais','genero'])
d
Out[29]:
gener
pais
o
hombr
0 Chile
e
1 Colombia mujer
hombr
2 Colombia
e
Venezuel
3 mujer
a
In [30]:
pd.get_dummies(d)
Out[30]:
pais_Chil pais_Colombi pais_Venezuel genero_hombr genero_muje
e a a e r
0 1 0 0 1 0
1 0 1 0 0 1
2 0 1 0 1 0
3 0 0 1 0 1
Sklearn también ofrece un objeto OneHotEncoder pero es un poco más díficil de utilizar, así que por criterios
pedagogicos hemos elegido pd.get_dummies. Sin embargo el objeto de sklearn tiene la ventaja de ser
pipeable, por lo que es bueno considerarlo para ciertos casos de uso.
Cuantas columnas generaríamos con un one-hot encoding de nuestras features categóricas?
In [31]:
movies_obj = pd.read_csv('../vol/intermediate_results/movies_obj.csv')
In [33]:
movies_obj.apply(pd.Series.nunique).sort_values()
Out[33]:
color 2
content_rating 18
language 47
country 65
genres 914
actor_1_name 2097
director_name 2398
actor_2_name 3032
actor_3_name 3521
plot_keywords 4760
movie_title 4917
dtype: int64
Las features más informativas son las del casting. Si embargo haciendo un one-hot encoding de estas
estaríamos aumentando la dimensión por 2000 y algo!!
Encoding Binario
Esta técnica no es canónica por lo que tendremos que buscarla en otra librería. Sin embargo el autor tuvo la
buena idea de hacer su API compatible con la de sklearn, así que no tendremos ninguna dificultad en usarla.

In [34]:
!pip install category_encoders
Requirement already satisfied: category_encoders in /opt/conda/lib/python3.5/site-packages
Requirement already satisfied: scikit-learn>=0.15.0 in /opt/conda/lib/python3.5/site-packages (from
category_encoders)
Requirement already satisfied: scipy>=0.9 in /opt/conda/lib/python3.5/site-packages (from
category_encoders)
Requirement already satisfied: statsmodels>=0.6.0 in /opt/conda/lib/python3.5/site-packages (from
category_encoders)
Requirement already satisfied: numpy>=1.8.0 in /opt/conda/lib/python3.5/site-packages (from
category_encoders)
Requirement already satisfied: pandas>=0.15.0 in /opt/conda/lib/python3.5/site-packages (from
category_encoders)
Requirement already satisfied: patsy>=0.4.0 in /opt/conda/lib/python3.5/site-packages (from
category_encoders)
Requirement already satisfied: python-dateutil>=2 in /opt/conda/lib/python3.5/site-packages (from
pandas>=0.15.0->category_encoders)
Requirement already satisfied: pytz>=2011k in /opt/conda/lib/python3.5/site-packages (from
pandas>=0.15.0->category_encoders)
Requirement already satisfied: six in /opt/conda/lib/python3.5/site-packages (from patsy>=0.4.0-
>category_encoders)
In [35]:
categoricals = pd.read_csv('../vol/intermediate_results/categoricals.csv').set_index('Unnamed: 0')
In [36]:
categoricals.head(2)
Out[36]:
actor_1_nam director_nam
e e
Unnamed:
0
James
0 CCH Pounder
Cameron
1 Doug Walker Doug Walker
In [37]:
categoricals = categoricals.reset_index(drop=True).fillna(0)
In [38]:
X_binenc = pd.concat([X,categoricals],axis=1)
In [39]:
X_binenc.head()
Out[39]:
production_ title_yea aspect_r duratio cast_total_faceb imdb_s actor_1_ director_
budget
budget r atio n.1 ook_likes core name name
425000000. 2.00900 1.78000 1.78000 2.37000 CCH James
0 4834.0 7.9
0 0e+03 0e+00 0e+02 0e+08 Pounder Cameron
306000000. 5.91165 5.91165 5.91165 5.91165 Doug Doug
1 143.0 7.1
0 6e+08 6e+08 6e+08 6e+08 Walker Walker
300000000. 2.00700 2.35000 1.69000 3.00000 Johnny Gore
2 48350.0 7.1
0 0e+03 0e+00 0e+02 0e+08 Depp Verbinski
300000000. 2.01500 2.35000 1.48000 2.45000 Christop Sam
3 11700.0 6.8
0 0e+03 0e+00 0e+02 0e+08 h Waltz Mendes
275000000. 2.01200 2.35000 1.64000 2.50000 Tom Christoph
4 106759.0 8.5
0 0e+03 0e+00 0e+02 0e+08 Hardy er Nolan
In [40]:
import category_encoders as ce
encoder = ce.BinaryEncoder(cols=['actor_1_name','director_name'])
In [42]:
encoder.fit_transform(X_binenc).shape
Out[42]:
(4104, 29)
In [43]:
X_binenc = encoder.fit_transform(X_binenc)
In [44]:
Xb_train, Xb_test, y_train, y_test = train_test_split(X_binenc,y)
In [45]:
X_train, X_test = (Xb_train[X.columns],Xb_test[X.columns])
In [46]:
model_binenc = Lasso()
model = Lasso()
In [47]:
model_binenc.fit(Xb_train,y_train)
model.fit(X_train,y_train)
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:484:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
Out[47]:
Lasso(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute=False, random_state=None,
selection='cyclic', tol=0.0001, warm_start=False)
In [48]:
print(model_binenc.score(Xb_test,y_test))
print(model.score(X_test,y_test))
0.623169426585
0.624091664736
Aumentamos el rendimiento de nuestro algoritmo pero no de forma significativa. Mantengamos entonces la
dimensionalidad de nuestro espacio de features baja, y vamos a buscar modelos más complejos.
Conocimiento experto
Una grán parte del diseño de las features pasa por un **conocimiento espécifico del dominio en el que se
esta trabajando**.
Por ejemplo para analizar una imagen nuestro cerebro no se concentra en los millones de pixeles de una
imagen, pero sólo en algunos relevantes como los de los contornos. Durante un buen tiempo **los sistemas
de visión de computadores encodeaban features que traducían este conocimiento experto (contornos).**
Una de las únicas formas de obtener este conocimiento de forma sistemática es ir a bucear en repositorios
de papers de Machine Learning como Arxiv, y estudiar la investigación que se ha hecho sobre el dominio
específico.
Más datos de calidad
Nada le gana conseguir más datos que sean encodeables en features de calidad.
Píramide de Maslow del Machine Learning

Contamos con la base de datos de ganancias de las péliculas el primer fin de semana de exhibición, así como
la cantidad de cines en la que fue estrenada.
In [49]:
pd.read_csv('../vol/datasets/opening_df.csv').head()
Out[49]:
Unnamed: opening_gros screen
movie_title
0 s s
0 0 10 Days in a Madhouse 2451.0 10.0
10 Things I Hate About
1 1 8330681.0 2271.0
You
2 2 102 Dalmatians 19883351.0 2704.0
Unnamed: opening_gros screen
movie_title
0 s s
3 3 12 Rounds 5329240.0 2331.0
4 4 12 Years a Slave 923715.0 19.0
Puedes mejorar considerablemente nuestra predicción?

5.11- CROOS VALIDATION Y SELECCIÓN DE MODELOS.IPYNB


In [ ]:
import warnings
warnings.simplefilter("ignore")
In [1]:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
Métodos de evaluación
Por ahora hemos visto que:
 Se necesita separar de forma aleatoria en datos de entrenamiento y testeo para poder evaluar
performance del algoritmo
 Existen diversas métricas para evaluar rendimiento, y elegimos la nuestra según las
caracteristicas de nuestro problema
 Es útil apoyar la evaluación con visualizaciones de errores, como por ejemplo scatterplots de
residuales
Sin embargo nuestro método hasta ahora tiene una falla. Este depende de la forma en que fueron elegidos
nuestros datos de forma aleatoria:
 Podemos tener suerte y caer en un train set y test set que sea ideal para nuestro modelo.
 Podemos tener pésima performance con esa separación de datos pero no en otros.
Controlar la aleatoridad en train_test_split
train_test_split separa cada vez que lo llamamos los datos de forma diferente. Para poder comparar
modelos, hacer un código más limpio y compacto y para poder hacer nuestros experimentos reproducibles
utilizaremos el parametro random_state.
In [2]:
X = pd.read_csv('../vol/intermediate_results/X_opening.csv')
y = X['worldwide_gross']
X = X.drop('worldwide_gross',axis=1)
In [8]:
from sklearn.model_selection import train_test_split

X_train,X_test, y_train,y_test = train_test_split(X,y, random_state=1)


In [9]:
X2_train,X2_test, y2_train,y2_test = train_test_split(X,y, random_state=1)
In [10]:
pd.DataFrame.equals(X_train,X2_train)
Out[10]:
True
Cross Validation
In [11]:
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import Lasso

scores = cross_val_score(Lasso(),X,y,cv=5,scoring='r2')
scores
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:491:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:491:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
Out[11]:
array([ 0.59316596, 0.68931527, 0.55383855, 0.18147236, 0.23040894])
In [12]:
scores.mean()
Out[12]:
0.44964021745791793
In [13]:
Lasso().fit(X_train,y_train).score(X_test,y_test)
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:491:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
Out[13]:
0.79261902949633645
Selección de modelos
Overfitting o underfitting?
Recuerden que para saber si estamos en overfitting o en underfitting necesitamos los scores de
entrenamiento y test.
In [16]:
!pip install --upgrade scikit-learn
Requirement already up-to-date: scikit-learn in /opt/conda/lib/python3.5/site-packages
In [17]:
from sklearn.model_selection import cross_validate

results = cross_validate(Lasso(),X,y,return_train_score=True,cv=5)
results
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:491:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
/opt/conda/lib/python3.5/site-packages/sklearn/linear_model/coordinate_descent.py:491:
ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations.
Fitting data with very small alpha may cause precision problems.
ConvergenceWarning)
Out[17]:
{'fit_time': array([ 0.00688601, 0.00739503, 0.01647115, 0.05436873, 0.05301976]),
'score_time': array([ 0.0004952 , 0.00049186, 0.00062156, 0.00069237, 0.00061393]),
'test_score': array([ 0.59316596, 0.68931527, 0.55383855, 0.18147236, 0.23040894]),
'train_score': array([ 0.68988012, 0.77004932, 0.76604995, 0.76123379, 0.75837599])}
In [18]:
test_scores = results['test_score']
train_scores = results['train_score']
print(np.mean(train_scores))
print(np.mean(test_scores))
0.749117836304
0.449640217458
Tenemos bias por lo que buscaremos modelos más complejos.
Validation Curves y Learning Curves
In [19]:
from sklearn.neighbors import KNeighborsRegressor

cross_validate(KNeighborsRegressor(), X, y, cv=5)
Out[19]:
{'fit_time': array([ 0.00543714, 0.00307131, 0.00355124, 0.00312901, 0.00317121]),
'score_time': array([ 0.0024519 , 0.00276566, 0.00358152, 0.00287461, 0.00244856]),
'test_score': array([ 0.3647382 , 0.59274527, 0.21545625, 0.15143495, 0.25635077]),
'train_score': array([ 0.73553883, 0.78647652, 0.78386739, 0.77876542, 0.77477287])}
In [20]:
cross_validate(KNeighborsRegressor(n_neighbors=10), X, y, cv=5)
Out[20]:
{'fit_time': array([ 0.00420117, 0.00292206, 0.00309992, 0.00377607, 0.00303674]),
'score_time': array([ 0.00300527, 0.0043323 , 0.00517344, 0.00384665, 0.00271416]),
'test_score': array([ 0.23553954, 0.61921355, 0.24881301, 0.1209604 , 0.2466995 ]),
'train_score': array([ 0.67830521, 0.76365722, 0.76231726, 0.75701303, 0.75061953])}
In [22]:
n = np.arange(2,50,2)
n
Out[22]:
array([ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34,
36, 38, 40, 42, 44, 46, 48])
In [23]:
n.shape
Out[23]:
(24,)
In [39]:
from sklearn.model_selection import validation_curve

train_scores, test_scores = validation_curve(KNeighborsRegressor(),


X,
y,
param_name='n_neighbors',
param_range=n,
cv=5)
In [28]:
np.mean(train_scores,axis=1)
Out[28]:
array([ 0.86831591, 0.79120817, 0.7593398 , 0.7498298 , 0.74238245,
0.73284018, 0.72586058, 0.71779833, 0.71281982, 0.70976325,
0.70723469, 0.70502429, 0.70174649, 0.69741543, 0.69379214,
0.69163113, 0.68955146, 0.6862285 , 0.68321376, 0.68018032,
0.67885534, 0.67522056, 0.67135123, 0.66953759])
In [34]:
plt.plot(np.mean(train_scores,axis=1))
plt.plot(np.mean(test_scores,axis=1))
plt.xticks(np.arange(24),n);

In [36]:
from sklearn.model_selection import learning_curve

lc = learning_curve(KNeighborsRegressor(n_neighbors=6),X,y,cv=5)
samples, train, test = lc[0], lc[1], lc[2]
In [38]:
plt.plot(samples[1:],np.mean(train,axis=1)[1:])
plt.plot(samples[1:],np.mean(test,axis=1)[1:])
Out[38]:
[<matplotlib.lines.Line2D at 0x7f5caf524160>]

<img src="../vol/img/learning_curve.png" width=500>


El modelo aún está aprendiendo, sin embargo no tenemos como obtener datos adicionales.
Como solucionar el overfitting y el underfitting?
Viarianza Alta:
 Conseguir más ejemplos
 Reducir cantidad de features
 Aumentar coeficiente de regularización
Bias Alto:
 Más features
 Modelo más complejo
Mal resultado general:
 Probar otro algoritmo/familia de modelos, quizás las hipotesis del modelo no son cumplidad por tu
dataset
5.12- ENSEMBLES Y OPTIMIZACIÓN DE HIPERPARAMETROS.IPYNB
In [ ]:
import warnings
warnings.simplefilter("ignore")
In [1]:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
Según distintos benchmarks (papers, kaggle.com) los **algoritmos de uso general** que tienen más veces la
mejor performance son: **Gradient Boosted Trees, Random Forest y SVM**.

Decision Trees
In [5]:
from sklearn.tree import DecisionTreeRegressor

model = DecisionTreeRegressor(max_depth=2)
In [6]:
from sklearn.model_selection import train_test_split

X = pd.read_csv('../vol/intermediate_results/X_opening.csv')
y = X['worldwide_gross']
X = X.drop('worldwide_gross',axis=1)
In [7]:
X_train, X_test, y_train, y_test = train_test_split(X,y,random_state=1)
In [8]:
model.fit(X_train,y_train)
Out[8]:
DecisionTreeRegressor(criterion='mse', max_depth=2, max_features=None,
max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, min_samples_leaf=1,
min_samples_split=2, min_weight_fraction_leaf=0.0,
presort=False, random_state=None, splitter='best')
In [9]:
import graphviz
In [10]:
from sklearn.tree import export_graphviz

treedot = export_graphviz(model,
out_file=None,
feature_names=X.columns)
In [11]:
treedot
Out[11]:
'digraph Tree {\nnode [shape=box] ;\n0 [label="opening_gross <= 41613376.0\\nmse =
4.4919943637e+16\\nsamples = 1665\\nvalue = 141540319.054"] ;\n1 [label="opening_gross <=
22074048.0\\nmse = 1.33338221931e+16\\nsamples = 1506\\nvalue = 92999937.199"] ;\n0 -> 1
[labeldistance=2.5, labelangle=45, headlabel="True"] ;\n2 [label="mse = 4.9236662412e+15\\nsamples =
1257\\nvalue = 64781848.271"] ;\n1 -> 2 ;\n3 [label="mse = 3.147813102e+16\\nsamples = 249\\nvalue =
235450289.735"] ;\n1 -> 3 ;\n4 [label="opening_gross <= 70351576.0\\nmse =
1.10398118716e+17\\nsamples = 159\\nvalue = 601300162.289"] ;\n0 -> 4 [labeldistance=2.5,
labelangle=-45, headlabel="False"] ;\n5 [label="mse = 4.06753884592e+16\\nsamples = 92\\nvalue =
440868287.554"] ;\n4 -> 5 ;\n6 [label="mse = 1.22264857987e+17\\nsamples = 67\\nvalue =
821594676.851"] ;\n4 -> 6 ;\n}'
In [12]:
graphviz.Source(treedot)
Out[12]:

Virtudes de los arboles de decision:


 Metodo poderoso y probado
 Interpretable
 No necesita escalar los datos (clasificación), y menos preprocesamiento de variables
Sin embargo en la practica existen modelos que obtienen mejor rendimiento. Como mejorar el modelo de
arboles de decisión?
Ensembles
Concepto General
Random Forest y Gradient Boosted Trees, forman parte de una familia de algoritmos que se denominan
ensembles.

Cómo funciona el algoritmo Random Forest?


Vamos a generar cientos de modelos de arboles de decisión que serán entrenados sobre conjuntos de datos
bootstrapeados del conjunto de datos original y donde para cada etapa de separación el conjunto de
features elegibles sera un subconjunto aleatorio del conjunto original de features.

Cada uno de los arboles entrenados luego podrá votar por su predicción y promediaremos estos votos.

Ensembles del pobre ("Poor man's ensembles")


 Entrenar diversos modelos a mano
 Promediar el resultado
 Owen Zhang, número 1 de Kaggle.com durante un largo tiempo, ocupaba esta estrategia
promediando diversos modelos XGBoost.
 from sklearn.ensemble import VotingClassifier sirve por ejemplo para hacer un ensemble manual de
clasificación
En general los ensembles del pobre funcionan ya que cada uno de los modelos que votarán en conjunto son
bastante fuertes.
Porqué RF es poderoso?
**Leo Breiman** creador del Random Forest demostró que un ensemble podía tener buen poder de
generalización sí:
1. Los submodelos tienen buen poder de predicción
2. Los submodelos están descorrelacionados
Así el algoritmo de Random Forest compromete un poco de poder de predicción de cada uno de los decision
trees que arma, pero la forma aleatoria de generarlos hace que esten fuertemente descorrelacionados.
In [13]:
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_validate

forest = RandomForestRegressor(200)
results = cross_validate(forest,X,y,cv=5,scoring='r2')
In [14]:
test_scores = results['test_score']
train_scores = results['train_score']
print(np.mean(train_scores))
print(np.mean(test_scores))
0.965239108957
0.514504965042
Mejor resultado que Lasso! Ya no tenemos Bias y tenemos un mejor score r2. Sin embargo tenemos una
diferencia importante entre score de entrenamiento y de test (overfit).
Gradient Boosted Trees
In [15]:
from sklearn.ensemble import GradientBoostingRegressor

ensemble = GradientBoostingRegressor()
results = cross_validate(ensemble,X,y,cv=5,scoring='r2')
In [16]:
test_scores = results['test_score']
train_scores = results['train_score']
print(np.mean(train_scores))
print(np.mean(test_scores))
0.915139214355
0.525193924287
Cómo optimizamos los parametros de este último modelo?
Optimización de hiperparametros
 Fijar un learning rate alto
 Fijar parametros de los arboles
 Fijados estos parametros, elegir el mejor numero de estimadores que conforman el ensemble
 (Tarea) Con el learning rate dado y el numero de estimadores óptimo, optimizar los parametros de
los arboles
Grid Search
Por ahora dijimos que:
 train_test_split servia para evaluaciones rapidas, testeos y prototipaje
 cross_validate es un método más robusto para poder estimar el rendimiento de tu algoritmo
Sin embargo una vez que hemos finalizado nuestra etapa de prototipaje y ya queremos establecer un
modelo definitivo deberiamos seguir el flujo siguiente.
<img src="../vol/img/grid_search_crossval.png" width=700>
In [17]:
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X,y,random_state=1)


In [18]:
from sklearn.model_selection import GridSearchCV

param_test1 = {'n_estimators': range(20,501,20)}


In [20]:
list(param_test1['n_estimators'])
Out[20]:
[20,
40,
60,
80,
100,
120,
140,
160,
180,
200,
220,
240,
260,
280,
300,
320,
340,
360,
380,
400,
420,
440,
460,
480,
500]
In [21]:
estimator = GradientBoostingRegressor(learning_rate=0.1,
min_samples_split=500,
min_samples_leaf=50,
max_depth=8,
max_features='sqrt',
subsample=0.8,
random_state=10)
In [22]:
gsearch1 = GridSearchCV(estimator,
param_grid = param_test1,
scoring='r2',
cv=5)
In [23]:
gsearch1.fit(X_train,y_train)
Out[23]:
GridSearchCV(cv=5, error_score='raise',
estimator=GradientBoostingRegressor(alpha=0.9, criterion='friedman_mse', init=None,
learning_rate=0.1, loss='ls', max_depth=8,
max_features='sqrt', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=50, min_samples_split=500,
min_weight_fraction_leaf=0.0, n_estimators=100,
presort='auto', random_state=10, subsample=0.8, verbose=0,
warm_start=False),
fit_params=None, iid=True, n_jobs=1,
param_grid={'n_estimators': range(20, 501, 20)},
pre_dispatch='2*n_jobs', refit=True, return_train_score=True,
scoring='r2', verbose=0)
In [24]:
gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_
/opt/conda/lib/python3.5/site-packages/sklearn/model_selection/_search.py:747: DeprecationWarning:
The grid_scores_ attribute was deprecated in version 0.18 in favor of the more elaborate cv_results_
attribute. The grid_scores_ attribute will not be available from 0.20
DeprecationWarning)
Out[24]:
([mean: 0.65534, std: 0.05764, params: {'n_estimators': 20},
mean: 0.71947, std: 0.06256, params: {'n_estimators': 40},
mean: 0.73472, std: 0.06360, params: {'n_estimators': 60},
mean: 0.73893, std: 0.06236, params: {'n_estimators': 80},
mean: 0.74205, std: 0.06271, params: {'n_estimators': 100},
mean: 0.74593, std: 0.06236, params: {'n_estimators': 120},
mean: 0.74954, std: 0.06335, params: {'n_estimators': 140},
mean: 0.75082, std: 0.06305, params: {'n_estimators': 160},
mean: 0.75257, std: 0.06344, params: {'n_estimators': 180},
mean: 0.75349, std: 0.06447, params: {'n_estimators': 200},
mean: 0.75457, std: 0.06342, params: {'n_estimators': 220},
mean: 0.75531, std: 0.06489, params: {'n_estimators': 240},
mean: 0.75517, std: 0.06572, params: {'n_estimators': 260},
mean: 0.75389, std: 0.06495, params: {'n_estimators': 280},
mean: 0.75460, std: 0.06569, params: {'n_estimators': 300},
mean: 0.75250, std: 0.06545, params: {'n_estimators': 320},
mean: 0.75350, std: 0.06492, params: {'n_estimators': 340},
mean: 0.75354, std: 0.06623, params: {'n_estimators': 360},
mean: 0.75259, std: 0.06542, params: {'n_estimators': 380},
mean: 0.75254, std: 0.06469, params: {'n_estimators': 400},
mean: 0.75186, std: 0.06477, params: {'n_estimators': 420},
mean: 0.75205, std: 0.06508, params: {'n_estimators': 440},
mean: 0.75157, std: 0.06449, params: {'n_estimators': 460},
mean: 0.75051, std: 0.06352, params: {'n_estimators': 480},
mean: 0.75096, std: 0.06327, params: {'n_estimators': 500}],
{'n_estimators': 240},
0.7553059694284987)
In [26]:
final_results = cross_validate(gsearch1.best_estimator_,X_train,y_train)
In [27]:
test_scores = final_results['test_score']
train_scores = final_results['train_score']
print(np.mean(train_scores))
print(np.mean(test_scores))
0.81831693665
0.741387612516
In [28]:
estimator = GradientBoostingRegressor(learning_rate=0.1,
min_samples_split=500,
min_samples_leaf=50,
max_depth=8,
max_features='sqrt',
subsample=0.8,
random_state=10,
n_estimators=240)
In [29]:
estimator.fit(X_train,y_train)
Out[29]:
GradientBoostingRegressor(alpha=0.9, criterion='friedman_mse', init=None,
learning_rate=0.1, loss='ls', max_depth=8,
max_features='sqrt', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=50, min_samples_split=500,
min_weight_fraction_leaf=0.0, n_estimators=240,
presort='auto', random_state=10, subsample=0.8, verbose=0,
warm_start=False)
In [30]:
estimator.score(X_test,y_test)
Out[30]:
0.8092888852563106
Reflexiones de cierre
Recursos
 Reddit /machinelearning y /learnmachinelearning
 Analytics Vidhya y KD Nuggets
 Kaggle.com y "There is no Free Hunch" Blog
 Arxiv, papers
 Libros: "Pattern Recognition and Machine Learning" C.Bishop y "Elements of Statistical Learning".
Próximos pasos
 Matemáticas
 Praxis: Feature Engineering, Model Selection y Tuning
 Deep Learning para NLP y Computer Vision
 Machine Learning Bayesiano
5.13- README.MD
  
machine-learning-platzi
Este repositorio contiene los notebooks del curso "Machine Learning Aplicado con Python" que dicté en
platzi.
El objetivo de este curso es entregar los skills prácticos necesarios para implementar algoritmos de ML en
un contexto profesional.
El curso incluye:
 Introducción a Numpy, para manejo de algebra lineal.
 Introducción a Pandas, para manejo de los datos en un formato de DataFrames (tablas).
 Docker files para setup de ambientes limpios y poderosos de trabajo de Machine Learning.
 Estudio completo del ciclo de ingeniería del Machine Learning.
o Preparación de datos: Cleaning, Imputation, Merging.
o Feature Engineering: One-hot encode, Scaling, Feature Design
o Entrenamiento de modelos: Sklearn API (train_test_split, fit, predict, score)
o Evaluación de modelos: sklearn.model_selection, Cross Validation, Grid Search.
 Algoritmos de Machine Learning: Regresión Lineal, Regresión Lasso, KNN, Random Forest, Gradient
Boosting Trees.
El curso sigue un flujo de resolución real de un problema de predicción de ingreso de peliculas con la base de
datos de IMDB con 1000+ ejemplos de entrenamiento.

6. EL CICLO DE MACHINE LEARNING

También podría gustarte