Partilhar via


Tutorial: Use R para prever o atraso do voo

Este tutorial apresenta um exemplo completo de um fluxo de trabalho Synapse Data Science no Microsoft Fabric. Ele usa os nycflights13 dados e da R para prever se um avião chega com mais de 30 minutos de atraso. Em seguida, ele usa os resultados da previsão para criar um painel interativo do Power BI.

Neste tutorial, você aprenderá a:

  • Use tidymodels packages (recipes, parsnip, rsample, workflows) para processar dados e treinar um modelo de aprendizado de máquina
  • Gravar os dados de saída num lakehouse como uma tabela Delta
  • Criar um relatório visual no Power BI para aceder diretamente aos dados nesse lakehouse.

Pré-requisitos

  • Obtenha uma assinatura Microsoft Fabric. Ou inscreva-se para obter uma avaliação gratuita do Microsoft Fabric.

  • Inicie sessão no Microsoft Fabric.

  • Use o seletor de experiência no canto inferior esquerdo da página inicial para alternar para o Fabric.

    Captura de tela do menu do seletor de experiências, mostrando onde selecionar Ciência de Dados.

  • Abra ou crie um bloco de notas. Para saber como, consulte Como usar blocos de anotações do Microsoft Fabric.

  • Defina a opção de idioma como SparkR (R) para alterar o idioma principal.

  • Ligue o seu bloco de notas a uma casa no lago. No lado esquerdo, selecione Adicionar Adicionar para adicionar uma casa de lago existente ou para criar uma casa de lago.

Instalar pacotes

Instale o pacote nycflights13 para usar o código neste tutorial.

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

Explore os dados

Os dados da nycflights13 têm informações sobre 325.819 voos que chegaram perto de Nova York em 2013. Primeiro, veja a distribuição de atrasos de voos. Este gráfico mostra que a distribuição dos atrasos de chegada é enviesada para a direita. Apresenta uma cauda longa nos valores altos.

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

Captura de tela que mostra um gráfico de atrasos de voos.

Carregue os dados e faça algumas alterações nas variáveis:

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)

Antes de construirmos o modelo, considere algumas variáveis específicas que são importantes tanto para o pré-processamento quanto para a modelagem.

A variável arr_delay é uma variável fatorial. Para o treinamento do modelo de regressão logística, é importante que a variável de resultado seja uma variável fatorial.

glimpse(flight_data)

Cerca de 16% dos voos deste conjunto de dados chegaram com mais de 30 minutos de atraso.

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

A funcionalidade dest possui 104 destinos de voos.

unique(flight_data$dest)

Existem 16 transportadoras distintas.

unique(flight_data$carrier)

Dividir os dados

Divida o conjunto de dados único em dois conjuntos: um conjunto de treinamento e um conjunto de teste. Mantenha a maioria das linhas no conjunto de dados original (como um subconjunto escolhido aleatoriamente) no conjunto de dados de treinamento. Use o conjunto de dados de treinamento para ajustar o modelo e use o conjunto de dados de teste para medir o desempenho do modelo.

Use o pacote rsample para criar um objeto que contenha informações sobre como dividir os dados. Em seguida, use mais duas funções rsample para criar DataFrames para os conjuntos de treinamento e teste:

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)

Criar uma receita e funções

Crie uma receita para um modelo de regressão logística simples. Antes de treinar o modelo, use uma receita para criar novos preditores e realize o pré-processamento que o modelo exige.

Use a função update_role() para que as receitas saibam que flight e time_hour são variáveis, com uma função personalizada chamada ID. Uma função pode ter qualquer valor de carácter. A fórmula inclui todas as variáveis no conjunto de treinamento, exceto arr_delay, como preditores. A receita mantém essas duas variáveis de identificação, mas não as usa como resultados ou preditores.

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

Para exibir o conjunto atual de variáveis e funções, use a função summary():

summary(flights_rec)

Criar funcionalidades

Faça alguma engenharia de recursos para melhorar seu modelo. A data do voo pode ter um efeito razoável na probabilidade de uma chegada tardia.

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

