Predict.lm в R не распознает новые данные

Я запускаю линейную регрессию, в которой предиктор классифицируется по другому значению, и у меня возникают проблемы с созданием смоделированных ответов для новых данных.

Во-первых, я генерирую несколько случайных значений для предиктора и ошибок. Затем я строю ответ. Обратите внимание, что коэффициент предиктора зависит от значения категориальной переменной. Я составляю матрицу дизайна на основе предиктора и его категории.

set.seed(1)

category = c(rep("red", 5), rep("blue",5))
x1 = rnorm(10, mean = 1, sd = 1)
err = rnorm(10, mean = 0, sd = 1)

y = ifelse(category == "red", x1 * 2, x1 * 3)
y = y + err

df = data.frame(x1 = x1, category = category)

dm = as.data.frame(model.matrix(~ category + 0, data = df))
dm = dm * df$x1

fit = lm(y ~ as.matrix(dm) + 0, data = df)

# This line will not produce a warning
predictOne = predict.lm(fit, newdata = dm)

# This line WILL produce a warning
predictTwo = predict.lm(fit, newdata = dm[1:5,])

Предупреждение:

'newdata' было 5 строк, но найденные переменные имеют 10 строк

Если я не ошибаюсь, у меня не должно быть проблем с именами переменных. (На этой доске есть одно или два обсуждения, которые предлагают эту проблему.) Обратите внимание, что первый прогноз выполняется нормально, а второй — нет. Единственное изменение заключается в том, что второй прогноз использует только первые пять строк матрицы плана.

Мысли?


person PirateGrunt    schedule 22.01.2013    source источник
comment
Настоящая проблема здесь заключается в вашей, скажем так, творческой попытке указать модель через интерфейс формулы lm.   -  person joran    schedule 22.01.2013
comment
На странице справки predict.lm говорится, что аргумент «newdata» должен быть фреймом данных. Предупреждение выглядит немного не так, как нужно, но, возможно, оно лучше, чем поведение по умолчанию, которое заключается в молчаливом сообщении прогнозов на основе исходных данных, когда вы могли подумать, что получаете новые прогнозы.   -  person IRTFM    schedule 22.01.2013


Ответы (3)


Я не уверен на 100%, что вы пытаетесь сделать, но я думаю, что краткий обзор того, как работают формулы, прояснит для вас ситуацию.

Основная идея очень проста: вы передаете две вещи, формулу и фрейм данных. Термины в формуле должны все быть именами переменных в вашем фрейме данных.

Теперь вы можете заставить lm работать, не следуя этому правилу в точности, но вы просто просите, чтобы что-то пошло не так. Так что остановитесь и посмотрите на характеристики вашей модели и подумайте, где R ищет что-то.

Когда вы вызываете lm, в действительности ни одно из имен в вашей формуле не находится во фрейме данных df. Поэтому я подозреваю, что df вообще не используется.

Затем, если вы вызовете model.frame(fit), вы увидите, как, по мнению R, должны вызываться ваши переменные. Заметили что-нибудь странное?

model.frame(fit)
            y as.matrix(dm).categoryblue as.matrix(dm).categoryred
1   2.2588735                  0.0000000                 0.3735462
2   2.7571299                  0.0000000                 1.1836433
3  -0.2924978                  0.0000000                 0.1643714
4   2.9758617                  0.0000000                 2.5952808
5   3.7839465                  0.0000000                 1.3295078
6   0.4936612                  0.1795316                 0.0000000
7   4.4460969                  1.4874291                 0.0000000
8   6.1588103                  1.7383247                 0.0000000
9   5.5485653                  1.5757814                 0.0000000
10  2.6777362                  0.6946116                 0.0000000

Есть ли что-нибудь под названием as.matrix(dm).categoryblue в dm? Да, я так не думал.

Я подозреваю (но не уверен), что вы хотели сделать что-то вроде этого:

df$y <- y
fit <- lm(y~category - 1,data = df)
person joran    schedule 22.01.2013

Джоран на правильном пути. Проблема связана с именами столбцов. Что я хотел сделать, так это создать свою собственную матрицу дизайна, что, как оказалось, мне не нужно было делать. Если запустить модель со следующей строкой кода, все будет гладко:

fit = lm(y ~ x1:category + 0, data = df)

Это обозначение формулы заменит ручное построение матрицы проекта.

Я использовал свою собственную матрицу проектирования в прошлом, и параметры подгонки и диагностика были такими, какими они должны были быть. Я не использовал функцию прогнозирования, поэтому никогда не знал, что R отбрасывает параметр «data =». Предупреждение было бы круто. R - суровая любовница.

person PirateGrunt    schedule 22.01.2013

Это может помочь. Преобразуйте новые данные как data.frame, например:

x = 1:5
y = c(2,4,6,8,10)

fit = lm(y ~ x)

# PREDICTION
newx = c(3,5,7)

predict(fit, data.frame(x=newx))
person Hadi Pourbagher    schedule 01.07.2019