$30 off During Our Annual Pro Sale. View Details »

Tokyo.Rも100回目なので、 そろそろPythonと仲良くしたい

bob3bob3
July 20, 2022

Tokyo.Rも100回目なので、 そろそろPythonと仲良くしたい

RMarkdownの中でRとPythonを同時に使う事例の紹介。
前処理はRで、機械学習はPythonで、可視化と評価はRで行う。
機械学習には Optuna LightGBM Tuner を使っています。

bob3bob3

July 20, 2022
Tweet

More Decks by bob3bob3

Other Decks in Science

Transcript

  1. Tokyo.Rも100回目なので、
    そろそろPythonと仲良くしたい
    Tokyo.R #100 (2022/07/23)
    @bob3bob3

    View Slide

  2. Tokyo.R100回開催!
    おめでとうございます!

    View Slide

  3. 第1回から参加してます!

    View Slide

  4. View Slide

  5. 「パーマーステーションのペンギンたち」
    ● 脱初心者のセッションをシリーズで展開中。
    ● 次回は「データクリーニング編」の予定。

    View Slide

  6. ここから本題

    View Slide

  7. RとPythonと言えば永遠のライバル!

    View Slide

  8. Tokyo.Rも100回目なので、そろそろPythonと仲良くしたい。

    View Slide

  9. RMarkdownとreticulateパッケージでPythonと仲良くできます!

    View Slide

  10. 例えばこんな時
    ● LightGBMを使いたい。
    ● 機械学習はやっぱりPythonが得意。Optuna LightGBM Tuner というハイパーパ
    ラメータの自動最適化までいい感じに実行してくれるモジュールがあり、正直うらや
    ましい。
    ● でも、データの前処理はRの方が圧倒的に便利。
    ● 可視化にはやっぱりggplot2を使いたい。
    ● 「前処理はR」|>「機械学習はPython」|>「可視化はR」ってできないの?

    View Slide

  11. RMarkdownを使うと簡単にできます
    ● RMarkdown上でRとPythonを同居させることができます。
    ● 今回は palmerpenguins の penguins_raw データセットを題材に、ペンギンの種
    類を判別するモデル(多クラス分類)をOptunaを使って実行してみます。
    ● Pythonの基本や環境設定については応用セッションのやわらかクジラさんの発表
    を参考にしてください。Pythonと必要なモジュールはインストール済みの前提でお
    話しします。

    View Slide

  12. 1. Rで前処理
    Rで実行したいのは以下の処理です。
    ● クリーニング
    ○ 変数名をスネークケースに統一
    ○ 必要な変数に絞る
    ● LightGBM用に整形
    ○ 名義尺度であるペンギンの種類、性別、居住する島を ゼロから始まる整数型 に変換。
    ● 学習用データと検証用データに分割
    ● 説明変数群と目的変数に分割

    View Slide

  13. Rのターン

    View Slide

  14. 1. Rで前処理
    ```{r library, include=FALSE}
    library(tidyverse) # データ操作全般
    library(palmerpenguins) # デモデータ
    library(janitor) # データクリーニング
    library(rsample) # 学習データと検証データの分割
    library(withr) # 乱数種の制御
    library(reticulate) # RとPythonのやり取り
    library(MLmetrics) # モデル評価指標
    ```

    View Slide

  15. 1. Rで前処理
    ```{r cleaning}
    dat <- penguins_raw |> clean_names() # 変数名をスネークケースに統一
    dat_cleaned <- dat |> # 必要な変数に絞る
    select(
    species, island, culmen_length_mm, culmen_depth_mm, flipper_length_mm,
    body_mass_g, sex, delta_15_n_o_oo, delta_13_c_o_oo
    ) |>
    mutate(species = species |> str_split(" ") |> map_chr(1)) |>
    mutate( # 名義尺度であるペンギンの種類、性別、居住する島をゼロから始まる整数型に変換。
    species = case_when(
    species == "Adelie" ~ 0, species == "Chinstrap" ~ 1, species == "Gentoo" ~ 2),
    island = case_when(
    island == "Biscoe" ~ 0, island == "Dream" ~ 1, island == "Torgersen" ~ 2),
    sex = case_when(
    sex == "FEMALE" ~ 0, sex == "MALE" ~ 1, is.na(sex) ~ 2)
    )
    ```
    処理内容は今回の主
    題じゃないので解説は
    省きます。

    View Slide

  16. 1. Rで前処理
    ```{r split}
    df_train <- dat_cleaned |> # 学習用データと検証用データに分割
    initial_split(prop = 0.8, strata = "species") |>
    with_seed(1234, code = _) |>
    training()
    df_test <- dat_cleaned |>
    initial_split(prop = 0.8, strata = "species") |>
    with_seed(1234, code = _) |>
    testing()
    x_train <- df_train |> select(!species) # 説明変数群と目的変数に分割
    y_train <- df_train |> select(species)
    x_test <- df_test |> select(!species)
    y_test <- df_test |> select(species)
    ```
    処理内容は今回の主
    題じゃないので解説は
    省きます。

    View Slide

  17. Pythonのターン

    View Slide

  18. 2. PythonでLightGBM
    ```{python r_object1}
    r.x_train.head()
    ```
    ```{python r_object2}
    r.x_train.info()
    ```
    Python上の r オブジェ
    クトからRのデータが
    取り出せる!
    Rのデータフ
    レームは
    pandasのデー
    タフレームに
    なる。

    View Slide

  19. 2. PythonでLightGBM
    ```{python lgb, cache=TRUE, include=FALSE}
    import pandas as pd
    import numpy as np
    import optuna.integration.lightgbm as lgb
    train = lgb.Dataset(r.x_train, r.y_train) # Rで前処理したデータをLightGBM用のデータセットに変換
    test = lgb.Dataset(r.x_test, r.y_test)
    params = { # 基本パラメータの設定
    'task': 'train',
    'boosting': 'gbdt',
    'objective': 'multiclass',
    'metric': 'multi_logloss',
    'num_class': 3,
    'verbosity': 0,
    'seed': 0
    }
    lgb_trained = lgb.train( # モデルの構築とハイパーパラメータ最適化
    params,
    train,
    categorical_feature = ["island","sex"],
    valid_sets=test
    )
    ```
    貧弱なノートPCで十数分程度かかりました。

    View Slide

  20. 2. PythonでLightGBM
    ```{python lgb2, cache=TRUE}
    best_params = lgb_trained.params # 最適化パラメータを取り出す
    # 最適化モデルで検証用データに対する各クラスの推定確率
    y_test_pred_prop = lgb_trained.predict(r.x_test, num_iteration=lgb_trained.best_iteration)
    # 最も推定確率の一番大きいクラスに振り分け
    y_test_pred = np.argmax(y_test_pred_prop, axis=1)
    # 説明変数の重要度を取り出す
    cols = list(r.x_test.columns)
    f_importance =
     np.array(lgb_trained.feature_importance(importance_type='gain'))
    df_importance = pd.DataFrame({'feature':cols, 'importance':f_importance})
    ```
    結果の取り出しと、検証データへの適用。

    View Slide

  21. Rのターン

    View Slide

  22. 3. Rで可視化と評価
    ```{r output, cache=TRUE}
    py$df_importance |>
    ggplot(aes(x =reorder(feature, importance, mean),
    y = importance,
    fill = importance)) +
    scale_fill_gradient(
    low = "blue",
    high = "red"
    ) +
    coord_flip() +
    geom_col(width = 0.5) +
    labs(
    x = "feature",
    title="LightGBM 説明変数の重要度 ",
    subtitle = "RとPythonの併用",
    x = "説明変数",
    y = "重要度",
    fill = "重要度"
    )
    ```
    R上のpyオブジェクトからPython
    のデータが取り出せる!

    View Slide

  23. 3. Rで可視化と評価
    ```{r output5, cache=TRUE}
    tibble(
    score = c("Accuracy", "Precision", "Recall", "F1_Score"),
    value = c(
    Accuracy(y_test$species, py$y_test_pred), # Accuracy(正解率)
    Precision(y_test$species, py$y_test_pred), # Recall (再現率)
    Recall(y_test$species, py$y_test_pred), # Precision (適合率)
    F1_Score(y_test$species, py$y_test_pred) # F1スコア
    ) |>
    round(4)
    )
    ```
    R上のpyオブジェクトからPython
    のデータが取り出せる!

    View Slide

  24. Enjoy!

    View Slide