0

質問:

予測区間のカバレッジが予想よりも広くなる要因は何ですか? 特にrangerパッケージを使用した分位回帰フォレストに関しては?

特定のコンテキスト + REPREX:

私はパースニップtidymodelsパッケージ スイートを介して分位点回帰フォレストを使用しrangerて、予測間隔を生成しています。私はames住宅データを使用した例を確認していましたが、以下の例で、ホールドアウト データセットで評価した場合、私の 90% 予測区間が経験的に 97% までカバーされていることに驚きました (トレーニング データのカバー率はさらに高かった)。 .

私のモデルのパフォーマンスがトレーニングセットよりもホールドアウト セットの方が大幅に悪いことを考えると、これはさらに驚くべきことでした。

ライブラリのロード、データ、分割のセットアップ:

```{r}
library(tidyverse)
library(tidymodels)
library(AmesHousing)

ames <- make_ames() %>% 
  mutate(Years_Old = Year_Sold - Year_Built,
         Years_Old = ifelse(Years_Old < 0, 0, Years_Old))

set.seed(4595)
data_split <- initial_split(ames, strata = "Sale_Price", p = 0.75)

ames_train <- training(data_split)
ames_test  <- testing(data_split)
```

モデル ワークフローを指定します。

```{r}
rf_recipe <- 
  recipe(
    Sale_Price ~ Lot_Area + Neighborhood  + Years_Old + Gr_Liv_Area + Overall_Qual + Total_Bsmt_SF + Garage_Area, 
    data = ames_train
  ) %>%
  step_log(Sale_Price, base = 10) %>%
  step_other(Neighborhood, Overall_Qual, threshold = 50) %>% 
  step_novel(Neighborhood, Overall_Qual) %>% 
  step_dummy(Neighborhood, Overall_Qual) 

rf_mod <- rand_forest() %>% 
  set_engine("ranger", importance = "impurity", seed = 63233, quantreg = TRUE) %>% 
  set_mode("regression")

set.seed(63233)
rf_wf <- workflows::workflow() %>% 
  add_model(rf_mod) %>% 
  add_recipe(rf_recipe) %>% 
  fit(ames_train)
```

トレーニング データセットとホールドアウト データセットで予測を行います。

```{r}
rf_preds_train <- predict(
  rf_wf$fit$fit$fit, 
  workflows::pull_workflow_prepped_recipe(rf_wf) %>% bake(ames_train),
  type = "quantiles",
  quantiles = c(0.05, 0.50, 0.95)
  ) %>% 
  with(predictions) %>% 
  as_tibble() %>% 
  set_names(paste0(".pred", c("_lower", "", "_upper"))) %>% 
  mutate(across(contains(".pred"), ~10^.x)) %>% 
  bind_cols(ames_train)

rf_preds_test <- predict(
  rf_wf$fit$fit$fit, 
  workflows::pull_workflow_prepped_recipe(rf_wf) %>% bake(ames_test),
  type = "quantiles",
  quantiles = c(0.05, 0.50, 0.95)
  ) %>% 
  with(predictions) %>% 
  as_tibble() %>% 
  set_names(paste0(".pred", c("_lower", "", "_upper"))) %>% 
  mutate(across(contains(".pred"), ~10^.x)) %>% 
  bind_cols(ames_test)
```

トレーニング データとホールドアウト データの両方のカバレッジ率が、予想される 90% よりもはるかに高いことを示します (経験的には、それぞれ ~98% と ~97% のようです)。

```{r}
rf_preds_train %>%
  mutate(covered = ifelse(Sale_Price >= .pred_lower & Sale_Price <= .pred_upper, 1, 0)) %>% 
  summarise(n = n(),
            n_covered = sum(
              covered
            ),
            covered_prop = n_covered / n,
            stderror = sd(covered) / sqrt(n)) %>% 
  mutate(min_coverage = covered_prop - 2 * stderror,
         max_coverage = covered_prop + 2 * stderror)
# # A tibble: 1 x 6
#       n n_covered covered_prop stderror min_coverage max_coverage
#   <int>     <dbl>        <dbl>    <dbl>        <dbl>        <dbl>
# 1  2199      2159        0.982  0.00285        0.976        0.988

rf_preds_test %>%
  mutate(covered = ifelse(Sale_Price >= .pred_lower & Sale_Price <= .pred_upper, 1, 0)) %>% 
  summarise(n = n(),
            n_covered = sum(
              covered
            ),
            covered_prop = n_covered / n,
            stderror = sd(covered) / sqrt(n)) %>% 
  mutate(min_coverage = covered_prop - 2 * stderror,
         max_coverage = covered_prop + 2 * stderror)
# # A tibble: 1 x 6
#       n n_covered covered_prop stderror min_coverage max_coverage
#   <int>     <dbl>        <dbl>    <dbl>        <dbl>        <dbl>
# 1   731       706        0.966  0.00673        0.952        0.979
```

推測:

  • rangerパッケージまたは分位点回帰フォレストに関する何かが、分位点を推定する方法で過度に極端であるか、何らかの形で「極端な」方向に過剰適合しています-非常に保守的な予測間隔につながります
  • これは、このデータセット / モデルに固有の癖です
  • 何かが足りないか、何かが正しく設定されていません
4

0 に答える 0