library(caret) library(mlbench) library(leaps) library(lib7af) #library(MASS) seed <- 111 set.seed(seed) tracon <- caret::trainControl("cv") data("BostonHousing")
In lib7af, we created a package with a function called ridgereg. This function is able to take a formula object, a dataset and a parameter lambda $\lambda$. The situation when a ridge regression is intended to be used, is when p>n or when multikollinearity is present. Different scalings of the covariates in X will affect results. That is why we finetune the the model to best fit the lambda parameters. Before we do so, we must normalize all covariates so the analysis can be done.
QR decomposition is used to calculate the regression coefficients.
Create are partition of the dataset. 70% for the training data and 30% for the test data.
tr_data_index<-createDataPartition(BostonHousing$medv, p=0.7, times= 1, list= FALSE) tr_data<-BostonHousing[tr_data_index,] te_data<-BostonHousing[-tr_data_index,]
The model is fitted - one time with linear regression and one using forward selection.
l_n_m<-train(medv~., tr_data, method="lm", trControl = tracon) l_n_m l_n_M<-train(medv~., tr_data, method="leapForward", trControl = tracon) l_n_M
For the forward selection, the RMSE was used to select the optimal model. Comparing the linear model and the model selected with forward regression shows that the linear model has a lower RMSE. A lower RMSE value suggests a better fit and $R^2$ indicates how much data is represented by the model.
l_n_m$results$RMSE l_n_M$results$RMSE
# Acknowledgement to Eric Herwin and Albin Vasterlund ridge_example<- list(type = "Regression", library ="lib7af", loop= NULL, prob=NULL) ridge_example$parameters<-data.frame(parameter="lambda", class="numeric", label="Ridge Regression") ridge_example$grid<-function(x,y,len=NULL, search="grid"){ data.frame(lambda=lambda) } ridge_example$fit <- function (x, y, wts, param, lev, last, classProbs, ...) { d_rid <- if (is.data.frame(x)) x else as.data.frame(x) d_rid$.outcome<-y results<-ridgereg(.outcome ~ ., data=d_rid ,lambda = param$lambda, ...) return(results) } ridge_example$predict<-function (modelFit, newdata, submodels = NULL) { if (!is.data.frame(newdata)) newdata <- as.data.frame(newdata) newdata <- scale(newdata) return(modelFit$predict(newdata)) }
set.seed(seed) result<-c() for(lambda in seq(0, 20, by = 1)) { zwes <- train(medv~., data = tr_data, ridge_example) result[lambda] <- zwes$results$RMSE } lambda <- which.min(result) / 10 RMSE <- result[which.min(result)] lambda RMSE
We can see, that the best $\lambda$ is 1.1 and the RMSE is 23.1903.
Finding the best hyperparameter value for $\lambda$ using 10-folf cross-validation on the training set.
set.seed(seed) count<-10 l_val<-seq(0.1,by=.1) fit_control<-trainControl(method="repeatedcv", number=count, repeats= count) ridge_example<-train(medv~., data=te_data, method=ridge_example, trControl= fit_control) ridge_example
lin_mod <- predict(l_n_m, te_data) postResample(lin_mod,te_data$medv) lin_mod_with <- predict(l_n_M, te_data) postResample(lin_mod_with,te_data$medv) ridge_ex <- predict(ridge_example, te_data) postResample(ridge_ex,te_data$medv)
Even though the model fit by ridge regression has the highest $R^2$, the RMSE is really high. Therefore the linear models seem to be more suitable here.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.