predict関数から学習データしか返ってこない(dot-dot-dotについて)
R言語のrpartにあるpredict関数を使っていた時の話。
penguinsデータをtrain233件、valid100件に分割。
# packages ---------------------------------------------------------------- library(palmerpenguins) data(package = 'palmerpenguins') # data preparation --------------------------------------------------------------- set.seed(2022) df <- penguins |> tidyr::drop_na(tidyselect::everything()) n_size <- nrow(df) split <- sample(n_size, size = 0.7 * n_size) train <- df[split,] valid <- df[-split,] train |> nrow() # [1] 233 valid |> nrow() # [1] 100
rpartで学習してvalidに適用したつもりだったが、なぜか233件のデータが返ってきた。validは100件のはず。
# modeling ---------------------------------------------------------------- tr <- rpart::rpart(formula = species ~ ., data = train, method = "class", parms = list(split = "gini")) pred_data <- predict(object = tr, data = valid, type = "prob") pred_data |> nrow() # [1] 233 # validの100件が返ってくるはずなのに233件 valid |> nrow() # [1] 100 # validの件数を確認するがやはり100件
RDocumentationに戻って確認すると、モデルを適用するデータを指定する引数は”newdata”だったが誤って”data”という引数名にしていたことが分かった。
newdata
data frame containing the values at which predictions are required.
predict.rpart function - RDocumentation
pred_data <- predict(object = tr, data = valid, # ここをdataではなくnewdataにしないといけなかった type = "prob")
疑問が2つ出てきて、1つ目は”newdata”に何も渡していないのに問題ないのかということ、2つ目は”data”という私が勝手に創り上げた引数に渡したオブジェクトはどこに行ったのかということ。
1つ目の”newdata”に関する疑問は、RDocumantationに書いてあった。”newdata”に何も与えていないと学習に使用した値が返ってくるとのこと。今回233件のデータが返ってきていたのはこれが起こっていたからだった。
If missing, the fitted values are returned.
predict.rpart function - RDocumentation
2つ目の”data”に関する疑問。これもRDocumentationに書いてあって「…」という引数が元凶だった。AdvancedRでは”dot-dot-dot”という名称で説明されている。
このdot-dot-dotは追加の引数をいくらでも受け取ることができる。主に他の関数で利用されることが想定される関数に、後々柔軟に引数を取れるよう設定される様子。一方でその柔軟性故に、引数名を誤った場合に警告やエラーなく受け取ってしまうことが注意点としてAdvancedRには挙げられている。今回は件数が明らかに違ったので気づくことができたが、関数によっては難しそう。AdvancedRではsum関数を例にとってどのような問題が起こるのか説明されている。
Functions can have a special argument ... (pronounced dot-dot-dot). With it, a function can take any number of additional arguments. 6 Functions | Advanced R
教訓として2つ。
- 引数のスペルを確認する。引数にdot-dot-dotがある場合特に注意。
- Documentちゃんと読む。
この記事の内容をスライドにしたのが以下のリンク先。