web-dev-qa-db-fra.com

predict.lm () dans une boucle. avertissement: la prédiction d'un ajustement déficient en grade peut être trompeuse

Ce code R lance un avertissement

# 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
}

J'ai un jeu de données d'apprentissage (C1) et un jeu de données de test (C2). Chacun a 129 variables. Je faisais k signifie une analyse de cluster sur le C1, puis divise mon ensemble de données en fonction de l'appartenance à un cluster et crée une liste de différents clusters (C1 [[1]], C1 [[2]], ..., C1 [[k] ]). J'ai également affecté une appartenance à un cluster à chaque cas dans C2 et créé C2 [[1]], ..., C2 [[k]]. Ensuite, j'adapte une régression linéaire à chaque cluster de C1. Ma variable dépendante est "Death". Mes prédicteurs sont différents dans chaque cluster et vars [[i]] (i = 1, ..., k) affiche une liste du nom des prédicteurs. Je veux prédire la mort pour chaque cas dans l'ensemble de données de test (C2 [[1]], ..., C2 [[k]). Lorsque je lance le code suivant, pour certains des clusters.

J'ai eu cet avertissement:

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

J'ai beaucoup lu sur cet avertissement, mais je ne pouvais pas comprendre le problème.

30
Mahsa

Vous pouvez inspecter la fonction de prédiction avec body(predict.lm). Là vous verrez cette ligne:

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

Cet avertissement vérifie si le rang de votre matrice de données est au moins égal au nombre de paramètres que vous souhaitez ajuster. Une façon de l’invoquer est d’avoir des covariables colinéaires:

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

Notez que x3 et x4 ont la même direction dans data. L'un est le multiple de l'autre. Ceci peut être vérifié avec length(fit$coefficients) > fit$rank

Une autre façon consiste à avoir plus de paramètres que de variables disponibles:

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

Cet avertissement:

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

Obtient jeté de R predict.lm _ . Voir: http://stat.ethz.ch/R-manual/R-devel/library/stats/html/predict.lm.html

Comprendre la déficience de rang: demandez à R de vous dire le rang d'une matrice:

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

Une matrice qui n'a pas de "rang complet" est dite "déficiente de rang". On dit qu'une matrice a un rang complet si son rang est égal à son nombre de colonnes ou à son nombre de lignes (ou aux deux).

Le problème est que predict.lm jettera cet avertissement même si vos matrices ont le rang complet (pas de rang déficient), parce que predict.lm en tire un rapide sous le capot, en rejetant ce qu’il considère comme des fonctionnalités inutiles, en modifiant votre entrée de rang complet en déficit de rang. Il s'en plaint ensuite par un avertissement.

Cet avertissement semble également être un fourre-tout pour d'autres situations telles que, par exemple, vous avez trop d'entités en entrée et votre densité de données est trop rare et elle donne à penser que les prédictions sont fragiles.

Exemple de passage de matrices de rangs complets, pourtant predict.lm se plaint toujours de l’insuffisance de rang

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 voit que les données de formation ne génèrent aucun gain d’information et rejette des fonctionnalités inutiles (en gros, toutes les fonctionnalités), puis indique que ce que vous lui avez donné n’est pas fiable, car le modèle présente de sérieux problèmes.

solution de contournement:

En supposant que Predict renvoie de bonnes prédictions, vous pouvez ignorer l'avertissement. predict.lm offre son opinion compte tenu d'une perspective insuffisante et vous voilà.

Donc, désactivez les avertissements sur l’étape de prédiction comme ceci:

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

C'est parce que l'une de vos variables dépendantes a NA pour les coefficients donnés en sortie par la fonction lm (..). Une telle variable ne change en rien le modèle, souvent en raison d’un problème de multicolinéarité, c’est-à-dire que cette variable prédictive est linéairement dépendante des autres variables prédictives OR car cette variable prédictive est constante pour tous les enregistrements ( La meilleure chose à faire est de supprimer cette variable de la formule dans la fonction lm (..) et de refaire la régression, ce qui ne réduit pas la précision du modèle.

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

variable année a la même valeur pour tous les enregistrements. Après avoir enlevé la variable année

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

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

Cela ne donne aucun message d'avertissement

3