Функция линейного прогнозирования R линейной модели (лм) с одним массивом

У меня есть lm модель в R, которую я обучил и сериализовал. Внутри функции, куда я передаю в качестве входных данных модель и вектор объектов (один отдельный массив), у меня есть:

CREATE OR REPLACE FUNCTION lm_predict(
    feat_vec float[],
    model bytea
)
RETURNS float
AS
$$
    #R-code goes here.
    mdl <- unserialize(model)
    # class(feat_vec) outputs "array"
    y_hat <- predict.lm(mdl, newdata = as.data.frame.list(feat_vec))
    return (y_hat)
$$ LANGUAGE 'plr';

Это возвращает неправильное y_hat!! Я знаю это, потому что это другое решение работает (входные данные для этой функции все еще модель (в байтовом массиве) и один feat_vec (Массив)):

CREATE OR REPLACE FUNCTION lm_predict(
    feat_vec float[],
    model bytea
)
RETURNS float
AS
$$
    #R-code goes here.
    mdl <- unserialize(model)
    coef = mdl$coefficients
    y_hat = coef[1] + as.numeric(coef[-1]%*%feat_vec)
    return (y_hat)
$$ LANGUAGE 'plr';

Что я делаю неправильно?? Это та же несериализованная модель, первый вариант также должен дать мне правильный ответ...

1 ответ

Решение

Проблема, кажется, заключается в использовании newdata = as.data.frame.list(feat_vec), Как обсуждалось в вашем предыдущем вопросе, это возвращает уродливые имена столбцов. Хотя, когда вы звоните predict, newdata должны иметь имена столбцов, соответствующие именам ковариат в формуле модели. Вы должны получить предупреждающее сообщение при звонке predict,

## example data
set.seed(0)
x1 <- runif(20)
x2 <- rnorm(20)
y <- 0.3 * x1 + 0.7 * x2 + rnorm(20, sd = 0.1)

## linear model
model <- lm(y ~ x1 + x2)

## new data
feat_vec <- c(0.4, 0.6)
newdat <- as.data.frame.list(feat_vec)
#  X0.4 X0.6
#1  0.4  0.6

## prediction
y_hat <- predict.lm(model, newdata = newdat)
#Warning message:
#'newdata' had 1 row but variables found have 20 rows 

Что вам нужно

newdat <- as.data.frame.list(feat_vec,
                             col.names = attr(model$terms, "term.labels"))
#   x1  x2
#1 0.4 0.6

y_hat <- predict.lm(model, newdata = newdat)
#        1 
#0.5192413 

Это то же самое, что вы можете вычислить вручную:

coef = model$coefficients
unname(coef[1] + sum(coef[-1] * feat_vec))
#[1] 0.5192413 
Другие вопросы по тегам