モデルに対して値の推定結果を作成する
やりたいこと
モデルを作成して、そのモデルをある値に適用したときの推定結果を作成したい。
今回は
- モデルの学習データの推定値
- 任意の値をモデルに適用したときの推定値
の2パターンについて書く。
共通処理
今回、モデルはdiamondsに対して線形モデルlog(price) ~ clarity + log(carat)を適用した結果で考える。
モデルの学習データの推定値
この場合、modelの結果をbroom::argumentに適用することでmodelに使用したデータおよび、その推定結果が返ってくる。
diamonds %>% do(fit = lm(log(price) ~ clarity + log(carat), data = .)) %>% augment(fit)

このとき、モデルlog(price) ~ clarity + log(carat)に用いた実際の学習データはインスタンス毎にそれぞれそのままlog.price., clarity, log.carat.列として表示される。そしてそれら値を用いた各インスタンスのclarity + log(carat)の結果、つまりlog(price)の推定結果は .fitted列として格納される。また、.se.fitなどで推定結果の統計値も表示される。
また、過去記事のようにモデルをpurrr::mapとbroom::tidy,broom::glanceで作成するのと同じ流れでbroom::argumentも使うことができる。
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))

任意の値をモデルに適用したときの推定値
先程は学習データをモデルに適用した結果だが、今度は任意の値を適用した結果を考える。
これはなぜおこなうかというと、 このモデルを適用したときどういう値が推定されるか がモチベーションとなっている。
まずは、学習させたmodelオブジェクトを作成する。
# modelオブジェクトの作成 lm_model = diamonds %>% lm(log(price) ~ clarity + log(carat), data = .)

次に、各clarityに対して任意のcaratとなるインスタンスをdata_gridで作成する。
# 各clarityに対して、任意のcaratとなるインスタンスを作成 dummy_diamonds = diamonds %>% data_grid(clarity, carat = seq(0, 5, 0.01))
これは、今回の場合diamondsのclarityのユニークな値に対して任意のcaratを全て紐付けたDFを作成している。

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

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

その他(個人的メモに近いので、わかりづらい話)
今回、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))