Partager via


Tutoriel : Utiliser R pour prédire le retard des vols

Ce tutoriel présente un exemple de bout en bout d’un flux de travail science des données Synapse dans Microsoft Fabric. Il utilise les données nycflights13 pour prédire si un avion arrive avec plus de 30 minutes de retard. Il utilise ensuite les résultats de la prédiction pour créer un tableau de bord Power BI interactif.

Dans ce tutoriel, vous allez apprendre à :

  • Utilisez des packages tidymodels (recipes, parsnip, rsample, workflows) pour traiter les données et entraîner un modèle Machine Learning
  • Inscrivez les données de sortie dans un lakehouse sous la forme d’une table delta
  • Générer un rapport visuel Power BI pour accéder directement aux données de ce lakehouse

Prérequis

  • Ouvrez ou créez un notebook. Pour en savoir plus, consultez Comment utiliser les blocs-notes Microsoft Fabric.

  • Réglez l’option de langue sur SparkR (R) pour modifier la langue principale.

  • Attachez votre cahier à une cabane au bord du lac. Sur le côté gauche, sélectionnez Ajouter pour ajouter un lakehouse existant ou pour créer un lakehouse.

Installer des packages

Installez le package nycflights13 pour utiliser le code de ce tutoriel.

install.packages("nycflights13")
# Load the packages
library(tidymodels)      # For tidymodels packages
library(nycflights13)    # For flight data

Exploration des données

Les données nycflights13 contiennent des informations sur 325 819 vols qui sont arrivés près de New York en 2013. Tout d’abord, regardez la répartition des retards des vols. Ce graphique montre que la distribution des retards à l’arrivée est asymétrique à droite. Il a une longue queue dans les valeurs élevées.

ggplot(flights, aes(arr_delay)) + geom_histogram(color="blue", bins = 300)

Screenshot that shows a graph of flight delays.

Chargez les données et apportez quelques modifications aux variables :

set.seed(123)

flight_data <- 
  flights %>% 
  mutate(
    # Convert the arrival delay to a factor
    arr_delay = ifelse(arr_delay >= 30, "late", "on_time"),
    arr_delay = factor(arr_delay),
    # You'll use the date (not date-time) for the recipe that you'll create
    date = lubridate::as_date(time_hour)
  ) %>% 
  # Include weather data
  inner_join(weather, by = c("origin", "time_hour")) %>% 
  # Retain only the specific columns that you'll use
  select(dep_time, flight, origin, dest, air_time, distance, 
         carrier, date, arr_delay, time_hour) %>% 
  # Exclude missing data
  na.omit() %>% 
  # For creating models, it's better to have qualitative columns
  # encoded as factors (instead of character strings)
  mutate_if(is.character, as.factor)

Avant de générer le modèle, prenez en compte quelques variables spécifiques qui sont importantes à la fois pour le prétraitement et la modélisation.

La variable arr_delay est une variable factorielle. Pour la formation au modèle de régression logistique, il est important que la variable de résultat soit une variable factorielle.

glimpse(flight_data)

Environ 16 % des vols de ce jeu de données sont arrivés avec plus de 30 minutes de retard.

flight_data %>% 
  count(arr_delay) %>% 
  mutate(prop = n/sum(n))

La fonctionnalité dest comporte 104 destinations de vol.

unique(flight_data$dest)

Il existe 16 transporteurs distincts.

unique(flight_data$carrier)

Fractionner les données

Fractionnez le jeu de données unique en deux jeux : un jeu de formation et un jeu de test. Conservez la plupart des lignes de l’ensemble de données original (sous la forme d’un sous-ensemble choisi au hasard) dans le jeu de données de formation. Utilisez le jeu de données d’entraînement pour ajuster le modèle et utilisez le jeu de données de test pour mesurer les performances du modèle.

