Un proyecto completo de Machine Learning en Python: Primera Parte

Cesar Vega
27 septiembre, 2019

. . .

Poner las piezas de machine learning juntas


Este artículo se basa en el video publicado originalmente en inglés por Will Koehrsen en Medium. Por favor, visita el siguiente enlace y recomienda el artículo original si te gusta el contenido:

Al leer un libro de ciencias de datos o tomar un curso, puede parecer que tienes las piezas individuales, pero no sabes cómo armarlas. Dar el siguiente paso y resolver un problema completo de machine learning puede ser desalentador, pero conservar y completar un primer proyecto te dará la confianza para abordar cualquier problema de la ciencia de datos. Esta serie de artículos recorrerá una solución completa de machine learning con un conjunto de datos del mundo real para que puedas ver cómo se unen todas las piezas.

Seguiremos el flujo de trabajo general de machine learning paso a paso:

  • 1. Limpieza y formateo de datos
  • 2. Análisis exploratorio de datos
  • 3. Ingeniería y selección de características
  • 4. Comparar varios modelos de machine learning en una métrica de rendimiento
  • 5. Realizar el afinamiento de los hiperparámetros en el mejor modelo
  • 6. Evaluar el mejor modelo en el conjunto de pruebas
  • 7. Interpretar los resultados del modelo
  • 8. Sacar conclusiones y documentar el trabajo

A lo largo del camino, veremos cómo cada paso fluye hacia el siguiente y cómo implementar específicamente cada parte en Python. El proyecto completo está disponible en GitHub, con el primer notebook aquí. Este primer artículo cubrirá los pasos del 1 al 3 y el resto se tratará en los posts subsiguientes.

(Como nota, este problema me fue asignado originalmente como una «asignación» para una pantalla de trabajo en una start-up. Después de completar el trabajo, me ofrecieron el puesto, pero luego el CTO de la empresa renunció y no pudieron contratar a ningún nuevo empleado. Supongo que así es como van las cosas en el escenario de una start-up).

. . .

El primer paso antes de empezar a codificar es entender el problema que estamos tratando de resolver y los datos disponibles. En este proyecto, trabajaremos con datos de energía del edificio disponibles públicamente de la ciudad de Nueva York.

El objetivo es utilizar los datos energéticos para construir un modelo que pueda predecir la puntuación Energy Star Score de un edificio e interpretar los resultados para encontrar los factores que influyen en la puntuación

Los datos incluyen el puntaje Energy Star Score, que lo convierte en una tarea de machine learning de regresión supervisada:

  • * Supervisado: tenemos acceso tanto a las características como al objetivo y nuestro objetivo es formar un modelo que pueda aprender un mapeo entre los dos.
  • * Regresión: La puntuación de Energy Star es una variable continua

Queremos desarrollar un modelo que sea a la vez preciso -puede predecir la puntuación de Energy Star cerca del valor real- e interpretable -podemos entender las predicciones del modelo. Una vez que conocemos el objetivo, podemos usarlo para guiar nuestras decisiones a medida que escarbamos en los datos y construimos modelos.


Limpieza de datos

Contrariamente a lo que la mayoría de los cursos de ciencias de la información te hacen creer, no todos los datasets son un grupo perfectamente curado de observaciones sin valores perdidos o anomalías (observa tus datasets mtcars e iris). Los datos del mundo real son confusos, lo que significa que necesitamos limpiarlos y convertirlos en un formato aceptable incluso antes de que podamos comenzar el análisis. La limpieza de datos es una parte poco glamurosa, pero necesaria, de la mayoría de los problemas actuales de la ciencia de datos.

Primero, podemos cargar los datos como un DataFrame Pandas y echar un vistazo:

import pandas as pd
import numpy as np
# Leer datos en un dataframe
 data = pd.read_csv('data/Energy_and_Water_Data_Disclosure_for_Local_Law_84_2017__Data_for_Calendar_Year_2016_.csv')
# Mostrar la parte superior de dataframe
 data.head()


¡Cómo se ven los datos reales!


Este es un subconjunto de los datos completos que contiene 60 columnas. Ya podemos ver un par de problemas: primero, sabemos que queremos predecir el ENERGY STAR Score pero no sabemos lo que significan todas las columnas. Aunque esto no es necesariamente un problema – a menudo podemos hacer un modelo preciso sin ningún conocimiento de las variables – queremos centrarnos en la interpretabilidad, y puede ser importante entender al menos algunas de las columnas.

