web-dev-qa-db-ja.com

ループ内のpredict.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の各クラスターに線形回帰を当てはめます。私の従属変数は「死」です。私の予測変数は各クラスターで異なり、vars [[i]](i = 1、...、k)は予測変数の名前のリストを示します。テストデータセット(C2 [[1]]、...、C2 [[k])の各ケースの死亡を予測したい。一部のクラスターで次のコードを実行すると。

この警告が表示されました:

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

私はこの警告について多くを読みましたが、問題が何であるかを理解できませんでした。

30
Mahsa

body(predict.lm)を使用して、予測関数を検査できます。そこにこの行が表示されます:

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

この警告は、データ行列のランクが少なくとも適合させたいパラメーターの数に等しいかどうかをチェックします。それを呼び出す1つの方法は、共線的な共変量を持つことです。

_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
_

dataでx3とx4の方向が同じであることに注意してください。 1つは他の倍数です。これはlength(fit$coefficients) > fit$rankで確認できます

もう1つの方法は、使用可能な変数よりも多くのパラメーターを持つことです。

_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
_
46

この警告:

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

Rからスローされます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

「フルランク」を持たないマトリックスは、「ランク不足」と呼ばれます。ランクが列の数または行の数(または両方)に等しい場合、マトリックスはフルランクを持つと言われます。

問題はそれです 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は、トレーニングデータの情報ゲインがゼロであり、役に立たない機能(基本的にはすべて)を捨てていることを確認し、モデルに深刻な問題があるため、提供したものは信頼できないと言います。

回避策:

Predictが適切な予測を返していると仮定すると、警告は無視できます。 predict.lmは、視点が不十分であるという意見を提供します。

したがって、次のように予測ステップで警告を無効にします。

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

これは、従属変数の1つが、lm(..)関数によって出力として与えられる係数のNAを持っているためです。そのような変数は、多くの場合、多重共線性の問題、つまり、その予測変数は他の予測変数に線形に依存するため、モデルに違いはありませんOR行)。最適な方法は、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

変数yearは、すべてのレコードで同じ値を持ちます。年変数を削除した後

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

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

これは警告メッセージを出しません