Upgrade to Pro — share decks privately, control downloads, hide ads and more …

tidymodelsによるtidyな機械学習 / Japan.R 2019

tidymodelsによるtidyな機械学習 / Japan.R 2019

2019年12月7日に行われたJapan.R 2019での発表資料です
https://japanr.connpass.com/event/154070/

森下光之助

December 07, 2019
Tweet

More Decks by 森下光之助

Other Decks in Programming

Transcript

  1. tidymodelsによる
    tidyな機械学習
    2019/12/7
    Japan.R 2019
    森下光之助(@dropout009)

    View Slide

  2. tidymodels︓tidyなやり⽅で機械学習が⾏えるパッケージ群
    ü rsample︓Train/Test、Cross Validationなどのデータ分割
    ü recipe︓データの前処理、特徴量エンジニアリング
    ü parsnip︓モデル構築と学習
    ü tune︓ハイパーパラメータのチューニング
    ü yardstic :モデルの精度評価

    View Slide

  3. tidymodelsパッケージの読み込み
    library(tidymodels)
    library(tune)
    > library(tidymodels)
    Registered S3 method overwritten by 'xts':
    method from
    as.zoo.xts zoo
    ─ Attaching packages ─────────────── tidymodels 0.0.3 ─
    ✔ broom 0.5.2 ✔ purrr 0.3.3
    ✔ dials 0.0.3.9002 ✔ recipes 0.1.7.9001
    ✔ dplyr 0.8.3 ✔ rsample 0.0.5
    ✔ ggplot2 3.2.1 ✔ tibble 2.1.3
    ✔ infer 0.5.1 ✔ yardstick 0.0.4
    ✔ parsnip 0.0.4.9000
    ─ Conflicts ───────────────── tidymodels_conflicts() ─
    ✖ purrr::discard() masks scales::discard()
    ✖ dplyr::filter() masks stats::filter()
    ✖ dplyr::lag() masks stats::lag()
    ✖ ggplot2::margin() masks dials::margin()
    ✖ dials::offset() masks stats::offset()
    ✖ recipes::step() masks stats::step()
    ✖ recipes::yj_trans() masks scales::yj_trans()
    tune以外は
    library(tidymodels)で
    ⼀括読み込みできる

    View Slide

  4. 今回はサンプルデータとしてAmesHousingを使⽤
    df = AmesHousing::make_ames()
    > df %>%
    + select(Sale_Price, everything())
    # A tibble: 2,930 x 81
    Sale_Price MS_SubClass MS_Zoning Lot_Frontage Lot_Area Street Alley

    1 215000 One_Story_… Resident… 141 31770 Pave No_A…
    2 105000 One_Story_… Resident… 80 11622 Pave No_A…
    3 172000 One_Story_… Resident… 81 14267 Pave No_A…
    4 244000 One_Story_… Resident… 93 11160 Pave No_A…
    5 189900 Two_Story_… Resident… 74 13830 Pave No_A…
    6 195500 Two_Story_… Resident… 78 9978 Pave No_A…
    7 213500 One_Story_… Resident… 41 4920 Pave No_A…
    8 191500 One_Story_… Resident… 43 5005 Pave No_A…
    9 236500 One_Story_… Resident… 39 5389 Pave No_A…
    10 189000 Two_Story_… Resident… 60 7500 Pave No_A…
    # … with 2,920 more rows, and 74 more variables:
    Sale Priceを予測したい

    View Slide

  5. rsampleでデータを分割
    split = initial_split(df, prop = 0.8)
    df_train = training(split)
    df_test = testing(split)
    df_cv = vfold_cv(df_train, v = 5)
    > df_cv
    # 5-fold cross-validation
    # A tibble: 5 x 2
    splits id

    1 Fold1
    2 Fold2
    3 Fold3
    4 Fold4
    5 Fold5
    Train/Testの分割
    Trainをさらに
    CVとして5分割

    View Slide

  6. recipeでデータの前処理
    rec = recipe(Sale_Price ~ ., data = df_train) %>%
    step_log(Sale_Price)
    > rec
    Data Recipe
    Inputs:
    role #variables
    outcome 1
    predictor 80
    Operations:
    Log transformation on Sale_Price
    recipeで前処理⾏う
    今回はターゲットの対数をとった

    View Slide

  7. parsnipでモデルを作成
    model = rand_forest(mode = "regression",
    trees = 500,
    min_n = tune(),
    mtry = tune()) %>%
    set_engine(engine = "ranger",
    num.threads = parallel::detectCores(),
    seed = 42)
    > model
    Random Forest Model Specification (regression)
    Main Arguments:
    mtry = tune()
    trees = 500
    min_n = tune()
    Engine-Specific Arguments:
    num.threads = parallel::detectCores()
    seed = 42
    Computational engine: ranger
    parsnipでモデルを指定する
    今回はRF
    探索したいハイパーパラメータ
    はtune()としておく
    どのRFパッケージを使うかは
    set_engine()で指定
    パッケージ固有のパラメータ
    もここで指定

    View Slide

  8. tuneで探索するハイパーパラメータとその範囲を指定
    params = list(min_n = min_n(range = c(1, 20)),
    mtry = mtry(range(5, 20))) %>%
    parameters()
    > params
    Collection of 2 parameters for tuning
    id parameter type object class
    min_n min_n nparam[+]
    mtry mtry nparam[+]
    探索したいハイパーパラメータと
    その範囲をリストに

    View Slide

  9. tuneでハイパーパラメータを探索
    df_tuned = tune_bayes(
    rec,
    model = model,
    resamples = df_cv,
    param_info = params,
    initial = 5,
    iter = 50,
    metrics = metric_set(rsq),
    control = control_bayes(no_improve = 10, verbose = TRUE))
    > df_tuned
    # 5-fold cross-validation
    # A tibble: 90 x 5
    splits id .metrics .notes .iter
    *
    1 Fold1 0
    2 Fold2 0
    3 Fold3 0
    4 Fold4 0
    5 Fold5 0
    # … with 80 more rows
    ハイパーパラメータの探索
    今回はベイズ最適化で探す

    View Slide

  10. ハイパーパラメータの探索結果を確認(tune)
    df_best_result = df_tuned %>%
    show_best(metric = "rsq", n_top = 3, maximize = TRUE)
    > df_best_result
    # A tibble: 3 x 8
    mtry min_n .iter .metric .estimator mean n std_err

    1 14 1 4 rsq standard 0.896 5 0.00356
    2 20 1 10 rsq standard 0.896 5 0.00324
    3 20 4 0 rsq standard 0.896 5 0.00325
    特に精度の良かった
    ハイパーパラメータを確認
    mtry=14, min_n=1
    で最⾼の精度

    View Slide

  11. 最も精度の良かったハイパーパラメータをモデルにセット(parsnip)
    df_best_param = df_tuned %>%
    select_best(metric = "rsq", maximize = TRUE)
    model_best = model %>%
    update(df_best_param)
    > model_best
    Random Forest Model Specification (regression)
    Main Arguments:
    mtry = 14
    trees = 500
    min_n = 1
    Engine-Specific Arguments:
    num.threads = parallel::detectCores()
    seed = 42
    Computational engine: ranger
    特に精度の良かった
    ハイパーパラメータを
    モデルにセット

    View Slide

  12. 全Trainデータで再学習し、Testデータで予測(recipe, parsnip)
    preped_rec = rec %>% prep()
    df_train_baked = preped_rec %>% juice()
    df_test_baked = preped_rec %>% bake(df_test)
    fitted_model = model_best %>%
    fit(Sale_Price ~ ., data = df_train_baked)
    df_pred = df_test_baked %>%
    bind_cols(fitted_model %>%
    predict(new_data = df_test_baked))
    レシピをTrainに適⽤
    レシピをTestに適⽤
    Trainで学習
    Testで予測

    View Slide

  13. yardsticでTestデータでの精度を確認
    df_eval = df_pred %>%
    metrics(Sale_Price, .pred)
    > df_eval
    # A tibble: 3 x 3
    .metric .estimator .estimate

    1 rmse standard 0.120
    2 rsq standard 0.903
    3 mae standard 0.0816
    Testデータでの予測精度を計算
    モデルの予測値と実際のSale Price

    View Slide

  14. まとめ︓tidymodels使うとtidyなやり⽅で機械学習が⾏える
    ü rsample︓Train/Test、Cross Validationなどのデータ分割
    ü recipe︓データの前処理、特徴量エンジニアリング
    ü parsnip︓モデル構築と学習
    ü tune︓ハイパーパラメータのチューニング
    ü yardstic :モデルの精度評価

    View Slide

  15. 参考⽂献
    • tidymodelsによるモデル構築と運⽤ / tidymodels
    https://speakerdeck.com/s_uryu/tidymodels
    • tidymodelsによるtidyな機械学習(その1︓データ分割と前処理から学習と性能評価まで)
    https://dropout009.hatenablog.com/entry/2019/01/06/124932
    • tidymodelsによるtidyな機械学習(その3︓ハイパーパラメータのチューニング)
    https://dropout009.hatenablog.com/entry/2019/11/10/125650
    • General Resampling Infrastructure • rsample
    https://tidymodels.github.io/rsample/
    • Preprocessing Tools to Create Design Matrices • recipes
    https://tidymodels.github.io/recipes/
    • A Common API to Modeling and Analysis Functions • parsnip
    https://tidymodels.github.io/parsnip/
    • Tidy Characterizations of Model Performance • yardstick
    https://tidymodels.github.io/yardstick/
    • Tidy Tuning Tools • tune
    https://tidymodels.github.io/tune/index.html

    View Slide