在循环中预测.lm()。警告:从等级缺陷的拟合预测可能会产生误导

时间:2014-10-25 01:56:07

标签: r lm

此R代码抛出警告

# Fit regression model to each cluster
y <- list() 
length(y) <- k
vars <- list() 
length(vars) <- k
f <- list()
length(f) <- k

for (i in 1:k) {
  vars[[i]] <- names(corc[[i]][corc[[i]]!= "1"])
  f[[i]] <- as.formula(paste("Death ~", paste(vars[[i]], collapse= "+")))
  y[[i]] <- lm(f[[i]], data=C1[[i]]) #training set
  C1[[i]] <- cbind(C1[[i]], fitted(y[[i]]))
  C2[[i]] <- cbind(C2[[i]], predict(y[[i]], C2[[i]])) #test set
}

我有训练数据集(C1)和测试数据集(C2)。每个都有129个变量。我做了k意味着对C1进行聚类分析,然后基于聚类成员分割我的数据集,并创建了不同聚类的列表(C1 [[1]],C1 [[2]],...,C1 [[k] ])。我还为C2中的每个案例分配了一个集群成员资格,并创建了C2 [[1]],...,C2 [[k]]。然后我对C1中的每个簇进行线性回归。我的因变量是“死亡”。我的预测变量在每个群集中都不同,变量[[i]](i = 1,...,k)显示了预测变量名称列表。我想为测试数据集中的每个案例预测死亡(C2 [[1]],...,C2 [[k])。当我运行以下代码时,对于某些集群。

我收到了这个警告:

In predict.lm(y[[i]], C2[[i]]) :
prediction from a rank-deficient fit may be misleading

我读了很多关于这个警告但我无法弄清楚问题是什么。

3 个答案:

答案 0 :(得分:42)

您可以使用body(predict.lm)检查预测功能。你会看到这一行:

if (p < ncol(X) && !(missing(newdata) || is.null(newdata))) 
    warning("prediction from a rank-deficient fit may be misleading")

此警告检查数据矩阵的等级是否至少等于您要拟合的参数数量。调用它的一种方法是使用一些共线协变量:

data <- data.frame(y=c(1,2,3,4), x1=c(1,1,2,3), x2=c(3,4,5,2), x3=c(4,2,6,0), x4=c(2,1,3,0))
data2 <- data.frame(x1=c(3,2,1,3), x2=c(3,2,1,4), x3=c(3,4,5,1), x4=c(0,0,2,3))
fit <- lm(y ~ ., data=data)

predict(fit, data2)
       1        2        3        4 
4.076087 2.826087 1.576087 4.065217 
Warning message:
In predict.lm(fit, data2) :
  prediction from a rank-deficient fit may be misleading

请注意,x3和x4在data中具有相同的方向。一个是另一个的倍数。可以使用length(fit$coefficients) > fit$rank

检查

另一种方法是拥有比可用变量更多的参数:

fit2 <- lm(y ~ x1*x2*x3*x4, data=data)
predict(fit2, data2)
Warning message:
In predict.lm(fit2, data2) :
  prediction from a rank-deficient fit may be misleading

答案 1 :(得分:9)

此警告:

In predict.lm(model, test) :
  prediction from a rank-deficient fit may be misleading

从R&#39> predict.lm 中获取。请参阅:http://stat.ethz.ch/R-manual/R-devel/library/stats/html/predict.lm.html

了解等级缺陷:让R告诉你矩阵的等级:

train <- data.frame(y=c(1234, 325, 152, 403), 
                   x1=c(3538, 324, 382, 335), 
                   x2=c(2985, 323, 223, 288), 
                   x3=c(8750, 322, 123, 935))
test <- data.frame(x1=c(3538, 324, 382, 335), 
                   x2=c(2985, 323, 223, 288), 
                   x3=c(8750, 322, 123, 935))
library(Matrix)
cat(rankMatrix(train), "\n")   #prints 4
cat(rankMatrix(test), "\n")    #prints 3

没有&#34;满级&#34;的矩阵据说是排名不足&#34;。如果矩阵的等级等于其列数或其行数(或两者),则称矩阵具有满等级。

问题是predict.lm即使你的矩阵是完全排名(不是排名不足)也会抛出这个警告,因为predict.lm通过抛出它认为无用的功能而修改了它的一个快速的东西,修改你的满级输入是排名不足的。然后它通过警告抱怨它。

此警告似乎也是其他情况的全部,例如你有太多的输入功能,而且你的数据密度太稀疏,它提供了预测很脆弱的观点

传递完整等级矩阵的示例,但predict.lm仍然抱怨排名不足

train <- data.frame(y=c(1,2,3,4),
                   x1=c(1,1,2,3),
                   x2=c(3,4,5,2),
                   x3=c(4,2,6,0),
                   x4=c(2,1,3,0))
test <- data.frame(x1=c(1, 2,  3,  9),
                   x2=c(3, 5,  1, 15),
                   x3=c(5, 9,  5, 22),
                   x4=c(9, 13, 2, 99))
library(Matrix)
cat(rankMatrix(train), "\n")    #prints 4, is full rank, good to go
cat(rankMatrix(test), "\n")     #prints 4, is full rank, good to go
myformula = as.formula("y ~ x1+x2+x3+x4")
model <- lm(myformula, train)
predict(model, test) 
    #Warning: prediction from a rank-deficient fit may be misleading

predict.lm看到训练数据没有信息增益,并且正在抛出无用的功能(基本上所有这些功能),然后说你给它的东西是不可靠的,因为模型有严重的问题。

解决方法:

假设预测正在返回良好的预测,您可以忽略该警告。如果观点不充分,那么提出.lm提供了它的意见,你就是这样。

因此,对预测步骤禁用警告:

options(warn=-1)      #turn off warnings
predict(model, test)
options(warn=1)      #turn warnings back on

答案 2 :(得分:2)

这是因为,您的一个因变量具有lm(..)函数作为输出给出的系数的NA。这种变量对模型没有影响,通常是由于多重共线性问题所致,即,该预测变量线性依赖于其他预测变量,或者是因为该预测变量对于所有记录(行)都是恒定的。最好的办法是从lm(..)函数的公式中删除该变量,然后再次进行回归。这不会降低模型的准确性。 就我而言,

model <- lm(Happiness.Score ~ Economy..GDP.per.Capita.+year+Health..Life.Expectancy., data=dfTrain)

> model
Call:
lm(formula = Happiness.Score ~ Economy..GDP.per.Capita. + year + 
    Health..Life.Expectancy., data = dfTrain)

Coefficients:
             (Intercept)  Economy..GDP.per.Capita.                      year  
                   3.036                     1.569                        NA  
Health..Life.Expectancy.  
                   1.559

可变年份的所有记录都具有相同的值。删除年份变量后

model <- lm(Happiness.Score ~ Economy..GDP.per.Capita.+Health..Life.Expectancy., data=dfTrain)

preds <- predict.lm(model, dfTest[, c(1:nrow(dfTest)-1]))

这没有警告消息