cucumber flesh

Rを中心としたデータ分析・統計解析らへんの話題をしていくだけ

Fukuoka.R#15でtidymodelsについての発表を行いました

先週末(2019年8月31日)に開催されたFukuoka.R#15 へ参加・発表してきました。Fukuoka.Rはその名の通り、九州・博多を中心として活動するRコミュニティです。私は茨城県つくば市に住んでいるので、会場のLINE Fukuokaまでは直線距離でおよそ928km離れた場所からの参加というわけです。いやはや遠い。遠いですが、参加してよかったと思える会でした。

以下、簡単にですが内容の振り返りと当日の発表では言えなかったことを書きます。

発表内容

tidymodelsによるモデル構築と運用」という題での発表です。

speakerdeck.com

tidymodelsに含まれるパッケージについて言及した日本語を記事をしばしば見かけるようになりました。私自身もいくつか記事を書いています。

blog.hoxo-m.com

blog.hoxo-m.com

しかしtidymodelsの全容、包括的な話題を扱っている日本語の情報は限られています。そこで今回は、モデルの構築から運用に至るまでの手順をパッケージの利用方法とともに紹介する形式としました。具体的には{rsample}で対象データの分割、リサンプリング、{recipes}でデータ前処理、特徴量の用意、{parsnip}でのモデル実行、最後に{yardstick}による性能評価です。

スライド資料なので、言葉足らずな面があるかと思います。 テキストと合わせた内容は id:dropout009 さんの記事 (その1,その2)を読んでおけばOKかなと感じる部分もあります。資料作成時も大変参考となりました。

今回は30分の枠でした。Tokyo.Rでは20分の枠が一般的なのでちょっと長めですね。たっぷりと話すことができました(その分詰め込みすぎて余裕がなくなってしまったという本末転倒な反省も)。tidymodelsはパイプフレンドリーで関数や操作性に一貫性があり、またパッケージがタスクに応じて分割されているので紹介もしやすかったです。

発表から除外したもの

最後の方は説明が複雑になる、時間も足りないということもあり、駆け足で説明不足になってしまいました。また、運用をタイトルに入れていたので{drake}{butcher}の紹介をと考えていましたが明らかに時間が足りない、それよりは他の説明に時間を割こうとして除外しました。そのため、こちらで簡単に補足させていただきます。

{drake}はtidymodelsの支配下にないパッケージであり、モデルとは関係しません。しかしモデル構築の作業をワークフロー化することで、再現性を確保、手間を減らすことが期待できます。おすすめです。

blog.hoxo-m.com

また当初、{butcher}を組みこもうとしていましたが結局除外してしまいました。このパッケージはモデルオブジェクトのサイズを減少させるのに効果的です。というのもモデル構築の過程でオブジェクトサイズが増大することがあるためです。関数の環境内で余分なオブジェクトを生成しているとそれが影響する感じでしょうか(よくわかっていない部分があります…)。{butcher}パッケージの名前は肉屋の従業員。その名の通り、余分なデータを捌きます。{butcher}を利用すると先のオブジェクトサイズが減少します。やや物騒な名前の関数を使います。こちらは{parsnip}が対応するエンジンについて対応しており、すでにCRANに登録されています。

今回のテーマはtidymodelsでしたが、今Rで機械学習モデルを実行するには他の選択肢がいくつかあります。この比較についても発表時は行えませんでした。以前tweetで発信した情報がありますのでこちらをご覧ください。

また会いましょう!

ggplot2::geom_sf()での緯度経度のラベルを調整する

要約

  • ggplot2::geom_sf()のデフォルトで表示される緯度経度の軸は桁数が揃っていないことがある
  • scales::degree_format()で桁数の調整が可能
    • 最新のバージョン(1.0.0)では実装されておらず、開発版をインストールして利用する
    • scalesを使わない方法も紹介

はじめに

f:id:u_ribo:20190302222837p:plain

