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

Я много читал об этом предупреждении, но не мог понять, в чем проблема.

Ответ 1

Вы можете проверить функцию прогнозирования с помощью 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

Ответ 2

Это предупреждение:

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 выдаст это предупреждение, даже если ваши матрицы имеют полный ранг (не ранг с недостатками), потому что предикат 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

pregnet.lm видит, что данные обучения имеют нулевой прирост информации, и отбрасывает бесполезные функции (в основном все), а затем говорит, что то, что вы им дали, ненадежно, потому что у модели серьезные проблемы.

обходной путь:

Предполагая, что прогнозирование возвращает хорошие прогнозы, вы можете игнорировать предупреждение. Предсказание дает свое мнение, учитывая недостаточную перспективу, и вот вы здесь.

Поэтому отключите предупреждения на шаге прогнозирования следующим образом:

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

Ответ 3

Это потому, что одна из ваших зависимых переменных имеет 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

переменная year имеет одинаковое значение для всех записей. После удаления переменной года

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

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

Это не дает предупреждение