错误:使用 {Tidymodels} 运行预测时无法对不存在的列进行子集化

Pet*_*rAL 1 r r-recipes tidymodels

我正在尝试使用 Tidymodels 预测 R 中的房地产价格。我正在关注本教程。一切都很顺利,直到我尝试对测试数据进行预测时。

\n

请参阅下面的代码示例和最后的错误。

\n

我看了两个类似的问题(这里这里),但似乎我已经定义了可变角色,并为我的工作流程提供了未准备好的配方。

\n\n
    # libraries ---------------------------------------------------------------\n    library(tidymodels)\n    #> \xe2\x94\x80\xe2\x94\x80 Attaching packages \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 tidymodels 0.1.2 \xe2\x94\x80\xe2\x94\x80\n    #> \xe2\x9c\x93 broom     0.7.3      \xe2\x9c\x93 recipes   0.1.15\n    #> \xe2\x9c\x93 dials     0.0.9      \xe2\x9c\x93 rsample   0.0.8 \n    #> \xe2\x9c\x93 dplyr     1.0.3      \xe2\x9c\x93 tibble    3.0.5 \n    #> \xe2\x9c\x93 ggplot2   3.3.3      \xe2\x9c\x93 tidyr     1.1.2 \n    #> \xe2\x9c\x93 infer     0.5.4      \xe2\x9c\x93 tune      0.1.2 \n    #> \xe2\x9c\x93 modeldata 0.1.0      \xe2\x9c\x93 workflows 0.2.1 \n    #> \xe2\x9c\x93 parsnip   0.1.5      \xe2\x9c\x93 yardstick 0.0.7 \n    #> \xe2\x9c\x93 purrr     0.3.4\n    #> \xe2\x94\x80\xe2\x94\x80 Conflicts \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 tidymodels_conflicts() \xe2\x94\x80\xe2\x94\x80\n    #> x purrr::discard() masks scales::discard()\n    #> x dplyr::filter()  masks stats::filter()\n    #> x dplyr::lag()     masks stats::lag()\n    #> x recipes::step()  masks stats::step()\n    library(data.table)\n    \n    library(purrr)\n    \n    \n    # data --------------------------------------------------------------------\n    # \'re\' means real estate\n    # I\'m using data.table in general. Using tribble below for cleaner data definition.\n    real_estate_data <- tibble::tribble(\n        ~re_id, ~price_per_sqm_huf_mil, ~district, ~num_room,\n        "30876343",      0.534722222222222,        1,         3,\n        "31914489",      0.476119402985075,        1,         1,\n        "30972289",      0.507352941176471,        1,         2,\n        "31739730",      0.472972972972973,        1,         3,\n        "31783137",                0.49875,        2,         3,\n        "31809435",      0.439705882352941,        2,         2,\n        "31943408",      0.469117647058824,        2,         3,\n        "31944348",       0.56231884057971,        2,         1,\n        "31961146",      0.472972972972973,        3,         3,\n        "24314388",      0.649550561797753,        3,         2,\n        "29840270",      0.719178082191781,        3,         3,\n        "29840429",      0.719178082191781,        3,         3,\n        "30873484",      0.822857142857143,        4,         3,\n        "30969673",      0.533802816901408,        4,         3,\n        "31333120",      0.741511627906977,        4,         3,\n        "31788730",      0.527142857142857,        4,         2,\n        "31948441",      0.734848484848485,        5,         2,\n        "31962350",                    0.8,        5,         3,\n        "31962779",      0.670454545454545,        5,         3,\n        "31979128",      0.689054054054054,        5,         1\n    )\n    \n    real_estate_data <- as.data.table(real_estate_data) %>% .[, district := factor(district)]\n    \n    # train/test split --------------------------------------------------------\n    set.seed(123)\n    re_split <- initial_split(real_estate_data)\n    re_train <- training(re_split)\n    re_test  <- testing(re_split)\n    \n    # workflow (w/ recipe) ----------------------------------------------------\n    re_rec <- recipe(re_train,\n                     formula = price_per_sqm_huf_mil ~ .) %>%\n        update_role(re_id, new_role = "ID") %>%\n        step_center(all_numeric(), - district) %>%\n        step_scale(all_predictors(), all_numeric(), - district) %>%\n        step_dummy(district) %>%\n        step_zv(all_predictors())\n    \n    summary(re_rec)\n    #> # A tibble: 4 x 4\n    #>   variable              type    role      source  \n    #>   <chr>                 <chr>   <chr>     <chr>   \n    #> 1 re_id                 nominal ID        original\n    #> 2 district              nominal predictor original\n    #> 3 num_room              numeric predictor original\n    #> 4 price_per_sqm_huf_mil numeric outcome   original\n    \n    lr_model <-\n        linear_reg() %>%\n        set_engine("lm")\n    \n    re_wflow <-\n        workflow() %>%\n        add_model(lr_model) %>%\n        add_recipe(re_rec)\n    \n    # model training and prediction -------------------------------------------\n    re_fit <-\n        re_wflow %>%\n        fit(data = re_train)\n    \n    re_pred <- predict(re_fit, re_test)\n    #> Error: Can\'t subset columns that don\'t exist.\n    #> x Column `price_per_sqm_huf_mil` doesn\'t exist.\n