Pode ser útil adicionar termos de modelo derivados da data que potencialmente tenham importância para o modelo. Derive os seguintes recursos significativos da variável de data única:

  • Dia da semana
  • Mês
  • Se a data corresponde ou não a um feriado

Adicione os três passos à sua receita:

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

Ajuste um modelo com uma receita

Use regressão logística para modelar os dados de voo. Primeiro, construa uma especificação de modelo com o pacote parsnip:

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

Utilize a embalagem workflows para agrupar o seu modelo de parsnip (lr_mod) com a sua receita (flights_rec):

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

flights_wflow

Treinar o modelo

Esta função pode preparar a receita e treinar o modelo a partir dos preditores resultantes:

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

Use as funções auxiliares xtract_fit_parsnip() e extract_recipe() para extrair os objetos de modelo ou receita do fluxo de trabalho. Neste exemplo, puxe o objeto de modelo ajustado e, em seguida, use a função broom::tidy() para obter um tibble arrumado de coeficientes de modelo:

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

Prever resultados

Uma única chamada para predict() usa o fluxo de trabalho treinado (flights_fit) para fazer previsões com os dados de teste invisíveis. O método predict() aplica a receita aos novos dados e, em seguida, passa os resultados para o modelo ajustado.

predict(flights_fit, test_data)

Obtenha a saída de predict() para retornar a classe prevista: late versus on_time. No entanto, para as probabilidades de classe previstas para cada voo, use augment() juntamente com o modelo e os dados de teste, para salvá-los em conjunto:

flights_aug <- 
  augment(flights_fit, test_data)

Analise os dados:

glimpse(flights_aug)

Avaliar o modelo

Agora temos um tibble com as previsões das probabilidades de classe. Nas primeiras filas, o modelo previu corretamente cinco voos pontuais (valores de .pred_on_time são p > 0.50). No entanto, temos um total de 81.455 linhas para prever.

Precisamos de uma métrica que diga quão bem o modelo previu chegadas tardias, em comparação com o verdadeiro status da sua variável de resultado, arr_delay.

Use a Área Sob a Curva da Característica de Operação do Receptor (AUC-ROC) como métrica. Calcule-o com roc_curve() e roc_auc(), a partir do pacote yardstick:

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

Criar um relatório do Power BI

O resultado do modelo parece bom. Use os resultados da previsão de atraso de voo para criar um painel interativo do Power BI. O painel mostra o número de voos por companhia aérea e o número de voos por destino. O painel pode filtrar com base nos resultados da previsão de atrasos.

Captura de ecrã que mostra gráficos de barras para o número de voos por transportadora e o número de voos por destino num relatório do Power BI.

Inclua o nome da transportadora e o nome do aeroporto no conjunto de dados do resultado da previsão:

  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)

Analise os dados:

glimpse(flights_clean)

Converta os dados em um DataFrame do Spark:

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

Escreva os dados em uma tabela delta em sua casa do lago:

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

Use a tabela delta para criar um modelo semântico.

  1. À esquerda, selecione OneLake

  2. Selecione a casa do lago que você anexou ao seu bloco de anotações

  3. Selecione Abrir

    Captura de tela que mostra o botão para abrir uma casa do lago.

  4. Selecione Novo modelo semântico

  5. Selecione nycflight13 para o seu novo modelo semântico e, em seguida, selecione Confirmar

  6. Seu modelo semântico é criado. Selecione Novo Relatório

  7. Selecione ou arraste campos dos painéis Data e Visualizações para a tela do relatório para criar seu relatório

    Captura de tela que mostra dados e detalhes de visualização de um relatório.

Para criar o relatório mostrado no início desta seção, use estas visualizações e dados:

  1. Gráfico de barras empilhado com:
    1. Eixo Y: carrier_name
    2. Eixo X: voo. Selecione Contagem para a agregação
    3. Legenda: origin_name
  2. Gráfico de barras empilhado com:
    1. Eixo Y: dest_name
    2. Eixo X: voo. Selecione contagem para a agregação
    3. Legenda: origin_name
  3. Segmentação de dados com:
    1. Domínio: _pred_class
  4. Segmentação de dados com:
    1. Domínio: _pred_late