Прогнозирование новых данных с использованием glm и cv.gl mnet в R (включая взаимодействия и категориальные переменные) - PullRequest
2 голосов
/ 31 марта 2020

Я хотел бы смоделировать формулу регрессии, включающую взаимодействия и категориальные переменные. Мне интересно использовать glm и gl mnet :: cv.gl mnet. Я согласен с функциями, которые соответствуют модели, но я не совсем уверен, что использую обученные модели для правильного прогнозирования выборочных данных. Вот пример.

Formula <- "Sepal.Length ~ Sepal.Width + Petal.Length + as.factor(Species):Petal.Width + Sepal.Width:Petal.Length +  as.factor(Species) +  bs(Petal.Width, df = 2, degree = 2)"

data("iris")
Inx <- sample( 1: nrow(iris), nrow(iris),  replace = F)

iris$Species <- as.factor(iris$Species)

train_data <- iris[Inx[1:100], ]
test_data <- iris[Inx[101:nrow(iris) ],]

#---- glm -----------------
ModelMatrix <- predict(caret::dummyVars(Formula, train_data, fullRank = T, sep = ""), train_data)
glmfit <- glm(formula = as.formula(Formula) , data = train_data)

prd_glm <- predict(glmfit, newx = ModelMatrix, type = "response")

#------- glm cross validation --------------
cvglm <- glmnet::cv.glmnet(x = ModelMatrix,
                           y = train_data$Sepal.Length,
                           nfolds = 4, keep = TRUE, alpha = 1, parallel = F, type.measure = 'mse')

ModelMatrix_test <- predict(caret::dummyVars(Formula, test_data, fullRank = T, sep = ""), test_data)
prd_cvglm <- predict(cvglm, newx = ModelMatrix_test,  s = "lambda.1se", type ='response')

1 Ответ

1 голос
/ 31 марта 2020

Вы используете либо матрицу модели, либо формулу, но не оба, потому что, как только вы предоставите формулу, любой glm будет внутренне генерировать матрицу модели. И вы учитываете только один раз. Итак, в вашем случае, скажем, прямо подойдет модель matrx:

library(splines)
library(caret)
library(glmnet)

data(iris)
Inx <- sample(nrow(iris),100)
iris$Species <- factor(iris$Species)

train_data <- iris[Inx, ]
test_data <- iris[-Inx,]

Formula <- "Sepal.Length ~ Sepal.Width + Petal.Length + Species:Petal.Width + Sepal.Width:Petal.Length +  Species +  bs(Petal.Width, df = 2, degree = 2)"

glmfit <- glm(as.formula(Formula),data=train_data)

Вы можете видеть, что это то же самое, что подгонка по формуле:

ModelMatrix <- predict(caret::dummyVars(Formula, train_data, fullRank = T, sep = ""), train_data)
y = train_data[,"Sepal.Length"]
fit_dummy = glm(y ~ ModelMatrix)
table(fitted(glmfit) == fitted(fit_dummy))
TRUE 
 100

И мы прогнозируем на тесте данные:

prd_glm <- predict(glmfit, newdata = test_data, type = "response")

Тогда для gl mnet:

cvglm <- cv.glmnet(x = ModelMatrix,y = train_data$Sepal.Length,nfolds = 4, 
    keep = TRUE, alpha = 1, parallel = F, type.measure = 'mse')

ModelMatrix_test <- predict(caret::dummyVars(Formula, test_data, fullRank = T, sep = ""), test_data)
prd_cvglm <- predict(cvglm, newx = ModelMatrix_test,  s = "lambda.1se", type ='response')

Вы можете увидеть, как они отличаются:

plot(prd_glm,prd_cvglm)

enter image description here

...