Cuando originalmente obtuve la asignación de la start-up, no quise preguntar qué significaban todos los nombres de columna, así que miré el nombre del archivo,

y decidí buscar «Local Law 84». Eso me llevó a esta página que explica que esta es una ley de la ciudad de Nueva York que requiere que todos los edificios de cierto tamaño reporten su uso de energía. Más búsquedas me llevaron a todas las definiciones de las columnas. Tal vez mirar el nombre de un archivo es un lugar obvio para empezar, pero para mí esto fue un recordatorio de ir despacio para que no te pierdas nada importante.

No necesitamos estudiar todas las columnas, pero al menos deberíamos entender el Energy Star Score, que se describe como:

Una clasificación de percentil de 1 a 100 basada en el uso de energía auto informado para el reporte anual. El puntaje Energy Star es una medida relativa utilizada para comparar la eficiencia energética de los edificios.

Esto aclara el primer problema, pero el segundo problema es que los valores que faltan se codifican como «Not Available». Esta es un string en Python, lo que significa que incluso las columnas con números se almacenarán como tipos de datos de object  porque Pandas convierte una columna con cualquier string en una columna de todas los strings. Podemos ver los datatypes de las columnas usan el método dataframe.info():

# See the column data types and non-missing values
data.info()

Por supuesto, algunas de las columnas que claramente contienen números (como ft²), se almacenan como objetos. ¡No podemos hacer análisis numéricos en strings, así que estos tendrán que ser convertidos a tipos de datos numéricos (específicamente float)!

Aquí hay un pequeño código Python que reemplaza todas las entradas de «Not Available» con not a number (np.nan), que puede ser interpretado como números, y luego convierte las columnas relevantes al datatype  float:

# Reemplaza todas las apariciones de Not Available con numpy, no un número
data = data.replace({'Not Available': np.nan})

# Iterar a través de las columnas 
for col in list(data.columns):
    # Select columns that should be numeric
    if ('ft²' in col or 'kBtu' in col or 'Metric Tons CO2e' in col or 'kWh' in 
        col or 'therms' in col or 'gal' in col or 'Score' in col):
        # Convert the data type to float
        data[col] = data[col].astype(float)

Una vez que las columnas correctas son números, podemos comenzar a investigar los datos.


Datos faltantes y Valores Atípicos

Además de los tipos de datos incorrectos, otro problema común cuando tratamos datos del mundo real, es la falta de valores. Estos pueden surgir por muchas razones y tienen que ser completados o eliminados antes de entrenar un modelo machine learning. Primero, vamos a tener una idea de cuántos valores faltantes hay en cada columna (ver el notebook para el código).

(Para crear esta tabla, utilicé una función de este Foro de Stack Overflow).

Aunque siempre queremos tener cuidado al eliminar información, si una columna tiene un alto porcentaje de valores faltantes, entonces probablemente no será útil para nuestro modelo. El umbral para eliminar columnas debe depender del problema (aquí hay una discusión), y para este proyecto, eliminaremos cualquier columna con más del 50% de valores faltantes.

En este punto, es posible que también queramos eliminar los valores atípicos. Estos pueden ser debidos a errores tipográficos en la entrada de datos, errores en las unidades, o pueden ser valores legítimos pero extremos. Para este proyecto, eliminaremos las anomalías basadas en la definición de valores extremos atípicos:

  • Por debajo del primer cuartil – 3 ∗ rango intercuartil
  • Por encima del tercer cuartil + 3 ∗ rango intercuartil

(Para que el código elimine las columnas y las anomalías, ver el notebook). Al final del proceso de limpieza de datos y eliminación de anomalías, nos quedamos con más de 11.000 edificios y 49 características.

. . .


Análisis exploratorio de datos

Ahora que el tedioso -pero necesario- paso de la limpieza de datos está completo, ¡podemos pasar a explorar nuestros datos! El Análisis Exploratorio de Datos (EDA, por sus siglas en inglés) es un proceso abierto donde calculamos estadísticas y hacemos figuras para encontrar tendencias, anomalías, patrones o relaciones dentro de los datos.

En resumen, el objetivo de la EDA es aprender lo qué nos pueden decir nuestros datos. Generalmente comienza con una visión general de alto nivel, luego se reduce a áreas específicas a medida que encontramos partes interesantes de los datos. Los hallazgos pueden ser interesantes por sí mismos, o pueden ser utilizados para informar nuestras opciones de modelado, por ejemplo, ayudándonos a decidir qué características utilizar.


