Error in h(simpleError(msg, call)) in Ridge/Lasso Regression

Viewed 7776

I am trying to run ridge/lasso with the glmnetand onehot package and getting an error.

library(glmnet)
library(onehot)
set.seed(123)

Sample <- HouseData[1:1460, ]  
smp_size <- floor(0.5 * nrow(Sample))
train_ind <- sample(seq_len(nrow(Sample)), size = smp_size)
train <- Sample[train_ind, ]
test <- Sample[-train_ind, ]

############Ridge & Lasso Regressions ################

# Define the response for the training + test set
y_train <- train$SalePrice
y_test <- test$SalePrice

# Define the x training and test
x_train <- train[,!names(train)=="SalePrice"]
x_test <- test[,!names(train)=="SalePrice"]
str(y_train)

## encoding information for training set 
x_train_encoded_data_info <- onehot(x_train,stringsAsFactors = TRUE, max_levels = 50)
x_train_matrix <- (predict(x_train_encoded_data_info,x_train)) 
x_train_matrix <- as.matrix(x_train_matrix)

# create encoding information for x test
x_test_encoded_data_info <- onehot(x_test,stringsAsFactors = TRUE, max_levels = 50)
x_test_matrix <- (predict(x_test_encoded_data_info,x_test)) 
str(x_train_matrix)

###Calculate best lambda 
cv.out <- cv.glmnet(x_train_matrix, y_train,
                    alpha = 0, nlambda = 100,
                    lambda.min.ratio = 0.0001)

best.lambda <- cv.out$lambda.min
best.lambda
model <- glmnet(x_train_matrix, y_train, alpha = 0, lambda = best.lambda)
results_ridge <- predict(model,newx=x_test_matrix)

I know my data is clean and my matrices are the same size, But I keep getting this error when I try to run my prediction.

Error in h(simpleError(msg, call)) : error in evaluating the argument 'x' in selecting a method for function 'as.matrix': Cholmod error 'X and/or Y have wrong dimensions' at file ../MatrixOps/cholmod_sdmult.c, line 90

My professor has also told me to one-hot encode before I split my data, but that makes no sense to me.

1 Answers

It's hard to debug that specific error because it's not entirely clear where the onehot function in your code is coming from; it doesn't exist in base R or the glmnet package.

That said, I would recommend using the old built-in standby function model.matrix (or its sparse cousin, sparse.model.matrix, if you have larger datasets) for creating the x argument to glmnet. model.matrix will automatically one-hot encode factor or categorical variables for you. It requires a model formula as input, which you can create from your dataset as shown below.

# create the model formula
y_variable <- "SalePrice"
model_formula <- as.formula(paste(y_variable, "~",
                                  paste(names(train)[names(train) != y_variable], collapse = "+"))) 
# test & train matrices
x_train_matrix <- model.matrix(model_formula, data = train)[, -1]
x_test_matrix <- model.matrix(model_formula, data = test)[, -1]

###Calculate best lambda 
cv.out <- cv.glmnet(x_train_matrix, y_train,
                    alpha = 0, nlambda = 100,
                    lambda.min.ratio = 0.0001)

A second, newer option would be to use the built-in glmnet function makeX(), which builds matrices off of your test/train dataframes. This can just be fed into cv.glmnet as the x argument as below.

## option 2: use glmnet built in function to create x matrices
x_matrices <- glmnet::makeX(train = train[, !names(train) == "SalePrice"],
                            test = test[, !names(test) == "SalePrice"])

###Calculate best lambda 
cv.out <- cv.glmnet(x_matrices$x, y_train,
                    alpha = 0, nlambda = 100,
                    lambda.min.ratio = 0.0001)
Related