2016-09-14 4 views
4

Я пытаюсь запустить различные модели регрессии по данным рака простаты из пакета lasso2. Когда я использую Lasso, я видел два разных метода для вычисления среднеквадратической ошибки. Но они дают мне совсем другие результаты, поэтому я хотел бы знать, что я делаю что-то неправильно или это просто означает, что один метод лучше другого?Почему вычисление MSE в регрессии лассо дает разные выходы?

# Needs the following R packages. 
library(lasso2) 
library(glmnet) 

# Gets the prostate cancer dataset 
data(Prostate) 

# Defines the Mean Square Error function 
mse = function(x,y) { mean((x-y)^2)} 

# 75% of the sample size. 
smp_size = floor(0.75 * nrow(Prostate)) 

# Sets the seed to make the partition reproductible. 
set.seed(907) 
train_ind = sample(seq_len(nrow(Prostate)), size = smp_size) 

# Training set 
train = Prostate[train_ind, ] 

# Test set 
test = Prostate[-train_ind, ] 

# Creates matrices for independent and dependent variables. 
xtrain = model.matrix(lpsa~. -1, data = train) 
ytrain = train$lpsa 
xtest = model.matrix(lpsa~. -1, data = test) 
ytest = test$lpsa 

# Fitting a linear model by Lasso regression on the "train" data set 
pr.lasso = cv.glmnet(xtrain,ytrain,type.measure='mse',alpha=1) 
lambda.lasso = pr.lasso$lambda.min 

# Getting predictions on the "test" data set and calculating the mean  square error 
lasso.pred = predict(pr.lasso, s = lambda.lasso, newx = xtest) 

# Calculating MSE via the mse function defined above 
mse.1 = mse(lasso.pred,ytest) 
cat("MSE (method 1): ", mse.1, "\n") 

# Calculating MSE via the cvm attribute inside the pr.lasso object 
mse.2 = pr.lasso$cvm[pr.lasso$lambda == lambda.lasso] 
cat("MSE (method 2): ", mse.2, "\n") 

Так что эти выходные я получил как для MSE:

MSE (method 1): 0.4609978 
MSE (method 2): 0.5654089 

И они совершенно разные. Кто-нибудь знает, почему? Большое спасибо за вашу помощь!

Samuel

+0

Если я правильно читать, 'mse.1' является тест MSE и 'mse.2' является ошибкой перекрестной проверки выбранной модели, но основывается исключительно на данных обучения. – alistaire

+0

Спасибо, что указали это на alistaire. Таким образом, правильная последовательность будет состоять в том, чтобы запустить cv.glmnet над данными обучения, чтобы получить наилучшую лямбду, а затем использовать метод 1 для MSE? Я предполагаю, что нет смысла повторно запускать cv.glmnet во второй раз по тестовым данным, чтобы взять cvm (средняя перекрестная проверенная ошибка)? Извините, я немного смущен. – chogall

+0

Вы используете кросс-валидацию, чтобы дать вам оценку ошибки теста, чтобы выяснить, какое значение лямбда использовать в ваших тестовых данных. Вы должны касаться только своих тестовых данных. – alistaire

ответ

1

Как отметил @alistaire, в первом случае вы используете тестовые данные для вычисления MSE, во втором случае MSE от перекрестной проверки (подготовка) сгибы сообщается, так это не сравнение яблок с яблоками.

Мы можем сделать что-то вроде следующего, чтобы сравнить яблоки с яблоками (сохраняя установленные значения на тренировочных сгибах), и, как мы видим, mse.1 и mse.2 в точности равны, если они вычисляются на тех же тренировочных сгибах (хотя значение мало чем отличается от вашего, с моей настольной версией R 3.1.2, x86_64-w64-mingw32, окно 10):

# Needs the following R packages. 
library(lasso2) 
library(glmnet) 

# Gets the prostate cancer dataset 
data(Prostate) 

# Defines the Mean Square Error function 
mse = function(x,y) { mean((x-y)^2)} 

# 75% of the sample size. 
smp_size = floor(0.75 * nrow(Prostate)) 

# Sets the seed to make the partition reproductible. 
set.seed(907) 
train_ind = sample(seq_len(nrow(Prostate)), size = smp_size) 

# Training set 
train = Prostate[train_ind, ] 

# Test set 
test = Prostate[-train_ind, ] 

# Creates matrices for independent and dependent variables. 
xtrain = model.matrix(lpsa~. -1, data = train) 
ytrain = train$lpsa 
xtest = model.matrix(lpsa~. -1, data = test) 
ytest = test$lpsa 

# Fitting a linear model by Lasso regression on the "train" data set 
# keep the fitted values on the training folds 
pr.lasso = cv.glmnet(xtrain,ytrain,type.measure='mse', keep=TRUE, alpha=1) 
lambda.lasso = pr.lasso$lambda.min 
lambda.id <- which(pr.lasso$lambda == pr.lasso$lambda.min) 

# get the predicted values on the training folds with lambda.min (not from test data) 
mse.1 = mse(pr.lasso$fit[,lambda.id], ytrain) 
cat("MSE (method 1): ", mse.1, "\n") 

MSE (method 1): 0.6044496 

# Calculating MSE via the cvm attribute inside the pr.lasso object 
mse.2 = pr.lasso$cvm[pr.lasso$lambda == lambda.lasso] 
cat("MSE (method 2): ", mse.2, "\n") 

MSE (method 2): 0.6044496 

mse.1 == mse.2 
[1] TRUE 
+0

Спасибо за ваш ответ @sandipan. Таким образом, cv.glmnet использует по умолчанию 10 раз. Указав гораздо большее количество сгибов, означает ли это, что результат перекрестной проверки будет лучше? – chogall

+0

с большим количеством складок может привести к переобучению, так как вы получаете больше данных для обучения. –

+0

Хорошо, так что лучше оставить значение по умолчанию K = 10? Или есть способ найти оптимальное количество складок? – chogall

Смежные вопросы