Gráficos de variables individuales

El objetivo es predecir la puntuación de Energy Star Score (renombrada como score en nuestros datos), por lo que un lugar razonable para empezar es examinar la distribución de esta variable. Un histograma es una manera simple pero efectiva de visualizar la distribución de una sola variable y es fácil de hacer usando matplotlib.

import matplotlib.pyplot as plt
# Histogram of the Energy Star Score
plt.style.use('fivethirtyeight')
plt.hist(data['score'].dropna(), bins = 100, edgecolor = 'k');
plt.xlabel('Score'); plt.ylabel('Number of Buildings'); 
plt.title('Energy Star Score Distribution');

¡Esto parece bastante sospechoso! El puntaje de Energy Star es un rango de percentil, lo que significa que esperaríamos ver una distribución uniforme, con cada puntaje asignado al mismo número de edificios. Sin embargo, un número desproporcionado de edificios tiene la puntuación más alta, 100, o la más baja, 1 (más alto es mejor para la puntuación de Energy Star).

Si volvemos a la definición de la puntuación, vemos que se basa en el «consumo de energía autoinformado», lo que podría explicar las puntuaciones muy altas. Pedir a los propietarios de edificios que informen sobre su propio uso de energía es como pedir a los estudiantes que informen sobre sus propios resultados en una prueba. Como resultado, esta no es probablemente la medida más objetiva de la eficiencia energética de un edificio.

Si tuviéramos una cantidad ilimitada de tiempo, podríamos investigar por qué tantos edificios tienen puntuaciones muy altas y muy bajas, lo cual podríamos hacer seleccionando estos edificios y viendo lo que tienen en común. Sin embargo, nuestro objetivo es sólo predecir la puntuación y no idear un mejor método para puntuar edificios. Podemos anotar en nuestro informe que las puntuaciones tienen una distribución sospechosa, pero nuestro objetivo principal es predecir la puntuación.


Buscando relaciones

Una parte importante de EDA es la búsqueda de relaciones entre las características y el objetivo. Las variables que están correlacionadas con el objetivo son útiles para un modelo porque se pueden utilizar para predecir el objetivo. Una forma de examinar el efecto de una variable categórica (que sólo toma un conjunto limitado de valores) sobre el objetivo es a través de un diagrama de densidad utilizando la biblioteca seaborn.

Un gráfico de densidad puede considerarse como un histograma suavizado porque muestra la distribución de una sola variable. Podemos colorear un gráfico de densidad por clase para ver cómo una variable categórica cambia la distribución. El siguiente código hace una gráfica de densidad de la Energy Star Score coloreada por el tipo de edificio (limitada a los tipos de edificios con más de 100 puntos de datos):


# Crea una lista de edificios con más de 100 medidas
types = data.dropna(subset=['score'])
types = types['Largest Property Use Type'].value_counts()
types = list(types[types.values > 100].index)

# Gráfico de distribución de puntajes para categorías de construcción
figsize(12, 10)

# Dibujar cada edificio
for b_type in types:
    # Select the building type
    subset = data[data['Largest Property Use Type'] == b_type]
    
    # Density plot of Energy Star scores
    sns.kdeplot(subset['score'].dropna(),
               label = b_type, shade = False, alpha = 0.8);
    
# etiquete el gráfico
plt.xlabel('Energy Star Score', size = 20); plt.ylabel('Density', size = 20); 
plt.title('Density Plot of Energy Star Scores by Building Type', size = 28);



Podemos ver que el tipo de edificio tiene un impacto significativo en la puntuación Energy Star Score. Los edificios de oficinas tienden a tener una puntuación más alta, mientras que los Hoteles tienen una puntuación más baja. Esto nos dice que debemos incluir el tipo de edificio en nuestro modelado porque tiene un impacto en el objetivo. Como variable categórica, tendremos que codificar en caliente el tipo de edificio.

Un gráfico similar puede ser usado para mostrar Energy Star Score por ciudad:



La ciudad no parece tener un impacto tan grande en la puntuación como el tipo de edificio. Sin embargo, es posible que queramos incluirlo en nuestro modelo porque hay pequeñas diferencias entre las ciudades.

