まずは蝋の翼から。

学んだことを書きながら確認・整理するためのメモブログ。こういうことなのかな?といったことをふわっと書いたりしていますが、理解が浅いゆえに的はずれなことも多々あると思うのでツッコミ歓迎

モデルに対して値の推定結果を作成する

やりたいこと

モデルを作成して、そのモデルをある値に適用したときの推定結果を作成したい。

今回は

    1. モデルの学習データの推定値
    1. 任意の値をモデルに適用したときの推定値

の2パターンについて書く。

共通処理

今回、モデルはdiamondsに対して線形モデルlog(price) ~ clarity + log(carat)を適用した結果で考える。

モデルの学習データの推定値

この場合、modelの結果をbroom::argumentに適用することでmodelに使用したデータおよび、その推定結果が返ってくる。

diamonds %>% 
  do(fit = lm(log(price) ~ clarity + log(carat), data = .)) %>% 
  augment(fit)

f:id:chito_ng:20200623102444p:plain:w600

このとき、モデルlog(price) ~ clarity + log(carat)に用いた実際の学習データはインスタンス毎にそれぞれそのままlog.price., clarity, log.carat.列として表示される。そしてそれら値を用いた各インスタンスclarity + log(carat)の結果、つまりlog(price)の推定結果は .fitted列として格納される。また、.se.fitなどで推定結果の統計値も表示される。

また、過去記事のようにモデルをpurrr::mapbroom::tidy,broom::glanceで作成するのと同じ流れでbroom::argumentも使うことができる。

knknkn.hatenablog.com

diamonds %>% 
  group_nest(clarity) %>% 
  mutate(model = map(data, ~lm(log(price) ~ log(carat), data = .)),
         tidied = map(model, tidy),
         glanced = map(model, glance),
         augmented = map(model, augment))

f:id:chito_ng:20200623091804p:plain:w600

任意の値をモデルに適用したときの推定値

先程は学習データをモデルに適用した結果だが、今度は任意の値を適用した結果を考える。

これはなぜおこなうかというと、 このモデルを適用したときどういう値が推定されるか がモチベーションとなっている。

まずは、学習させたmodelオブジェクトを作成する。

# modelオブジェクトの作成
lm_model = diamonds %>% 
  lm(log(price) ~ clarity + log(carat), data = .) 

f:id:chito_ng:20200623102543p:plain:w600

次に、各clarityに対して任意のcaratとなるインスタンスdata_gridで作成する。

www.rdocumentation.org

# 各clarityに対して、任意のcaratとなるインスタンスを作成
dummy_diamonds = diamonds %>% 
  data_grid(clarity, carat = seq(0, 5, 0.01))

これは、今回の場合diamondsclarityのユニークな値に対して任意のcaratを全て紐付けたDFを作成している。

f:id:chito_ng:20200623102631p:plain:w200

次に、predictを用いてこのデータをモデルに適用する

# 各clarity・任意のcaratインスタンスを先程作成したmodelに適用した結果を返す
dummy_diamonds %>% 
  mutate(fit = predict(lm_model, newdata = .))

f:id:chito_ng:20200623102709p:plain:w200

可視化

前述のように、 このモデルを適用したときどういう値が推定されるか がわかったので、結果を可視化する。

diamonds %>% 
  ggplot(aes(carat, log(price))) +
  geom_point(color = 'grey') + # 元のデータポイント
  geom_line(aes(y = fit), data = pred_diamond, color = 'red') + # 推定された値(fitting curve)
  facet_wrap(. ~ clarity)

f:id:chito_ng:20200623102833p:plain:w600

その他(個人的メモに近いので、わかりづらい話)

今回、dummy_diamondsとして推定結果のもととなるデータを作成した。
推定するモデルlog(price) ~ clarity + log(carat)clarityはカテゴリカル変数だったが仮にintだった場合実際のclarityよりも1.2倍大きかった場合、今のモデルを適用するとどのような結果になったか、という推定結果も出すことができる。

dummy_diamonds = diamonds %>% 
  mutate(clarity = clarity * 1.2) %>% # 1.2倍の値を作成
  data_grid(clarity, carat = seq(0, 5, 0.01))

参考

douglas-watson.github.io

notchained.hatenablog.com