Utilisez le package rsample pour créer un objet contenant des informations sur la manière de fractionner les données. Ensuite, utilisez deux autres fonctions rsample pour créer des DataFrames pour les ensembles de formation et de test :

set.seed(123)
# Keep most of the data in the training set 
data_split <- initial_split(flight_data, prop = 0.75)

# Create DataFrames for the two sets:
train_data <- training(data_split)
test_data  <- testing(data_split)

Créer une recette et des rôles

Créez une recette pour un modèle de régression logistique simple. Avant d’entraîner le modèle, utilisez une recette pour créer de nouveaux prédicteurs et effectuez le prétraitement requis par le modèle.

Utilisez la fonction update_role() pour que les recettes sachent que flight et time_hour sont des variables, avec un rôle personnalisé appelé ID. Un rôle peut avoir n’importe quelle valeur de caractère. La formule inclut toutes les variables du jeu d’apprentissage, autres que arr_delay, en tant que prédicteurs. La recette conserve ces deux variables d’ID, mais ne les utilise pas comme résultats ou prédicteurs.

flights_rec <- 
  recipe(arr_delay ~ ., data = train_data) %>% 
  update_role(flight, time_hour, new_role = "ID") 

Pour afficher l’ensemble actuel de variables et de rôles, utilisez la fonction summary() :

summary(flights_rec)

Création de caractéristiques

Effectuez une ingénierie des fonctionnalités pour améliorer votre modèle. La date du vol peut avoir un effet raisonnable sur la probabilité d’une arrivée tardive.

flight_data %>% 
  distinct(date) %>% 
  mutate(numeric_date = as.numeric(date)) 

Il peut être utile d’ajouter des termes de modèle dérivés de la date qui peuvent avoir de l’importance pour le modèle. Dérivez les fonctionnalités significatives suivantes de la variable de date unique :

  • Jour de la semaine
  • Month
  • Indique si la date correspond ou non à un jour férié

Ajoutez les trois étapes à votre recette :

flights_rec <- 
  recipe(arr_delay ~ ., data = train_data) %>% 
  update_role(flight, time_hour, new_role = "ID") %>% 
  step_date(date, features = c("dow", "month")) %>%               
  step_holiday(date, 
               holidays = timeDate::listHolidays("US"), 
               keep_original_cols = FALSE) %>% 
  step_dummy(all_nominal_predictors()) %>% 
  step_zv(all_predictors())

Ajuster un modèle avec une recette

Utilisez la régression logistique pour modéliser les données de vol. Tout d’abord, générez une spécification de modèle avec le package parsnip :

lr_mod <- 
  logistic_reg() %>% 
  set_engine("glm")

Utilisez le package workflows pour regrouper votre modèle parsnip (lr_mod) avec votre recette (flights_rec) :

flights_wflow <- 
  workflow() %>% 
  add_model(lr_mod) %>% 
  add_recipe(flights_rec)

flights_wflow

Formation du modèle

Cette fonction permet de préparer la recette et d’entraîner le modèle à partir des prédicteurs obtenus :

flights_fit <- 
  flights_wflow %>% 
  fit(data = train_data)

Utilisez les fonctions d’assistance xtract_fit_parsnip() et extract_recipe() pour extraire les objets de modèle ou de recette du flux de travail. Dans cet exemple, tirez l’objet modèle ajusté, puis utilisez la fonction broom::tidy() pour obtenir un tableau ordonné des coefficients du modèle :

flights_fit %>% 
  extract_fit_parsnip() %>% 
  tidy()

Prédire les résultats

Un seul appel à predict() utilise le flux de travail formé (flights_fit) pour faire des prédictions avec les données d’essai non consulté. La méthode predict() applique la recette aux nouvelles données, puis transmet les résultats au modèle ajusté.

predict(flights_fit, test_data)

Obtenez la sortie de predict() pour rendre la classe prédite : late contre on_time. Cependant, pour les probabilités de classe prédites pour chaque vol, utilisez augment() avec le modèle, combiné aux données d’essai, pour les sauvegarder ensemble :