Para cuantificar las relaciones entre variables, podemos utilizar el Coeficiente de Correlación de Pearson. Esta es una medida de la fuerza y dirección de una relación lineal entre dos variables. Una puntuación de +1 es una relación positiva perfectamente lineal y una puntuación de -1 es una relación lineal perfectamente negativa. A continuación, se muestran varios valores del coeficiente de correlación:


Valores del coeficiente de correlación de Pearson (fuente)


Mientras que el coeficiente de correlación no puede capturar relaciones no lineales, es una buena manera de empezar a entender cómo se relacionan las variables. En Pandas, podemos calcular fácilmente las correlaciones entre cualquier columna de un marco de datos:


# Encuentra todas las correlaciones con la puntuación y ordena 
correlations_data = data.corr()['score'].sort_values()


Las correlaciones más negativas (izquierda) y positivas (derecha) con el objetivo:



Existen varias correlaciones negativas importantes entre las características y el objetivo, siendo las más negativas las diferentes categorías de EUI (estas medidas varían ligeramente en la forma de calcularlas). El EUI – Energy Use Intensity – es la cantidad de energía utilizada por un edificio dividida por la superficie cuadrada de los edificios. Se pretende que sea una medida de la eficiencia de un edificio con una puntuación más baja que es mejor. Intuitivamente, estas correlaciones tienen sentido: a medida que aumenta el índice EUI, la puntuación Energy Star Score tiende a disminuir.



Gráficos de dos variables


Para visualizar las relaciones entre dos variables continuas, utilizamos gráficos de dispersión. Podemos incluir información adicional, como una variable categórica, en el color de los puntos. Por ejemplo, el siguiente gráfico muestra Energy Star Score en comparación con el Site EUI coloreado por tipo de edificio:



Este gráfico nos permite visualizar cómo es un coeficiente de correlación de -0,7. A medida que el índice EUI del Site disminuye, la puntuación Energy Star Score aumenta, una relación que se mantiene estable en todos los tipos de edificios.

La última gráfica exploratoria que haremos se conoce como el gráfico de los pares (Pairs Plot). Esta es una gran herramienta de exploración porque nos permite ver las relaciones entre múltiples pares de variables así como las distribuciones de variables individuales. Aquí estamos usando la librería de visualización seaborn y la función PairGrid para crear una Pairs Plot con gráficos de dispersión en el triángulo superior, histogramas en la diagonal y gráficos de densidad de núcleo 2D y coeficientes de correlación en el triángulo inferior.


# Extrae las columnas para graficar
plot_data = features[['score', 'Site EUI (kBtu/ft²)', 
                      'Weather Normalized Source EUI (kBtu/ft²)', 
                      'log_Total GHG Emissions (Metric Tons CO2e)']]

# Remplace inf con nan
plot_data = plot_data.replace({np.inf: np.nan, -np.inf: np.nan})

# Renombre columnas 
plot_data = plot_data.rename(columns = {'Site EUI (kBtu/ft²)': 'Site EUI', 
                                        'Weather Normalized Source EUI (kBtu/ft²)': 'Weather Norm EUI',
                                        'log_Total GHG Emissions (Metric Tons CO2e)': 'log GHG Emissions'})

# Elimine valores na
plot_data = plot_data.dropna()

# Función para calcular el coeficiente de correlación entre dos columnas
def corr_func(x, y, **kwargs):
    r = np.corrcoef(x, y)[0][1]
    ax = plt.gca()
    ax.annotate("r = {:.2f}".format(r),
                xy=(.2, .8), xycoords=ax.transAxes,
                size = 20)

# Crear el objeto pairgrid
grid = sns.PairGrid(data = plot_data, size = 3)

# Upper es un scatter plot (es un diagrama de dispersión)
grid.map_upper(plt.scatter, color = 'red', alpha = 0.6)

# Diagonal es un histograma
grid.map_diag(plt.hist, color = 'red', edgecolor = 'black')

# La parte inferior es un gráfico de correlación y densidad
grid.map_lower(corr_func);
grid.map_lower(sns.kdeplot, cmap = plt.cm.Reds)

# Titulo para todo el gráfico
plt.suptitle('Pairs Plot of Energy Data', size = 36, y = 1.02);



