Tutorial: Usar o R para prever o atraso do voo
Este tutorial apresenta um exemplo de ponta a ponta de um fluxo de trabalho de Ciência de Dados do Synapse no Microsoft Fabric. Ele usa os dados nycflights13 e R para prever se um avião chega ou não 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 pacotes tidymodels (recipes, parsnip, rsample, fluxos de trabalho) para processar dados e treinar um modelo de machine learning
- Gravar os dados de saída em um lakehouse no formato de uma tabela delta
- Criar um relatório visual do Power BI para acessar diretamente os dados naquele lakehouse
Pré-requisitos
Obtenha uma assinatura do Microsoft Fabric . Ou cadastre-se para uma avaliação gratuita do Microsoft Fabric.
Entre no Microsoft Fabric.
Use o botão de alternância de experiência no canto inferior esquerdo da página inicial para mudar para o Fabric.
Abra ou crie um bloco de anotações. Para saber como, confira Como usar notebooks do Microsoft Fabric.
Defina a opção de idioma para SparkR (R) para alterar o idioma primário.
Anexe seu notebook a um lakehouse. No lado esquerdo, selecione Adicionar para adicionar um lakehouse existente ou para criar um.
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
Explorar os dados
Os dados nycflights13
têm informações sobre 325.819 voos que chegaram perto de Nova York em 2013. Primeiro, exiba a distribuição de atrasos de voo. Este grafo mostra que a distribuição dos atrasos de chegada está distorcida para a direita. Ele tem uma cauda longa nos valores altos.
ggplot(flights, aes(arr_delay)) + geom_histogram(color="blue", bins = 300)
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 criarmos o modelo, considere algumas variáveis específicas importantes para pré-processamento e modelagem.
A variável arr_delay
é uma variável de fator. Para o treinamento do modelo de regressão logística, é importante que a variável de resultado seja uma variável de fator.
glimpse(flight_data)
Cerca de 16% dos voos neste conjunto de dados chegaram com mais de 30 minutos de atraso.
flight_data %>%
count(arr_delay) %>%
mutate(prop = n/sum(n))
O recurso dest
tem 104 destinos de voo.
unique(flight_data$dest)
Há 16 transportadoras distintas.
unique(flight_data$carrier)
Dividir os dados
Divida o conjunto de dados 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 necessário para o modelo.
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
. Um papel pode ter qualquer valor de caractere. 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 ID, 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 sobre a probabilidade de uma chegada tardia.
flight_data %>%
distinct(date) %>%
mutate(numeric_date = as.numeric(date))
Pode ajudar a adicionar termos de modelo derivados da data que potencialmente têm importância para o modelo. Derivar 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 as três etapas à 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 a regressão logística para modelar os dados de voo. Primeiro, crie uma especificação de modelo com o pacote parsnip
:
lr_mod <-
logistic_reg() %>%
set_engine("glm")
Use o pacote workflows
para agrupar seu modelo de parsnip
(lr_mod
) com sua receita (flights_rec
):
flights_wflow <-
workflow() %>%
add_model(lr_mod) %>%
add_recipe(flights_rec)
flights_wflow
Treinar o modelo
Essa função pode preparar a receita e treinar o modelo 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, extraia o objeto de modelo ajustado e, em seguida, use a função broom::tidy()
para obter um tibble organizado 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 não vistos. 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()
com o modelo, combinado com os dados de teste, para salvá-los juntos:
flights_aug <-
augment(flights_fit, test_data)
Examine os dados:
glimpse(flights_aug)
Avaliar o modelo
Agora temos um tibble com as probabilidades de classe previstas. Nas primeiras linhas, o modelo previu corretamente cinco voos no horário (os valores de .pred_on_time
são p > 0.50
). No entanto, temos 81.455 linhas no total para prever.
Precisamos de uma métrica que informe o quão bem o modelo previu chegadas tardias, em comparação com o status verdadeiro da variável de resultado, arr_delay
.
Utilize a Área Sob a Curva da Característica de Operação do Receptor (AUC-ROC) como métrica. Compute-o com roc_curve()
e roc_auc()
, 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 os resultados da previsão de atraso.
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)
Examine 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 seu lakehouse:
# 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.
À esquerda, selecione OneLake
Selecione o lakehouse que você anexou ao notebook
Selecione Abrir
Selecione Novo modelo semântico
Selecione nycflight13 para seu novo modelo semântico e selecione Confirmar
Seu modelo semântico é criado. Selecione Novo relatório
Selecione ou arraste campos dos painéis de Dados e Visualizações para a tela do relatório e crie seu relatório
Para criar o relatório mostrado no início desta seção, use estas visualizações e dados:
Gráfico de barras empilhadas com:
- Eixo Y: carrier_name
- Eixo X: voo. Selecione Count para a agregação
- Legenda: origin_name
Gráfico de barras empilhadas com:
- Eixo Y: dest_name
- Eixo X: voo. Selecione Count para a agregação
- Legenda: origin_name
Segmentação com:
- Campo: _pred_class
Segmentação com:
- Campo: _pred_late