flights_aug <- 
  augment(flights_fit, test_data)

Passez en revue les données :

glimpse(flights_aug)

Évaluer le modèle

Nous avons maintenant un tibble avec les probabilités de classe prédites. Dans les premières lignes, le modèle a correctement prédit cinq vols à l’heure (les valeurs de .pred_on_time sont p > 0.50). Toutefois, nous avons 81 455 lignes au total à prédire.

Nous avons besoin d’une mesure qui indique dans quelle mesure le modèle a prédit les arrivées tardives, par rapport à l’état réel de votre variable de résultat, arr_delay.

Utilisez la caractéristique de fonctionnement du récepteur de l’aire sous la courbe (AUC-ROC) comme mesure. Calculez-le avec roc_curve() et roc_auc(), à partir du package yardstick :

flights_aug %>% 
  roc_curve(truth = arr_delay, .pred_late) %>% 
  autoplot()

Générer un rapport Power BI

Le résultat du modèle semble bon. Utilisez les résultats de la prédiction des retards de vols pour créer un tableau de bord Power BI interactif. Le tableau de bord indique le nombre de vols par transporteur et le nombre de vols par destination. Le tableau de bord peut être filtré en fonction des résultats de la prédiction des retards.

Screenshot that shows bar charts for number of flights by carrier and number of flights by destination in a Power BI report.

Incluez le nom du transporteur et le nom de l’aéroport dans les jeux de données des résultats de la prédiction :

  flights_clean <- flights_aug %>% 
  # Include the airline data
  left_join(airlines, c("carrier"="carrier"))%>% 
  rename("carrier_name"="name") %>%
  # Include the airport data for origin
  left_join(airports, c("origin"="faa")) %>%
  rename("origin_name"="name") %>%
  # Include the airport data for destination
  left_join(airports, c("dest"="faa")) %>%
  rename("dest_name"="name") %>%
  # Retain only the specific columns you'll use
  select(flight, origin, origin_name, dest,dest_name, air_time,distance, carrier, carrier_name, date, arr_delay, time_hour, .pred_class, .pred_late, .pred_on_time)

Passez en revue les données :

glimpse(flights_clean)

Convertissez les données en DataFrame Spark :

sparkdf <- as.DataFrame(flights_clean)
display(sparkdf)

Inscrivez les données dans une table delta dans votre lakehouse :

# Write data into a delta table
temp_delta<-"Tables/nycflight13"
write.df(sparkdf, temp_delta ,source="delta", mode = "overwrite", header = "true")

Utilisez la table delta pour créer un modèle sémantique.

  1. Sur la gauche, sélectionnez Hub de données OneLake

  2. Sélectionnez le Lakehouse que vous avez attaché à votre notebook

  3. Sélectionnez Ouvrir

    Screenshot that shows the button to open a lakehouse.

  4. Sélectionnez Nouveau modèle sémantique

  5. Sélectionnez nycflight13 pour votre nouveau modèle sémantique, puis sélectionnez Confirmer

  6. Votre modèle sémantique est créé. Sélectionnez Nouveau rapport

  7. Sélectionnez ou faites glisser des champs des volets Données et Visualisations vers le canevas du rapport pour générer votre rapport

    Screenshot that shows data and visualization details for a report.

Pour créer le rapport présenté au début de cette section, utilisez ces visualisations et ces données :

  1. Graphique à barres empilées avec :
    1. Axe Y : carrier_name
    2. Axe X : vol. Sélectionnez Compte pour l’agrégation
    3. Légende : origin_name
  2. Graphique à barres empilées avec :
    1. Axe Y : dest_name
    2. Axe X : vol. Sélectionnez Compte pour l’agrégation
    3. Légende : origin_name
  3. Segment avec :
    1. Champ : _pred_class
  4. Segment avec :
    1. Champ : _pred_late