Generación del modelo de Machine Learning

Para crear un modelo de Machine Learning, necesita dos conjuntos de datos: uno para el entrenamiento y otro para las pruebas. En la práctica, generalmente solo se tiene un conjunto de datos, que se divide en dos. En este ejercicio, realizará una división 80-20 del elemento DataFrame que ha preparado en el laboratorio anterior con el fin de usarlo para entrenar un modelo de Machine Learning. También separará el elemento DataFrame en columnas de característica y etiqueta. Las primeras contienen las columnas que se usan como entrada para el modelo (por ejemplo, el origen y el destino del vuelo, y la hora de salida programada), mientras que la segunda contiene la columna que el modelo intentará predecir, en este caso, la columna ARR_DEL15, que indica si un vuelo será puntual.

  1. Cambie al cuaderno de Azure que ha creado en la sección anterior. Si ha cerrado el cuaderno, puede volver a iniciar sesión en el portal de Microsoft Azure Notebooks, abrir el cuaderno y usar Cell -> Run All (Celda>Ejecutar todo) para volver a ejecutar todas las celdas del cuaderno después de abrirlo.

  2. En una celda nueva al final del cuaderno, escriba y ejecute las instrucciones siguientes:

    from sklearn.model_selection import train_test_split
    train_x, test_x, train_y, test_y = train_test_split(df.drop('ARR_DEL15', axis=1), df['ARR_DEL15'], test_size=0.2, random_state=42)
    

    La primera instrucción importa la función auxiliar train_test_split de Scikit-learn. En la segunda línea se usa la función para dividir el elemento DataFrame en un conjunto de entrenamiento que contiene el 80 % de los datos originales y un conjunto de prueba con el 20 % restante. El parámetro random_state inicializa el generador de números aleatorios que se usa para realizar la división, mientras que el primer y segundo parámetros son elementos DataFrame que contienen las columnas de característica y la de etiqueta.

  3. train_test_split devuelve cuatro elementos DataFrame. Use el comando siguiente para mostrar el número de filas y columnas del elemento DataFrame que contiene las columnas de característica que se usan para el entrenamiento:

    train_x.shape
    
  4. Ahora, use este comando para mostrar el número de filas y columnas del elemento DataFrame que contiene las columnas de característica que se usan para las pruebas:

    test_x.shape
    

    ¿Cómo se diferencian las dos salidas y por qué?

¿Puede predecir lo que vería si llamara a shape en los otros dos elementos DataFrame, train_y y test_y? Si no está seguro, pruébelo para averiguarlo.

Hay muchos tipos de modelos de Machine Learning. Uno de los más comunes es el modelo de regresión, en el que se usa uno de los diferentes algoritmos de regresión para generar un valor numérico, por ejemplo, la edad de una persona o la probabilidad de que una transacción de tarjeta de crédito sea fraudulenta. Entrenará un modelo de clasificación, que intenta resolver un conjunto de entradas en un resultado conocido de un conjunto. Un ejemplo clásico de modelo de clasificación es en el que se examinan mensajes de correo electrónico y se clasifican como "spam" o "no spam". En este caso, será un modelo de clasificación binaria que predice si un vuelo llegará a la hora o con retraso (es "binaria" porque hay solo dos resultados posibles).

Una de las ventajas del uso de Scikit-learn es que no es necesario generar estos modelos, ni implementar los algoritmos que usan, de forma manual. Scikit-learn incluye una serie de clases para implementar modelos de Machine Learning comunes. Una de ellas es RandomForestClassifier, que ajusta varios árboles de decisión a los datos y calcula el promedio para mejorar la precisión general y limitar el sobreajuste.

  1. Ejecute el código siguiente en una celda nueva para crear un objeto RandomForestClassifier y llame al método fit para entrenarlo.

    from sklearn.ensemble import RandomForestClassifier
    
    model = RandomForestClassifier(random_state=13)
    model.fit(train_x, train_y)
    

    En la salida se muestran los parámetros usados en el clasificador, incluido n_estimators, que especifica el número de árboles de cada bosque de árboles de decisión, y max_depth, que especifica la profundidad máxima de los árboles de decisión. Los valores que se muestran son los predeterminados, pero puede invalidar cualquiera de ellos al crear el objeto RandomForestClassifier.

    Entrenamiento del modelo

    Entrenamiento del modelo

  2. Ahora, llame al método predict para probar el modelo con los valores de test_x, seguido del método score para determinar la precisión media del modelo:

    predicted = model.predict(test_x)
    model.score(test_x, test_y)
    

    Confirme que ve la salida siguiente:

    Prueba del modelo

    Prueba del modelo

La precisión media es del 86 %, lo que aparentemente parece correcto. Pero la precisión media no siempre es un indicador fiable de la precisión de un modelo de clasificación. Vamos a profundizar un poco más y determinar la verdadera precisión del modelo, es decir, su capacidad para determinar si un vuelo llegará puntual o no.

