无法使用 tidymodels 软件包用分类预测因子训练 Poisson glmnet。

问题描述 投票:0回答:1

我的目标是使用下面的函数来拟合一个Poisson glmnet。tidymodels 包。为此,我使用了 recipes 包来预处理数据。parsnip 来拟合模型。workflows 将模型与预处理程序和 poissonreg 能够使用泊松回归与 parsnip. 如果我的训练数据集只包含数字预测因子,它的工作完全正常,但当有一些因子(或分类)预测因子时,我无法拟合模型。 在下面的代码中,你可能认为使用 tidymodels 是矫枉过正的。是的,对于这个最小的例子来说是的,但是最终,我将会想要调整我的超参数,验证我的模型等等,然后。tidymodels 会很有用。

首先,让我们加载我们需要的包。

library(tibble)
library(recipes)
library(poissonreg)
library(parsnip)
library(workflows)
library(glmnet)

让我们模拟我们的数据集,有1000行,1个结果(y),1个分类预测因子,2个层次(x_fac)和3个数字预测因子(x_num_01, x_num_02x_num_03).

n <- 1000

dat <- tibble::tibble(
  y = rpois(n, lambda = 0.15),
  x_fac = factor(sample(c("M", "F"), size = n, replace = T)),
  x_num_01 = rnorm(n),
  x_num_02 = rnorm(n),
  x_num_03 = rnorm(n)
)

然后,我们定义并准备配方。预处理非常简单:如果有分类预测因子的话,所有的分类预测因子都会转化为虚拟预测因子。

rec <- 
  recipes::recipe(y ~ ., data = dat) %>% 
  recipes::step_dummy(all_nominal()) %>% 
  recipes::prep()

然后我们定义我们的模型。

glmnet_mod <- 
  poissonreg::poisson_reg(penalty = 0.01, mixture = 1) %>% 
  parsnip::set_engine("glmnet")

捆绑模型和预处理程序与 workflows 包裹

glmnet_wf <- 
  workflows::workflow() %>%
  workflows::add_recipe(rec) %>% 
  workflows::add_model(glmnet_mod)

最后,我们用 parsnip:

glmnet_fit <- 
  glmnet_wf %>% 
  parsnip::fit(data = dat)

这个 parsnip::fit 函数抛出错误

Error in fishnet(x, is.sparse, ix, jx, y, weights, offset, alpha, nobs,  : 
  NA/NaN/Inf in foreign function call (arg 4)
In addition: Warning message:
In fishnet(x, is.sparse, ix, jx, y, weights, offset, alpha, nobs,  :
  NAs introduced by coercion
Timing stopped at: 0.005 0 0.006

我完全不知道为什么 如果你去掉预测器 x_fac 从模拟数据集 dat,它工作得很好。如果我在运行glmnet之前,自己先对数据进行预处理,然后用 glmnet 包。

x <- dat %>% dplyr::mutate(x_fac_M = x_fac == "M") %>% dplyr::select(contains("x"), -x_fac) %>% as.matrix()
y <- dat$y

glmnet::glmnet(x = x, y = y, family = "poisson", lambda = 0.01, alpha = 1)

谢谢你的帮助!

会话信息。

R version 4.0.0 (2020-04-24)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Catalina 10.15.4

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_CA.UTF-8/en_CA.UTF-8/en_CA.UTF-8/C/en_CA.UTF-8/en_CA.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] workflows_0.1.1  poissonreg_0.0.1 parsnip_0.1.0    recipes_0.1.12  
[5] dplyr_0.8.5      tibble_3.0.1    

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6       pillar_1.4.4       compiler_4.0.0     gower_0.2.1       
 [5] iterators_1.0.12   class_7.3-16       tools_4.0.0        rpart_4.1-15      
 [9] ipred_0.9-9        packrat_0.5.0      lubridate_1.7.8    lifecycle_0.2.0   
[13] lattice_0.20-41    pkgconfig_2.0.3    rlang_0.4.6        foreach_1.5.0     
[17] Matrix_1.2-18      cli_2.0.2          rstudioapi_0.11    prodlim_2019.11.13
[21] withr_2.2.0        generics_0.0.2     vctrs_0.2.4        glmnet_3.0-2      
[25] grid_4.0.0         nnet_7.3-13        tidyselect_1.0.0   glue_1.4.0        
[29] R6_2.4.1           fansi_0.4.1        survival_3.1-12    lava_1.6.7        
[33] purrr_0.3.4        tidyr_1.0.2        magrittr_1.5       codetools_0.2-16  
[37] ellipsis_0.3.0     MASS_7.3-51.5      splines_4.0.0      hardhat_0.1.2     
[41] assertthat_0.2.1   shape_1.4.4        timeDate_3043.102  utf8_1.1.4        
[45] crayon_1.3.4
r rstudio glmnet tidymodels r-recipes
1个回答
1
投票

好了,我才想明白。看来,添加到工作流中的配方不应该被准备。所以就把这部分改一下。

rec <- 
  recipes::recipe(y ~ ., data = dat) %>% 
  recipes::step_dummy(all_nominal()) %>% 
  recipes::prep()

改成以下内容

rec <- 
  recipes::recipe(y ~ ., data = dat) %>% 
  recipes::step_dummy(all_nominal())
© www.soinside.com 2019 - 2024. All rights reserved.