尝试从 R 中的 GLM 预测新数据时出现持续错误
Getting persistent error when trying to predict new data from a GLM in R
我在尝试使用 R 中的 predict 预测新数据的结果时收到持续错误“错误:变量‘x1’、‘x2’、‘x3’指定为不同类型”。我已经 运行 这段代码在其他模型上取得了成功,但出于某种原因我无法弄清楚这个代码有什么问题。我用以下代码复制了这个问题:
# make data
set.seed(19870630)
n <- 1000
df <- data.frame(y = rgamma(n, shape = .5, rate = 1),
#runif(n, 0, 1), # trows same error
x1 = runif(n, 0, 100),
x2 = runif(n, 0, 100),
x3 = runif(n, -1, 1))
df$x2 <- df$x1*df$x1
# refine data by scaling
df$x1 <- scale(df$x1, center = TRUE)
df$x2 <- scale(df$x2, center = TRUE)
df$x3 <- scale(df$x3, center = TRUE)
# double check
head(df); plot(df)
# fit model
mod <- glm(y ~ x1 + x2 + x3, data = df, family=Gamma(link="log"))
# confirm, success
summary(mod)
# make data to retain predictions
## first get realistic ranges of variables of interest, other vars will be held at mean
(x1_span <- c(rep(seq(min(df$x1), max(df$x1)), length = 50)))
(x2_span <- c(rep(seq(min(df$x2), max(df$x2)), length = 50)))
df_pred_x1_x2 <- data.frame(x1 = x1_span,
x2 = x2_span,
x3 = mean(df$x3))
# generate function for prediction ml predicted values
predict_fun <- function(my_glm) {
predict(my_glm, newdata = df_pred_x1_x2) # this is predict.glm
}
df_pred_x1_x2$y_value_pred <- predict_fun(mod) # error
# "Error: variables ‘x1’, ‘x2’, ‘x3’ were specified with different types from the fit"
# End March 8, 2021
如有任何帮助,我们将不胜感激。
这是因为scale()
在下面x1
的描述中将变量变成了单列矩阵(注意num [1:1000, 1]
)。老实说,我不确定这何时会或不会造成麻烦......
str(df)
'data.frame': 1000 obs. of 4 variables:
$ y : num ...
$ x1: num [1:1000, 1] 1.448 -1.702 -0.559 -1.147 0.732 ...
..- attr(*, "scaled:center")= num 49.2
..- attr(*, "scaled:scale")= num 28.5
...
您可以通过调用 df <- lapply(df,drop)
删除额外的维度来解决这个问题(在 适合模型之前)。 @dlaggy 指出您还可以定义自己的缩放函数 (function(x) (x-mean(x))/sd(x)
);你也可以定义
myscale <- function(...) drop(scale(...))
请注意,与使用 c()
(我在之前的回答中建议过)不同,它会降低尺寸 和 其他属性,drop()
只会降低尺寸- 这样您就可以在进行过程中将 scale/center 属性与数据保持在一起。
我在尝试使用 R 中的 predict 预测新数据的结果时收到持续错误“错误:变量‘x1’、‘x2’、‘x3’指定为不同类型”。我已经 运行 这段代码在其他模型上取得了成功,但出于某种原因我无法弄清楚这个代码有什么问题。我用以下代码复制了这个问题:
# make data
set.seed(19870630)
n <- 1000
df <- data.frame(y = rgamma(n, shape = .5, rate = 1),
#runif(n, 0, 1), # trows same error
x1 = runif(n, 0, 100),
x2 = runif(n, 0, 100),
x3 = runif(n, -1, 1))
df$x2 <- df$x1*df$x1
# refine data by scaling
df$x1 <- scale(df$x1, center = TRUE)
df$x2 <- scale(df$x2, center = TRUE)
df$x3 <- scale(df$x3, center = TRUE)
# double check
head(df); plot(df)
# fit model
mod <- glm(y ~ x1 + x2 + x3, data = df, family=Gamma(link="log"))
# confirm, success
summary(mod)
# make data to retain predictions
## first get realistic ranges of variables of interest, other vars will be held at mean
(x1_span <- c(rep(seq(min(df$x1), max(df$x1)), length = 50)))
(x2_span <- c(rep(seq(min(df$x2), max(df$x2)), length = 50)))
df_pred_x1_x2 <- data.frame(x1 = x1_span,
x2 = x2_span,
x3 = mean(df$x3))
# generate function for prediction ml predicted values
predict_fun <- function(my_glm) {
predict(my_glm, newdata = df_pred_x1_x2) # this is predict.glm
}
df_pred_x1_x2$y_value_pred <- predict_fun(mod) # error
# "Error: variables ‘x1’, ‘x2’, ‘x3’ were specified with different types from the fit"
# End March 8, 2021
如有任何帮助,我们将不胜感激。
这是因为scale()
在下面x1
的描述中将变量变成了单列矩阵(注意num [1:1000, 1]
)。老实说,我不确定这何时会或不会造成麻烦......
str(df)
'data.frame': 1000 obs. of 4 variables:
$ y : num ...
$ x1: num [1:1000, 1] 1.448 -1.702 -0.559 -1.147 0.732 ...
..- attr(*, "scaled:center")= num 49.2
..- attr(*, "scaled:scale")= num 28.5
...
您可以通过调用 df <- lapply(df,drop)
删除额外的维度来解决这个问题(在 适合模型之前)。 @dlaggy 指出您还可以定义自己的缩放函数 (function(x) (x-mean(x))/sd(x)
);你也可以定义
myscale <- function(...) drop(scale(...))
请注意,与使用 c()
(我在之前的回答中建议过)不同,它会降低尺寸 和 其他属性,drop()
只会降低尺寸- 这样您就可以在进行过程中将 scale/center 属性与数据保持在一起。