R 对分类变量级别低于训练数据的新数据进行预测

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

我需要对一些数据进行分类(R xgboost 或 catboost 等),这些数据共有大约 30 个输入变量。数据集变量之一是因子变量,在训练和测试集中有 100 个可能的级别(“n01”、“n02”、...、“n100”)。因此,当我对现有数据使用一种热编码(使用 R稀疏.模型.矩阵)时,我会得到 100 个新列,每个因子级别对应一列。

所以我用数据集制作了一个模型(训练、测试等),包括这 100 个级别的因子变量。但是,当我需要对新数据进行预测(使用模型)时,只有几个新数据样本,然后我得到的该因子变量的级别就会减少。 xgboost 和 catboost 都会给出错误,即功能名称不同。

将预测数据包含到模型创建数据中的想法是不可接受的,因为我需要制作一次模型,然后每次都用它来对新数据进行预测。

有哪些可能的方法可以解决这个问题?

r classification predict one-hot-encoding
1个回答
0
投票

也许这为你指明了方向。您可以使用完整的级别集将分类变量编码为

factor
,然后使用
model.matrix
将它们扩展为虚拟变量。

请注意,在我的示例中,

colnames(x_test)
命令显示了完整的虚拟对象集,尽管测试数据中仅存在两个级别的
z

请注意测试数据中的因子变量与训练数据中的因子变量具有相同的水平。如果训练数据和测试数据都源自同一数据帧,则不需要额外注意。如果训练数据和测试数据来自不同的来源,则需要将测试数据中的因子水平设置为与测试相同。我在这个答案中使用

|> factor(levels(train_data$z))

展示了这一点
library(tidyverse)
library(xgboost)

# simulated data ----
  
train_data <- expand_grid(
  z = as.factor(letters[1:10]),
  id = 1:10
) |> 
  mutate(
    x1 = runif(100), x2 = runif(100), x3 = runif(100),
    y = x1 + x2 + 0.1*x3 + rnorm(100)
  )

test_data <- expand_grid(
  z = letters[4:5] |> factor(levels(train_data$z)),
) |> 
  mutate(
    x1 = runif(2), x2 = runif(2), x3 = runif(2),
    y = x1 + x2 + 0.1*x3 + rnorm(2)
  )

print(train_data)
#> # A tibble: 100 × 6
#>    z        id      x1    x2      x3      y
#>    <fct> <int>   <dbl> <dbl>   <dbl>  <dbl>
#>  1 a         1 0.885   0.586 0.437    0.195
#>  2 a         2 0.776   0.981 0.758    1.08 
#>  3 a         3 0.578   0.835 0.419    1.15 
#>  4 a         4 0.00173 0.619 0.864    1.97 
#>  5 a         5 0.317   0.234 0.620    1.26 
#>  6 a         6 0.100   0.556 0.651    1.92 
#>  7 a         7 0.388   0.202 0.198    0.138
#>  8 a         8 0.374   0.972 0.0275   2.74 
#>  9 a         9 0.944   0.776 0.140    0.911
#> 10 a        10 0.200   0.488 0.00789 -0.647
#> # ℹ 90 more rows
print(test_data)
#> # A tibble: 2 × 5
#>   z         x1    x2    x3     y
#>   <fct>  <dbl> <dbl> <dbl> <dbl>
#> 1 d     0.758  0.986 0.785  1.63
#> 2 e     0.0283 0.270 0.235 -1.59

# model ----

form <- y ~ z + x1 + x2 + x3

x <- model.matrix(form, train_data)[, -1]
y <- train_data$y

model <- xgboost(x, y, nrounds = 10)
#> [1]  train-rmse:0.910737 
#> [2]  train-rmse:0.761354 
#> [3]  train-rmse:0.658591 
#> [4]  train-rmse:0.567893 
#> [5]  train-rmse:0.516402 
#> [6]  train-rmse:0.476570 
#> [7]  train-rmse:0.430633 
#> [8]  train-rmse:0.390250 
#> [9]  train-rmse:0.355300 
#> [10] train-rmse:0.333189

# predict ----

x_test <- model.matrix(form, test_data)[, -1]
colnames(x_test)
#>  [1] "zb" "zc" "zd" "ze" "zf" "zg" "zh" "zi" "zj" "x1" "x2" "x3"
predict(model, x_test)
#> [1] 1.3814828 0.3808365

创建于 2024-01-04,使用 reprex v2.0.2

© www.soinside.com 2019 - 2024. All rights reserved.