Hay varias maneras de medir la exactitud de un modelo de clasificación. Una de las mejores medidas generales para un modelo de clasificación binaria es el área bajo la curva de las características operativas del receptor (a veces denominada "Curva ROC") que básicamente cuantifica con qué frecuencia el modelo hará una predicción correcta independientemente del resultado. En esta unidad, calculará una puntuación de curva ROC para el modelo que ha creado antes y obtendrá información sobre algunas de las razones de por qué esa puntuación es inferior a la salida de precisión media representada por el método score. También aprenderá otras formas de medir la exactitud del modelo.

  1. Antes de calcular la curva ROC, tendrá que generar probabilidades de predicción para el conjunto de prueba. Estas probabilidades son estimaciones de cada una de las clases, o respuestas, que el modelo puede predecir. Por ejemplo, [0.88199435, 0.11800565] significa que hay un 89 % de posibilidades de que un vuelo sea puntual (ARR_DEL15 = 0) y un 12 % de que se retrase (ARR_DEL15 = 1). La suma de las dos probabilidades da como resultado 100 %.

    Ejecute el código siguiente para generar un conjunto de probabilidades de predicción a partir de los datos de prueba:

    from sklearn.metrics import roc_auc_score
    probabilities = model.predict_proba(test_x)
    
  2. Ahora, use la instrucción siguiente para generar una puntuación de curva ROC de las probabilidades mediante el método roc_auc_score de Scikit-learn:

    roc_auc_score(test_y, probabilities[:, 1])
    

    Confirme que en la salida se muestra una puntuación del 67 %:

    Generación de una puntuación AUC

    Generación de una puntuación AUC

    ¿Por qué la puntuación AUC es más baja que la precisión media calculada en el ejercicio anterior?

    En la salida del método score se reflejan cuántos elementos del conjunto de prueba ha predicho correctamente el modelo. Esta puntuación está sesgada por el hecho de que el conjunto de datos con el que se ha entrenado y probado el modelo contiene muchas más filas que representan llegadas puntuales que filas que representan llegadas con retraso. Debido a este desequilibrio en los datos, es más que probable que acierte si predice que un vuelo será puntual que si predice que va a llegar con retraso.

    La curva ROC tiene este hecho en cuenta y proporciona una indicación más precisa de la probabilidad de que una predicción de la llegada puntual o con retraso sea correcta.

  3. Puede obtener más información sobre el comportamiento del modelo si genera una matriz de confusión, también conocida como matriz de error. La matriz de confusión cuantifica el número de veces que cada respuesta se ha clasificado correcta o incorrectamente. En concreto, cuantifica el número de falsos positivos, falsos negativos, verdaderos positivos y verdaderos negativos. Esto es importante porque si un modelo de clasificación binaria entrenado para reconocer gatos y perros se prueba con un conjunto de datos en el que el 95 % son perros, podría puntuar un 95 % simplemente por adivinar "perro" cada vez. Pero si es incapaz de identificar gatos, su valor sería escaso.

    Use el código siguiente para generar una matriz de confusión para el modelo:

    from sklearn.metrics import confusion_matrix
    confusion_matrix(test_y, predicted)
    

    En la primera fila de la salida se representan los vuelos que han sido puntuales. En la primera columna de esa fila se muestran cuántos vuelos se predijeron correctamente como puntuales, mientras que en la segunda se muestran los que se predijeron incorrectamente como retrasados. De esto, el modelo parece estar diseñado para predecir correctamente que un vuelo será puntual.

    Generación de una matriz de confusión

    Generación de una matriz de confusión

    Pero examine la segunda fila, en la que se representan los vuelos que se retrasaron. En la primera columna se muestran cuántos vuelos con retraso se predijeron incorrectamente como puntuales. En la segunda columna se muestran cuántos vuelos se predijeron correctamente como retrasados. Es evidente que el modelo no es tan experto a la hora de predecir que un vuelo se va a retrasar como lo es para predecir que será puntual. Lo que le interesa en una matriz de confusión son números altos en las esquinas superior izquierda e inferior derecha, y números bajos (preferiblemente ceros) en las esquinas superior derecha e inferior izquierda.

  4. Otras medidas de la precisión de un modelo de clasificación son la precisión y la recuperación. Imagine que al modelo se la han proporcionado tres llegadas puntuales y tres con retraso, y que ha predicho correctamente dos de las llegadas puntuales, pero incorrectamente que dos de las llegadas con retraso serían puntuales. En este caso, la precisión sería del 50 % (dos de los cuatro vuelos que ha clasificado como puntuales realmente lo fueron), mientras que su recuperación sería del 67 % (ha identificado correctamente dos de las tres llegadas puntuales). Puede obtener más información sobre la precisión y la recuperación en https://en.wikipedia.org/wiki/Precision_and_recall.

    Scikit-learn contiene un método útil denominado precision_score para calcular la precisión. Para cuantificar la precisión del modelo, ejecute las instrucciones siguientes:

    from sklearn.metrics import precision_score
    
    train_predictions = model.predict(train_x)
    precision_score(train_y, train_predictions)
    

    Examine la salida. ¿Cuál es la precisión del modelo?

    Medición de la precisión

    Medición de la precisión

  5. Scikit-learn también contiene un método denominado recall_score para calcular la recuperación. Para medir la recuperación del modelo, ejecute las instrucciones siguientes:

    from sklearn.metrics import recall_score
    
    recall_score(train_y, train_predictions)
    

    ¿Cuál es la recuperación del modelo?

    Medición de la recuperación

    Medición de la recuperación

  6. Use el comando File -> Save and Checkpoint (Archivo>Guardar y punto de control) para guardar el cuaderno.

En el mundo real, un científico de datos entrenado buscaría formas de que el modelo fuera incluso más preciso. Entre otras cosas, podría probar diferentes algoritmos y tomar medidas para optimizar el algoritmo elegido a fin de determinar la combinación óptima de parámetros. Otro paso probablemente sería expandir el conjunto de datos a millones de filas en lugar de unos pocos miles y también intentar reducir el desequilibrio entre las llegadas con retraso y las puntuales. Pero para nuestros propósitos, el modelo es correcto como está.