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

Mah*_*hsa 31 statistics r linear-regression 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
}
Run Code Online (Sandbox Code Playgroud)

我有一个训练数据集(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
Run Code Online (Sandbox Code Playgroud)

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

Kar*_*ius 50

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

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

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

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
Run Code Online (Sandbox Code Playgroud)

请注意,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
Run Code Online (Sandbox Code Playgroud)

  • 在模型中包含更多案例而非变量非常重要.你可以尝试这样做而不是需要的情况少,但你应该记住,在这种情况下你的预测可能是不可靠的.这就是R给你一个"警告"而不是错误的原因.只是为了引起你的注意.您应该能够得到答案并在警告之后继续工作(它们不是错误),但尝试简化模型是明智的. (2认同)

Eri*_*ski 11

这个警告:

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

从R's抛出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
Run Code Online (Sandbox Code Playgroud)

没有"满级"的矩阵被称为"排名不足".如果矩阵的等级等于其列数或其行数(或两者),则称矩阵具有满等级.

问题是,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
Run Code Online (Sandbox Code Playgroud)

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

解决方法:

假设预测正在返回良好的预测,您可以忽略该警告.如果视角不够,那么你就会提出它的意见.

因此,在预测步骤中禁用警告,如下所示:

options(warn=-1)      #turn off warnings
predict(model, test)
options(warn=1)      #turn warnings back on
Run Code Online (Sandbox Code Playgroud)

  • 我认为这个答案是错误的。您需要获取设计矩阵的排名,而不是_包含带有响应变量的列_的数据框的排名!第二个示例中的“train”数据(具有“y”列到“x4”列)_是_等级不足的。尝试 `X &lt;- model.matrix(y ~ ., train); rankMatrix(X) &lt; ncol(X)`,您将看到设计矩阵是秩亏的。我相信你关于 R 会修改“你的满等级输入为等级不足”的断言是错误的。 (2认同)

小智 6

这是因为,您的因变量之一具有 NA 作为由 lm(..) 函数输出的系数。这样的变量对模型没有影响,通常是由于多重共线性问题,即预测变量线性依赖于其他预测变量,或者因为该预测变量对于所有记录(行)都是恒定的。最好的办法是从 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
Run Code Online (Sandbox Code Playgroud)

对于所有记录,变量 year 具有相同的值。删除年份变量后

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

preds <- predict.lm(model, dfTest[, c(1:nrow(dfTest)-1]))
Run Code Online (Sandbox Code Playgroud)

这没有给出警告信息