我有三个数据集:
响应-5(样本)x 10(因变量)矩阵
预测器.5(样本)x 2(自变量)的矩阵
test_set -10的矩阵(样本)x10(响应中定义的因变量)
response <- matrix(sample.int(15, size = 5*10, replace = TRUE), nrow = 5, ncol = 10)
colnames(response) <- c("1_DV","2_DV","3_DV","4_DV","5_DV","6_DV","7_DV","8_DV","9_DV","10_DV")
predictors <- matrix(sample.int(15, size = 7*2, replace = TRUE), nrow = 5, ncol = 2)
colnames(predictors) <- c("1_IV","2_IV")
test_set <- matrix(sample.int(15, size = 10*2, replace = TRUE), nrow = 10, ncol = 2)
colnames(test_set) <- c("1_IV","2_IV")我正在使用一个定义为响应集和预测集组合的训练集来建立一个多元线性模型,我想使用这个模型对测试集进行预测:
training_dataframe <- data.frame(predictors, response)
fit <- lm(response ~ predictors, data = training_dataframe)
predictions <- predict(fit, data.frame(test_set))然而,预测的结果确实很奇怪:
predictions首先,矩阵维数为5x10,即响应变量中的样本数与DVs的数量。
我对R中的这种分析不是很熟练,但是我不应该得到一个10×10矩阵,这样我就可以预测我的test_set中的每一行了?
马丁,如果能在这个问题上提供任何帮助,我们将不胜感激。
发布于 2016-09-18 04:57:00
在R中,您正在进入一个不受支持的部分,您所拥有的模型类是"mlm",即“多个线性模型”,它不是标准的"lm“类。当您对一个公共的协变量/预测器集有几个(独立的)响应变量时,就会得到它。虽然lm()函数可以适应这一模型,但对于"mlm“类,predict方法很差。如果您查看methods(predict),您将看到一个predict.mlm*。对于具有"lm“类的线性模型,通常在调用predict.lm时调用predict;而对于"mlm”类,则调用predict.mlm*。
predict.mlm*太原始了。它不允许se.fit,即它不能产生预测误差、置信度/预测间隔等,尽管这在理论上是可能的。它只能计算预测均值。如果是的话,我们为什么要使用predict.mlm*呢?!预测均值可以通过一个平凡的矩阵-矩阵乘法(在标准的"lm“类中,这是一个矩阵向量乘法)得到,所以我们可以自己做。
考虑这个小的,复制的例子。
set.seed(0)
## 2 response of 10 observations each
response <- matrix(rnorm(20), 10, 2)
## 3 covariates with 10 observations each
predictors <- matrix(rnorm(30), 10, 3)
fit <- lm(response ~ predictors)
class(fit)
# [1] "mlm" "lm"
beta <- coef(fit)
# [,1] [,2]
#(Intercept) 0.5773235 -0.4752326
#predictors1 -0.9942677 0.6759778
#predictors2 -1.3306272 0.8322564
#predictors3 -0.5533336 0.6218942当您有一个预测数据集时:
# 2 new observations for 3 covariats
test_set <- matrix(rnorm(6), 2, 3)我们首先需要放置一个拦截列
Xp <- cbind(1, test_set)然后做这个矩阵乘法。
pred <- Xp %*% beta
# [,1] [,2]
#[1,] -2.905469 1.702384
#[2,] 1.871755 -1.236240也许您已经注意到,这里我甚至没有使用数据框架。是的,这是没有必要的,因为你有矩阵形式的所有东西。对于那些R向导,,也许使用lm.fit,甚至qr.solve更简单。
但是作为一个完整的答案,必须演示如何使用predict.mlm来获得我们想要的结果。
## still using previous matrices
training_dataframe <- data.frame(response = I(response), predictors = I(predictors))
fit <- lm(response ~ predictors, data = training_dataframe)
newdat <- data.frame(predictors = I(test_set))
pred <- predict(fit, newdat)
# [,1] [,2]
#[1,] -2.905469 1.702384
#[2,] 1.871755 -1.236240当我使用I()时请注意data.frame()。当我们想要获得,一个矩阵的数据帧时,这是必须的。您可以比较以下之间的差异:
str(data.frame(response = I(response), predictors = I(predictors)))
#'data.frame': 10 obs. of 2 variables:
# $ response : AsIs [1:10, 1:2] 1.262954.... -0.32623.... 1.329799.... 1.272429.... 0.414641.... ...
# $ predictors: AsIs [1:10, 1:3] -0.22426.... 0.377395.... 0.133336.... 0.804189.... -0.05710.... ...
str(data.frame(response = response, predictors = predictors))
#'data.frame': 10 obs. of 5 variables:
# $ response.1 : num 1.263 -0.326 1.33 1.272 0.415 ...
# $ response.2 : num 0.764 -0.799 -1.148 -0.289 -0.299 ...
# $ predictors.1: num -0.2243 0.3774 0.1333 0.8042 -0.0571 ...
# $ predictors.2: num -0.236 -0.543 -0.433 -0.649 0.727 ...
# $ predictors.3: num 1.758 0.561 -0.453 -0.832 -1.167 ...没有I()来保护矩阵输入,数据是混乱的。令人惊讶的是,这不会给lm带来问题,但是如果不使用I(),predict.mlm将很难获得正确的预测矩阵。
--好吧,我建议在本例中使用" list“而不是"data frame”, data参数在lm中以及newdata参数在predict中允许列表输入。“列表”是一种比数据框架更通用的结构,它可以毫不费力地保存任何数据结构。我们可以:
## still using previous matrices
training_list <- list(response = response, predictors = predictors)
fit <- lm(response ~ predictors, data = training_list)
newdat <- list(predictors = test_set)
pred <- predict(fit, newdat)
# [,1] [,2]
#[1,] -2.905469 1.702384
#[2,] 1.871755 -1.236240也许在最后,我应该强调,使用公式接口总是安全的,而不是矩阵接口。,我将使用R内置的dataset trees作为一个可复制的例子。
fit <- lm(cbind(Girth, Height) ~ Volume, data = trees)
## use the first two rows as prediction dataset
predict(fit, newdata = trees[1:2, ])
# Girth Height
#1 9.579568 71.39192
#2 9.579568 71.39192也许您还记得我说过,predict.mlm*太原始,无法支持se.fit。这是一个测试它的机会。
predict(fit, newdata = trees[1:2, ], se.fit = TRUE)
#Error in predict.mlm(fit, newdata = trees[1:2, ], se.fit = TRUE) :
# the 'se.fit' argument is not yet implemented for "mlm" objects哦..。置信度/预测区间如何?(实际上如果没有计算标准误差的能力,就不可能产生这些区间)?好吧,predict.mlm*会忽略它。
predict(fit, newdata = trees[1:2, ], interval = "confidence")
# Girth Height
#1 9.579568 71.39192
#2 9.579568 71.39192与predict.lm相比,这是非常不同的。
https://stackoverflow.com/questions/39553770
复制相似问题