次の方法で共有


チュートリアル: R を使用してフライト遅延を予測する

このチュートリアルでは、Microsoft Fabric の Synapse Data Science ワークフローのエンド ツー エンドの例について説明します。 これは、nycflights13 データ、および [R] を使用して、飛行機が 30 分以上遅れて到着するかどうかを予測します。 次に、予測結果を使用して、対話型の Power BI ダッシュボードを構築します。

このチュートリアルでは、次の作業を行う方法について説明します。

  • tidymodels パッケージ (recipesparsniprsampleworkflows) を使用して、データを処理し、機械学習モデルをトレーニングします。
  • 出力データを Delta テーブルとしてレイクハウスに書き込みます。
  • Power BI ビジュアル レポートを構築し、そのレイクハウスのデータに直接アクセスします。

前提条件

  • ノートブックを開くか作成します。 方法については、「Microsoft Fabric ノートブックの使用方法」をご覧ください。

  • 言語オプションを [SparkR (R)] に設定することで、主要言語を変更します。

  • ノートブックをレイクハウスにアタッチします。 左側にある [追加] を選択して、既存のレイクハウスを追加するか、レイクハウスを作成します。

パッケージをインストールする

このチュートリアルのコードを使用するには、nycflights13 パッケージをインストールします。

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

データを検索する

この nycflights13 データには、2013 年にニューヨーク市近郊に到着した 325,819 件のフライトに関する情報が含まれています。 まず、フライトの遅延の分布を表示します。 このグラフは、到着遅延の分布が右に傾いていることを示しています。 高い値にはロング テールがあります。

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

Screenshot that shows a graph of flight delays.

データを読み込み、変数にいくつかの変更を加えます:

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)

モデルを構築する前に、前処理とモデリングの両方で重要な特定の変数をいくつか検討してください。

変数 arr_delay は因子変数です。 ロジスティック回帰モデルをトレーニングするためには、結果変数が因子変数であることが重要です。

glimpse(flight_data)

このデータセット内のフライトの約 16% が 30 分以上遅れて到着してました。

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

この dest 機能には、104 のフライト目的地があります。

unique(flight_data$dest)

16 の異なる航空会社があります。

unique(flight_data$carrier)

データを分割する

この 1 つのデータセットをトレーニング セットとテスト セットの 2 つに分割します。 元のデータセット (ランダムに選択されたサブセットとして) 内のほとんどの行をトレーニング データセット内に保持します。 トレーニング データセットをモデルを使用してモデルを適合させ、テスト データセットを使用してモデルのパフォーマンスを測定します。

rsample パッケージを使用して、データを分割する方法に関する情報を含むオブジェクトを作成します。 次に、もう 2 つの rsample 関数を使用して、トレーニング セットとテスト セット用の DataFrame を作成します:

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)

レシピと役割を作成する

単純なロジスティック回帰モデルのレシピを作成します。 モデルをトレーニングする前に、レシピを使用して新しい予測因子を作成し、モデルに必要な前処理を実行します。

この update_role() 関数を使用して、ID という名前のカスタム役割と共に、このレシピが flighttime_hour が変数であること認識するようにします。 ロールには任意の文字値を指定できます。 この式には、トレーニング セット内の arr_delay 以外のすべての変数が予測子として含まれています。 レシピではこれらの 2 つの ID 変数が保持されますが、結果または予測子としては使用されません。

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

変数とロールの現在のセットを表示するには、summary() 関数を使用します。

summary(flights_rec)

特徴を作成する

モデルを改善するために、特徴量エンジニアリングを行います。 フライトの日付が到着遅延の可能性に相応の影響を及ぼす場合があります。

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

モデルにとって重要になる可能性が高い日付から導かれたモデル項を追加することをお勧めします。 単一の日付変数から次の有意な特徴量を派生させます。

  • 曜日
  • 日付が休日に対応しているかどうか

レシピに次の 3 つの手順を追加します:

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

レシピを使用してモデルを適合させる

ロジスティック回帰を使用してフライト データをモデル化します。 まず、parsnip パッケージを使用してモデル仕様を構築します。

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

次に、workflows パッケージを使用して、parsnip モデル (lr_mod) をレシピ (flights_rec) とバンドルします:

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

flights_wflow

モデルのトレーニング

この関数は、レシピを準備し、得られた予測因子からモデルをトレーニングすることができます:

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

ヘルパー関数 xtract_fit_parsnip()extract_recipe() を使用して、ワークフローからモデルまたはレシピ オブジェクトを抽出します。 たとえば、適合したモデル オブジェクトをプルし、broom::tidy() 関数を使用してモデル係数の整理された tibble を取得します:

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

結果を予測する

predict() へ一回呼び出しすると、トレーニング済みワークフロー (flights_fit) を使用して、未見テスト データで予測をします。 predict() メソッドは、レシピを新しいデータに適用してから、その結果を適合モデルに渡します。

predict(flights_fit, test_data)

predict() からの出力を取得して予測されたクラスを返します (lateon_time)。 ただし、各フライトのクラスの予測確率には、モデルとテスト データを併せて augment() を使用し、それらを一緒に保存します。

flights_aug <- 
  augment(flights_fit, test_data)

データを確認する:

glimpse(flights_aug)

モデルを評価する

これで、クラスの予測確率を含む tibble があります。 最初の数行では、モデルは 5 つの定刻のフライト (.pred_on_time の値は p > 0.50) を正しく予測しました。 ただし、予測する行は合計 81,455 行あります。

結果変数 arr_delay の実際の状態と比較して、モデルが到着遅延をどの程度正しく予測したかを示すメトリックを必要としています。

受信者操作特性曲線 (AUC-ROC) の下の領域をメトリックとして使用します。 yardstick パッケージから、roc_curve()roc_auc() を使用して計算します:

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

Power BI レポートを作成する

モデルの結果は良好です。 次に、フライト遅延の予測結果を使用して、対話型の Power BI ダッシュボードを構築します。 ダッシュボードには、航空会社別のフライト数と目的地別のフライト数が表示されます。 ダッシュボードでは、遅延の予測結果でフィルター処理できます。

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

予測結果データセットに航空会社名と空港名を含めます。

  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)

データを確認する:

glimpse(flights_clean)

データを Spark DataFrame に変換します:

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

レイクハウスの Delta テーブルにデータを書き込みます:

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

Delta テーブルを使用してセマンティック モデルを作成します。

  1. 左側で、[OneLake データ ハブ] を選択します

  2. ご自分のノートブックにアタッチしたレイクハウスを選択します

  3. [開く] を選択します

    Screenshot that shows the button to open a lakehouse.

  4. [新しいセマンティック モデル] を選択します

  5. 新しいセマンティック モデルに [nycflight13] を選択し、[確認] を選択します

  6. セマンティック モデルが作成されます。 [新しいレポート] を選択します

  7. [データ] ペインと [視覚化] ペインからフィールドを選択するか、レポート キャンバスにドラッグして、レポートを作成します。

    Screenshot that shows data and visualization details for a report.

このセクションの先頭に表示されるレポートを作成するには、これらの視覚化とデータを使用します:

  1. 積み上げ横棒グラフの内容:
    1. Y 軸: carrier_name
    2. X 軸: flight。 集計に [カウント] を選択します
    3. 凡例: origin_name
  2. 積み上げ横棒グラフの内容:
    1. Y 軸: dest_name
    2. X 軸: flight。 集計に [カウント] を選択します
    3. 凡例: origin_name
  3. 次のスライサー:
    1. フィールド: _pred_class
  4. 次のスライサー:
    1. フィールド: _pred_late