确保model.matrix的列数与列车和测试集的列数相同
是否有办法确保模型矩阵中的列数与列车和测试集的列数相同 我尝试了以下方法:确保model.matrix的列数与列车和测试集的列数相同,r,R,是否有办法确保模型矩阵中的列数与列车和测试集的列数相同 我尝试了以下方法: library(tidyverse) create_encoder <- function(x){ cat_vars <- x[1, ] %>% select_if(is.factor) %>% names() labels_dic <- cat_vars %>% map(~x %>% pull(.) %>% levels) %>% set_nam
library(tidyverse)
create_encoder <- function(x){
cat_vars <- x[1, ] %>% select_if(is.factor) %>% names()
labels_dic <- cat_vars %>% map(~x %>% pull(.) %>% levels) %>%
set_names(cat_vars)
encode_test <- function(x){
y <- x
y[, cat_vars] <- cat_vars %>%
map(~factor(x %>% pull(.), labels_dic[[.]]))
y
}
}
x_ent <- tibble(x1 = c(1, 2, 3, 4), x2 = c('a', 'b', 'a', 'c'))
x_pr <- tibble(x1 = c(5, 6, 7), x2 = c('a', 'b', 'a'))
x_ent <- x_ent %>% mutate_if(is.character, as.factor)
x_pr <- x_pr %>% mutate_if(is.character, as.factor)
y_ent <- c(2, 1, 3, 4)
y_pr <- c(6, 3, 2)
encode_test <- create_encoder(x_ent)
x_pr <- encode_test(x_pr)
x_mat_ent <- model.matrix(~., x_ent)
x_mat_pr <- model.matrix(~., x_pr)
x_mat_ent
x_mat_pr
x_mat_ent %>% dim()
x_mat_pr %>% dim()
库(tidyverse)
创建\u编码器%names()
标签\u dic%映射(~x%%>%pull(%)%%>%levels)%%>%
设置名称(类别变量)
encode_test首先,我假设您不是指维度,而是指列的数量,我们希望行的数量不同,因为变量长度不同
我认为这是一个很好的例子,说明tidyverse将一些非常简单的问题复杂化:
library(tidyverse)
x_ent <- tibble(x1 = c(1, 2, 3, 4), x2 = factor(c('a', 'b', 'a', 'c'), levels = letters[1:3]))
x_pr <- tibble(x1 = c(5, 6, 7), x2 = factor(c('a', 'b', 'a'), levels = letters[1:3]))
x_mat_ent <- model.matrix(~., x_ent)
x_mat_pr <- model.matrix(~., x_pr)
x_mat_ent %>% dim()
x_mat_pr %>% dim()
对于forcats:
library(tidyverse)
library(magrittr)
set.seed(1)
x_ent <- tibble(x1 = runif(100), x2 = factor(rbinom(100, 100, 0.5)));
x_pr <- tibble(x1 = runif(100), x2 = factor(rbinom(100, 500, 0.5)))
x_ent %<>% mutate(x2 = fct_expand(x2, lvls_union(list(x_ent$x2, x_pr$x2))))
x_pr %<>% mutate(x2 = fct_expand(x2, lvls_union(list(x_ent$x2, x_pr$x2))))
x_mat_ent <- model.matrix(~., x_ent)
x_mat_pr <- model.matrix(~., x_pr)
x_mat_ent %>% dim()
x_mat_pr %>% dim()
库(tidyverse)
图书馆(magrittr)
种子(1)
x_ent您也可以在函数中传递列车数据帧,以获得要设置的级别
library(dplyr)
create_encoder <- function(test, train){
cols <- sapply(test, is.character)
test[cols] <- purrr::map2(test %>% select(where(is.character)),
train %>% select(where(is.factor)),
~factor(.x, levels = levels(.y))
)
test
}
x_ent <- tibble(x1 = c(1, 2, 3, 4), x2 = c('a', 'b', 'a', 'c'))
x_pr <- tibble(x1 = c(5, 6, 7), x2 = c('a', 'b', 'a'))
x_ent <- x_ent %>% mutate(across(where(is.character), factor))
x_pr <- create_encoder(x_pr, x_ent)
x_mat_ent <- model.matrix(~., x_ent)
x_mat_pr <- model.matrix(~., x_pr)
x_mat_ent %>% dim()
#[1] 4 4
x_mat_pr %>% dim()
#[1] 3 4
库(dplyr)
创建编码器是。我的意思是相同数量的列。我已经编辑了这个问题,所以现在问题清楚了。关于您的示例,如果数据集更大,如何自动执行此操作?我添加了第二个示例来演示此问题。这将是一个功能的全部。但是,难道没有类似于python OneHotEncoder的东西吗?我不知道python OneHotEncoder做什么。python中的sklearn模块有OneHotEncoder类,它获取一个热编码矩阵,并轻松处理分类变量的标签。到目前为止,我还没有找到一个R函数,它可以自动进行一次热编码,并处理train和testset中分类变量的标签数量之间的差异。
library(dplyr)
create_encoder <- function(test, train){
cols <- sapply(test, is.character)
test[cols] <- purrr::map2(test %>% select(where(is.character)),
train %>% select(where(is.factor)),
~factor(.x, levels = levels(.y))
)
test
}
x_ent <- tibble(x1 = c(1, 2, 3, 4), x2 = c('a', 'b', 'a', 'c'))
x_pr <- tibble(x1 = c(5, 6, 7), x2 = c('a', 'b', 'a'))
x_ent <- x_ent %>% mutate(across(where(is.character), factor))
x_pr <- create_encoder(x_pr, x_ent)
x_mat_ent <- model.matrix(~., x_ent)
x_mat_pr <- model.matrix(~., x_pr)
x_mat_ent %>% dim()
#[1] 4 4
x_mat_pr %>% dim()
#[1] 3 4