Para ver las interacciones entre variables, buscamos dónde se cruza una fila con una columna. Por ejemplo, para ver la correlación de la Weather Norm EUI (Norma Meteorológica EUI) con score, buscamos en la fila Weather Norm EUI y en la columna score y vemos un coeficiente de correlación de -0,67. Además de tener un buen aspecto, gráficos como estos pueden ayudarnos a decidir qué variables incluir en el modelado.


Ingeniería y selección de características


Ingeniería y selección de características a menudo proporcionan el mayor retorno del tiempo invertido en un problema de machine learning. En primer lugar, definamos cuáles son estas dos tareas:

  • * Ingeniería de características: El proceso de tomar datos sin procesar y extraer o crear nuevas características. Esto podría significar tomar transformaciones de variables, como un registro natural y una raíz cuadrada, o codificación one-hot de variables categóricas para que puedan ser usadas en un modelo. Generalmente, pienso en la ingeniería de características como la creación de características adicionales a partir de los datos brutos.
  • * Selección de características: El proceso de selección de las características más relevantes de los datos. En la selección de características, eliminamos características para ayudar al modelo a generalizarse mejor a nuevos datos y crear un modelo más interpretable. Generalmente, pienso en la selección de características, así como en la sustracción de características, por lo que nos quedamos sólo con aquellas que son más importantes.

Un modelo machine learning sólo puede aprender de los datos que le proporcionamos, por lo que es crucial garantizar que los datos incluyan toda la información relevante para nuestra tarea. ¡Si no le damos a un modelo los datos correctos, entonces lo estamos configurando para que falle y no debemos esperar que aprenda!

Para este proyecto, tomaremos los siguientes pasos de ingeniería de características:

  • * Codificación One-Hot de variables categóricas (tipo de uso de la ciudad y de la propiedad)
  • * Agregar la transformación natural de los registros de las variables numéricas

Es necesaria una codificación One-Hot para incluir variables categóricas en un modelo. Un algoritmo de machine learning no puede entender un tipo de edificio «office», así que tenemos que registrarlo como un 1 si el edificio es una oficina y un 0 si no lo es.

Agregar características transformadas puede ayudar a nuestro modelo a aprender relaciones no lineales dentro de los datos. Tomar la raíz cuadrada, el registro natural o varios poderes de las características es una práctica común en la ciencia de datos y puede basarse en el conocimiento del dominio o en lo que funciona mejor en la práctica. Aquí incluiremos el registro natural de todas las características numéricas.

El siguiente código selecciona las características numéricas, toma las transformaciones de registro de estas características, selecciona las dos características categóricas, codificación one-hot de estas características, y une los dos conjuntos juntos. ¡Esto parece mucho trabajo, pero es relativamente sencillo en Pandas!


# Copia los datos originales
features = data.copy()

# Selecciona las columnas numéricas
numeric_subset = data.select_dtypes('number')

# Crea columnas con registro de las columnas numéricas
for col in numeric_subset.columns:
    # Skip the Energy Star Score column
    if col == 'score':
        next
    else:
        numeric_subset['log_' + col] = np.log(numeric_subset[col])
        
# Seleccione las columnas categóricas
categorical_subset = data[['Borough', 'Largest Property Use Type']]

# Codificación One hot
categorical_subset = pd.get_dummies(categorical_subset)

# Une los dos dataframes usando concat
# Asegúrate de usar axis = 1 para realizar un enlace de columna
features = pd.concat([numeric_subset, categorical_subset], axis = 1)


Después de este proceso tenemos más de 11.000 observaciones (edificios) con 110 columnas (características). No es probable que todas estas características sean útiles para predecir el Energy Star Score, así que ahora pasaremos a la selección de características para eliminar algunas de las variables.


Selección de características

Muchas de las 110 características que tenemos en nuestros datos son redundantes porque están altamente correlacionadas entre sí. Por ejemplo, aquí hay un gráfico del Site EUI vs. El Site Normalizado Meteorológico EUI que tiene un coeficiente de correlación de 0.997.



Las características que están fuertemente correlacionadas entre sí se conocen como colineales y la eliminación de una de las variables de estos pares de características a menudo puede ayudar a un modelo machine learning a generalizarse y ser más interpretable. (¡Debo señalar que estamos hablando de correlaciones de características con otras características, no de correlaciones con el objetivo, que ayudan a nuestro modelo!)

Existen varios métodos para calcular la colinealidad entre características, siendo uno de los más comunes el factor de inflación de la varianza. En este proyecto, utilizaremos el coeficiente de correlación para identificar y eliminar las características colineales. Dejaremos caer una de un par de características si el coeficiente de correlación entre ellas es superior a 0,6. Para la implementación, echa un vistazo al notebook (y a esta respuesta de Stack Overflow)

