モデルに対して値の推定結果を作成する
やりたいこと
モデルを作成して、そのモデルをある値に適用したときの推定結果を作成したい。
今回は
- モデルの学習データの推定値
- 任意の値をモデルに適用したときの推定値
の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))