Självstudie: Använda R för att förutsäga flygfördröjning

I den här självstudien visas ett exempel från slutpunkt till slutpunkt på ett Synapse-Datavetenskap arbetsflöde i Microsoft Fabric. Den använder nycflights13-data och R för att förutsäga om ett plan anländer mer än 30 minuter för sent eller inte. Den använder sedan förutsägelseresultatet för att skapa en interaktiv Power BI-instrumentpanel.

I den här självstudien lär du dig att:

Förutsättningar

  • Öppna eller skapa en notebook-fil. Mer information finns i Använda Microsoft Fabric-notebook-filer.

  • Ange språkalternativet SparkR (R) för att ändra det primära språket.

  • Bifoga anteckningsboken till ett sjöhus. Till vänster väljer du Lägg till för att lägga till ett befintligt sjöhus eller för att skapa ett sjöhus.

Installera paket

Installera paketet nycflights13 för att använda koden i den här självstudien.

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

Utforska data

Uppgifterna nycflights13 har information om 325 819 flygningar som anlände nära New York City 2013. Visa först fördelningen av flygförseningar. Det här diagrammet visar att fördelningen av ankomstfördröjningarna är rätt skev. Den har en lång svans i de höga värdena.

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

Screenshot that shows a graph of flight delays.

Läs in data och gör några ändringar i variablerna:

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)

Innan vi skapar modellen bör du överväga några specifika variabler som är viktiga för både förbearbetning och modellering.

Variabel arr_delay är en faktorvariabel. För träning av logistiska regressionsmodeller är det viktigt att utfallsvariabeln är en faktorvariabel.

glimpse(flight_data)

Cirka 16 % av flygningarna i den här datamängden kom mer än 30 minuter för sent.

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

Funktionen dest har 104 flygdestinationer.

unique(flight_data$dest)

Det finns 16 distinkta transportörer.

unique(flight_data$carrier)

Dela upp data

Dela upp den enskilda datamängden i två uppsättningar: en träningsuppsättning och en testuppsättning . Behåll de flesta raderna i den ursprungliga datamängden (som en slumpmässigt vald delmängd) i träningsdatauppsättningen. Använd träningsdatauppsättningen för att passa modellen och använd testdatauppsättningen för att mäta modellens prestanda.

rsample Använd paketet för att skapa ett objekt som innehåller information om hur du delar upp data. Använd sedan ytterligare rsample två funktioner för att skapa DataFrames för tränings- och testuppsättningarna:

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)

Skapa ett recept och roller

Skapa ett recept för en enkel logistisk regressionsmodell. Innan du tränar modellen använder du ett recept för att skapa nya prediktorer och utför den förbearbetning som modellen kräver.

update_role() Använd funktionen så att recepten vet att flight och time_hour är variabler, med en anpassad roll som heter ID. En roll kan ha valfritt teckenvärde. Formeln innehåller alla variabler i träningsuppsättningen, förutom arr_delay, som prediktorer. Receptet behåller dessa två ID-variabler men använder dem inte som antingen utfall eller prediktorer.

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

Om du vill visa den aktuella uppsättningen variabler och roller använder du summary() funktionen:

summary(flights_rec)

Skapa funktioner

Utför vissa funktioner för att förbättra din modell. Flygdatumet kan ha en rimlig effekt på sannolikheten för en sen ankomst.

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

Det kan bidra till att lägga till modelltermer som härletts från det datum som potentiellt har betydelse för modellen. Härled följande meningsfulla funktioner från variabeln med ett enda datum:

  • Dag i veckan
  • Månad
  • Om datumet motsvarar en helgdag eller inte

Lägg till de tre stegen i receptet:

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())

Anpassa en modell med ett recept

Använd logistisk regression för att modellera flygdata. Skapa först en modellspecifikation med parsnip paketet:

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

workflows Använd paketet för att paketera din parsnip modell (lr_mod) med ditt recept (flights_rec):

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

flights_wflow

Träna modellen

Den här funktionen kan förbereda receptet och träna modellen från de resulterande prediktorerna:

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

Använd hjälpfunktionerna xtract_fit_parsnip() och extract_recipe() för att extrahera modell- eller receptobjekten från arbetsflödet. I det här exemplet hämtar du det anpassade modellobjektet och använder broom::tidy() sedan funktionen för att få en prydlig tibble av modellkoefficienter:

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

Förutsäga resultat

Ett enda anrop till predict() använder det tränade arbetsflödet (flights_fit) för att göra förutsägelser med osedda testdata. Metoden predict() tillämpar receptet på nya data och skickar sedan resultatet till den anpassade modellen.

predict(flights_fit, test_data)

Hämta utdata från predict() för att returnera den förutsagda klassen: late jämfört med on_time. För de förutsagda klassannolikheterna för varje flygning använder du augment() dock med modellen, kombinerat med testdata, för att spara dem tillsammans:

flights_aug <- 
  augment(flights_fit, test_data)

Granska data:

glimpse(flights_aug)

Utvärdera modellen

Vi har nu en tibble med de förutsagda klassannolikheterna. I de första raderna förutsade modellen korrekt fem flygningar i tid (värdena .pred_on_time för är p > 0.50). Vi har dock totalt 81 455 rader att förutsäga.

Vi behöver ett mått som anger hur väl modellen förutsade sena ankomster, jämfört med den verkliga statusen för din utfallsvariabel, arr_delay.

Använd området under curve receiver operating characteristic (AUC-ROC) som mått. Beräkna den med roc_curve() och roc_auc(), från yardstick paketet:

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

Skapa en Power BI-rapport

Modellresultatet ser bra ut. Använd förutsägelseresultatet för flygfördröjning för att skapa en interaktiv Power BI-instrumentpanel. Instrumentpanelen visar antalet flygningar per flygbolag och antalet flygningar per mål. Instrumentpanelen kan filtrera efter resultatet av förutsägelsefördröjningen.

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

Inkludera transportföretagets namn och flygplatsnamn i datauppsättningen för förutsägelseresultatet:

  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)

Granska data:

glimpse(flights_clean)

Konvertera data till en Spark DataFrame:

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

Skriv data till en deltatabell i ditt lakehouse:

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

Använd deltatabellen för att skapa en semantisk modell.

  1. Till vänster väljer du OneLake-datahubben

  2. Välj det sjöhus som du har kopplat till anteckningsboken

  3. Välj Öppna

    Screenshot that shows the button to open a lakehouse.

  4. Välj Ny semantisk modell

  5. Välj nycflight13 för din nya semantiska modell och välj sedan Bekräfta

  6. Din semantiska modell skapas. Välj Ny rapport

  7. Markera eller dra fält från fönstret Data och Visualiseringar till rapportarbetsytan för att skapa rapporten

    Screenshot that shows data and visualization details for a report.

Om du vill skapa rapporten som visas i början av det här avsnittet använder du dessa visualiseringar och data:

  1. Staplat stapeldiagram med:
    1. Y-axel: carrier_name
    2. X-axel: flyg. Välj Antal för aggregeringen
    3. Förklaring: origin_name
  2. Staplat stapeldiagram med:
    1. Y-axel: dest_name
    2. X-axel: flyg. Välj Antal för aggregeringen
    3. Förklaring: origin_name
  3. Utsnitt med:
    1. Fält: _pred_class
  4. Utsnitt med:
    1. Fält: _pred_late