Run Code Online (Sandbox Code Playgroud)\n

由reprex 包于 2021 年 1 月 25 日创建(v0.3.0)

\n

非常感谢!

\n

Jul*_*lge 5

这里的问题是,您过去常常step_center()转换结果( price_per_sqm_huf_mil),但在预测时,没有可用的结果。all_predictors() & all_numeric()您可以像这样指定要居中:

\n
library(tidymodels)\n#> \xe2\x94\x80\xe2\x94\x80 Attaching packages \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 tidymodels 0.1.2 \xe2\x94\x80\xe2\x94\x80\n#> \xe2\x9c\x93 broom     0.7.3      \xe2\x9c\x93 recipes   0.1.15\n#> \xe2\x9c\x93 dials     0.0.9      \xe2\x9c\x93 rsample   0.0.8 \n#> \xe2\x9c\x93 dplyr     1.0.3      \xe2\x9c\x93 tibble    3.0.5 \n#> \xe2\x9c\x93 ggplot2   3.3.3      \xe2\x9c\x93 tidyr     1.1.2 \n#> \xe2\x9c\x93 infer     0.5.4      \xe2\x9c\x93 tune      0.1.2 \n#> \xe2\x9c\x93 modeldata 0.1.0      \xe2\x9c\x93 workflows 0.2.1 \n#> \xe2\x9c\x93 parsnip   0.1.5      \xe2\x9c\x93 yardstick 0.0.7 \n#> \xe2\x9c\x93 purrr     0.3.4\n#> \xe2\x94\x80\xe2\x94\x80 Conflicts \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 tidymodels_conflicts() \xe2\x94\x80\xe2\x94\x80\n#> x purrr::discard() masks scales::discard()\n#> x dplyr::filter()  masks stats::filter()\n#> x dplyr::lag()     masks stats::lag()\n#> x recipes::step()  masks stats::step()\nlibrary(dplyr)\n\nreal_estate_data <- tibble::tribble(\n  ~re_id, ~price_per_sqm_huf_mil, ~district, ~num_room,\n  "30876343",      0.534722222222222,        1,         3,\n  "31914489",      0.476119402985075,        1,         1,\n  "30972289",      0.507352941176471,        1,         2,\n  "31739730",      0.472972972972973,        1,         3,\n  "31783137",                0.49875,        2,         3,\n  "31809435",      0.439705882352941,        2,         2,\n  "31943408",      0.469117647058824,        2,         3,\n  "31944348",       0.56231884057971,        2,         1,\n  "31961146",      0.472972972972973,        3,         3,\n  "24314388",      0.649550561797753,        3,         2,\n  "29840270",      0.719178082191781,        3,         3,\n  "29840429",      0.719178082191781,        3,         3,\n  "30873484",      0.822857142857143,        4,         3,\n  "30969673",      0.533802816901408,        4,         3,\n  "31333120",      0.741511627906977,        4,         3,\n  "31788730",      0.527142857142857,        4,         2,\n  "31948441",      0.734848484848485,        5,         2,\n  "31962350",                    0.8,        5,         3,\n  "31962779",      0.670454545454545,        5,         3,\n  "31979128",      0.689054054054054,        5,         1\n) %>%\n  mutate(district = factor(district))\n\n\nset.seed(123)\nre_split <- initial_split(real_estate_data)\nre_train <- training(re_split)\nre_test  <- testing(re_split)\n\nre_rec <- recipe(re_train,\n                 formula = price_per_sqm_huf_mil ~ .) %>%\n  update_role(re_id, new_role = "ID") %>%\n  step_center(all_predictors() & all_numeric()) %>%\n  step_scale(all_predictors() & all_numeric()) %>%\n  step_dummy(district) %>%\n  step_zv(all_predictors())\n\nsummary(re_rec)\n#> # A tibble: 4 x 4\n#>   variable              type    role      source  \n#>   <chr>                 <chr>   <chr>     <chr>   \n#> 1 re_id                 nominal ID        original\n#> 2 district              nominal predictor original\n#> 3 num_room              numeric predictor original\n#> 4 price_per_sqm_huf_mil numeric outcome   original\n\nlr_model <-\n  linear_reg() %>%\n  set_engine("lm")\n\nre_wflow <-\n  workflow() %>%\n  add_model(lr_model) %>%\n  add_recipe(re_rec)\n\nre_fit <-\n  re_wflow %>%\n  fit(data = re_train)\n\npredict(re_fit, new_data = re_test)\n#> # A tibble: 5 x 1\n#>   .pred\n#>   <dbl>\n#> 1 0.486\n#> 2 0.611\n#> 3 0.688\n#> 4 0.688\n#> 5 0.768\n
Run Code Online (Sandbox Code Playgroud)\n

由reprex 包于 2021 年 1 月 25 日创建(v0.3.0)

\n

这让比您更多的人感到困惑,因此我们正在努力添加一组新的选择器,这些选择器将很快合并。如果您确实想尝试改变结果,则需要考虑的另一个选择是考虑使用skip = TRUE.

\n