ggplot2で地理空間データを描画すると、両軸のラベルに緯度経度の値が表示されます。下記に示すように、たった2つの関数で地図を表示できて便利なのですが、この図のY軸、緯度の表示が"36.5°N", "36°N"と有効数字の桁数が異なっているのが気になります。 "36.5°N", "36.0°N"のように桁数を合わせたいところです。また、日本語での「北緯」や「東経」、「西経」というラベルも使いたい場面があるでしょう。今回はそのような際に役立つ、geom_sf()の軸ラベルの表示を変更して桁数を揃える方法と表示方法を任意のものに調整する例を紹介します。

続きを読む

ggplot2でのfacetした図のstripを下部に配置する方法と注意点

ggplot2のfacet_wrap()facet_grid()で、ある変数の水準ごとにパネルを分割した描画を行うと、分割の基準となっている変数名がパネルの上部に表示されます。これにはstripという名前がついています。“strip”の辞書を引くと「(金属の)薄板」の意味だそうです(確かに分割した様子は板っぽい…)。

stripの位置は、facet_wrap()facet_grid()それぞれ異なる方法で調整できます。まずはfacet_wrap()の例を示します。次のようにfacet_wrap(strip.position = "bottom")とすることでstripを下部に移動させることができます。できますが…。

library(ggplot2)
library(gghighlight)

p_base <- 
  ggplot(mpg, 
       aes(displ, hwy, color = class)) +
  geom_jitter() +
    gghighlight(use_direct_label = FALSE,
                unhighlighted_colour = "#99999930") +
  hrbrthemes::scale_color_ipsum() +
  guides(color = FALSE)

p_strip_bottom <- 
  p_base +
  facet_wrap(vars(class),
             ncol = dplyr::n_distinct(mpg$class),
             strip.position = "bottom")
p_strip_bottom +
  ggtitle('strip.position = "bottom"だけではx軸の数値ラベルの上部にきてしまう')

f:id:u_ribo:20190224145624p:plain

「違う、そうじゃない」。

stripがx軸のラベルより上にきており、肝心の値がわかりにくくなってしまっています。

そもそもstripの位置は図の上部にあったほうが良いんじゃ…という気がしますが、ここでは諸事情により下部に配置する必要があるとして話を続けます。

次にもう一つのfacetであるfacet_grid()でstrip位置を調整します。こちらは引数switchがラベルの位置指定に使われており、NULL (初期値), “x”, “y”, “both”のいずれかを与えます。デフォルトではstripの配置はパネルの上部・右側ですが、“x”の時は、縦方向にパネルを分割したstripの位置を下部に、“y”が与えられた時には横方向に分割されたstripを左側に配置します。また縦・横両方向にラベルを与える場合でstripを下部・左側にするには“both”を与えます

p_base +
  facet_grid(cols = vars(class), switch = "x") +
  ggtitle('switch = "x"でもx軸の数値ラベルの上部にきてしまう')

f:id:u_ribo:20190224145653p:plain

この問題を解決し、x軸の下にstripを表示するには、下記のようにtheme(strip.placement = "outside")でstripを外側に配置する指定を追加します。これはfacet_wrap()facet_grid()のいずれで作成した場合でも共通です。

p_strip_bottom + 
  # strip.placementは "inside" (初期値) または "outside"が指定可能
  theme(strip.placement = "outside",
        strip.background = element_blank())

f:id:u_ribo:20190224145756p:plain

整理すると、

  • stripの位置を変更するには
    • facet_wrap()ではstrip.position =
    • facet_grid()ではswith =
  • 下部に配置したstripを移動するにはtheme(strip.placement = "outside")

とfacetの処理により異なり、さらにtheme()で調整が必要なのでややこしいです。

参考

atusy.github.io

facetについての全般的な話題はこれを見ておけば大体OKだと思います。逆引き的に参照してもよし。

notchained.hatenablog.com

facet_wrap(strip.position = )facet_grid(swith = )の話題に触れられています。

それでは!