一些建模功能,例如glmnet()
,要求(或仅允许)将数据作为预测矩阵和响应矩阵(或向量)传入,与使用公式相同。在这些情况下,通常是 predict()
方法,例如predict.glmnet()
, 要求 newdata
参数提供了一个预测矩阵,其特征与用于训练模型的特征相同。
当您的数据帧具有 factors 时创建预测矩阵的便捷方法(R 的分类数据类型)是使用 model.matrix()
函数,它会自动为您的分类变量创建虚拟特征:
# this is the dataframe and matrix I want to use to train the model
set.seed(1)
df <- data.frame(x1 = factor(sample(LETTERS[1:5], replace = T, 20)),
x2 = rnorm(20, 100, 5),
x3 = factor(sample(c("U","L"), replace = T, 20)),
y = rnorm(20, 10, 2))
mm <- model.matrix(y~., data = df)
但是,当我引入一个带有新观测值的数据框时,该数据框仅包含来自原始数据框的因子水平的一个子集,
model.matrix()
(可预测)返回具有不同虚拟特征的矩阵。这个新矩阵不能用于 predict.glm()
因为它没有模型期望的相同功能:# this is the dataframe and matrix I want to predict on
set.seed(1)
df_new <- data.frame(x1 = c("B", "C"),
x2 = rnorm(2, 100, 5),
x3 = c("L","U"))
mm_new <- model.matrix(~., data = df_new)
有没有办法将转换(创建所有必要的虚拟特征)从数据帧保存到模型矩阵,以便我可以将此转换重新应用于 future 的观察? 在我上面的例子中,理想情况下这会导致
mm_new
具有与 mm
相同的功能名称以便 predict()
可以接受mm_new
.我想补充一点,我知道 this approach ,这基本上建议包括来自
df_new
的观察结果在 df
调用前 model.matrix()
.如果我有所有的观察开始,这很好用,而且我只是在训练和测试模型。然而,新的观察结果只能在 future (在生产预测管道中)访问,我想避免为新预测重新加载整个训练数据框的开销。
最佳答案
我在 model.matrix
的文档中找到了我需要的东西和 model.frame
,并想分享。 model.matrix
有争论叫 xlev
这是“如果数据是这样的 model.frame
被调用,则用作 model.frame
的参数。”
如 model.matrix
电话model.frame
, xlev
期望数据框中每个因子的字符向量列表(列表元素名称是因子名称);每个字符向量包含构建新 model.matrix
所需的全套因子级别。具有与原始 model.matrix
相同的虚拟特征.
这是一个工作示例:
set.seed(1)
df <- data.frame(x1 = factor(sample(LETTERS[1:5], replace = T, 20)),
x2 = rnorm(20, 100, 5),
x3 = factor(sample(c("U","L"), replace = T, 20)),
y = rnorm(20, 10, 2))
mm <- model.matrix(y~., data = df)
# this is a list of levels for each factor in the original df
xlevs <- lapply(df[,sapply(df, is.factor), drop = F], function(j){
levels(j)
})
# this is a new df with only a subset of the levels of the original factors
df_new <- data.frame(x1 = c("B", "C"),
x2 = rnorm(2, 100, 5),
x3 = c("U","U"))
# calling "xlev = " builds out a model.matrix with identical levels as the original df
mm_new <- model.matrix(~., data = df_new[1,], xlev = xlevs)
请注意,此解决方案仅处理作为原始因子级别子集的因子级别。它不是为了处理新的因子水平。
关于r - 如何保存 data.frame-to-model.matrix 的映射并应用于新的观察?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43578799/