Aunque este valor puede parecer arbitrario, probé varios umbrales diferentes, y esta elección dio como resultado el mejor modelo. Machine learning es un campo empírico y a menudo se trata de experimentar y encontrar lo que funciona mejor. Después de la selección de características, nos quedamos con un total de 64 características y un objetivo.


# Eliminar cualquier columna con todos los valores na
features  = features.dropna(axis=1, how = 'all')
print(features.shape)(11319, 65)


Establecer una línea de base

Ahora hemos completado la limpieza de datos, el análisis exploratorio de datos y la ingeniería de características. El paso final a tomar antes de comenzar con el modelado es establecer una línea de base ingenua. Esto es esencialmente una conjetura contra la cual podemos comparar nuestros resultados. Si los modelos de machine learning no superan esta suposición, es posible que tengamos que concluir que el machine learning no es aceptable para la tarea o que tengamos que intentar un enfoque diferente.

Para los problemas de regresión, una base de referencia razonable e ingenua es adivinar el valor medio del objetivo en el conjunto de la capacitación para todos los ejemplos en el conjunto de pruebas. Esto establece una barra relativamente baja para que cualquier modelo la supere.

La métrica que utilizaremos es el error absoluto medio (mae, por sus siglas en inglés) que mide el error absoluto medio en las predicciones. Hay muchas métricas para la regresión, pero me gusta el consejo de Andrew Ng de elegir una sola métrica y luego atenerse a ella al evaluar los modelos. El error absoluto medio es fácil de calcular y es interpretable.

Antes de calcular la línea de base, necesitamos dividir nuestros datos en un conjunto de entrenamiento y pruebas:

  • 1. El conjunto de entrenamiento de las características es lo que proporcionamos a nuestro modelo durante la formación junto con las respuestas. El objetivo es que el modelo aprenda un mapeo entre las características y el objetivo.
  • 2. El conjunto de prueba de las características se utiliza para evaluar el modelo entrenado. El modelo no tiene permitido ver las respuestas para el conjunto de pruebas y debe hacer predicciones usando sólo las características. Conocemos las respuestas para el conjunto de pruebas para que podamos comparar las predicciones de las pruebas con las respuestas.

Utilizaremos el 70% de los datos para el entrenamiento y el 30% para las pruebas:


# Se divide en un 70% de entrenamiento y un 30% de pruebas
X, X_test, y, y_test = train_test_split(features, targets, 
test_size = 0.3, 
random_state = 42)


# Función para calcular el error absoluto medio
def mae(y_true, y_pred):
    return np.mean(abs(y_true - y_pred))

baseline_guess = np.median(y)

print('The baseline guess is a score of %0.2f' % baseline_guess)
print("Baseline Performance on the test set: MAE = %0.4f" % mae(y_test, baseline_guess))


El punto de partida es una puntuación de 66.00
Desempeño de la línea de base en el equipo de prueba: MAE = 24.5164


La estimación ingenua está fuera de lugar por cerca de 25 puntos en el set de prueba. La puntuación oscila entre 1-100, por lo que esto representa un error del 25%, una barra bastante baja para superar!


Conclusiones

En este artículo caminamos a través de los primeros tres pasos de un problema de machine learning. Después de definir la pregunta, nosotros:

  • 1. Limpiamos y formateamos los datos sin procesar
  • 2. Realizamos un análisis exploratorio de los datos para conocer el dataset.
  • 3. Desarrollamos un conjunto de características que utilizaremos para nuestros modelos

Finalmente, también completamos el paso crucial de establecer una línea de base contra la cual podemos juzgar nuestros algoritmos de machine learning.

El segundo post (disponible aquí) mostrará cómo evaluar los modelos de machine learning usando Scikit-Learn, seleccionar el mejor modelo y realizar el ajuste de hiperparámetros para optimizar el modelo. El tercer post, relativo a la interpretación de modelos y la presentación de informes de resultados, está aquí.

Como siempre, agradezco los comentarios y las críticas constructivas y puedo ser contactado en Twitter @koehrsen_will.

14

1 comentario

  • R

    No me di cuenta y pasé +20 minutos leyendo y entendiendo el código jaja.
    Buen post!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Comunidades en Español