library(mlr)
daf = read.csv("https://pastebin.com/raw/p1cCCYBR", sep = " ", header = FALSE)
tsk = list(
tsk1110 = makeRegrTask(id = "tsk1110", data = daf, target = colnames(daf)[1]),
tsk500 = makeRegrTask(id = "tsk500", data = daf[, c(1,sample(ncol(daf)-1, 500)+1)], target = colnames(daf)[1]),
tsk100 = makeRegrTask(id = "tsk100", data = daf[, c(1,sample(ncol(daf)-1, 100)+1)], target = colnames(daf)[1]),
tsk50 = makeRegrTask(id = "tsk50", data = daf[, c(1,sample(ncol(daf)-1, 50)+1)], target = colnames(daf)[1]),
tsk10 = makeRegrTask(id = "tsk10", data = daf[, c(1,sample(ncol(daf)-1, 10)+1)], target = colnames(daf)[1])
)
lrn = makeLearner("regr.glmnet", alpha = 0)
rdesc = makeResampleDesc("CV", iters = 10)
msrs = list(mse, rsq)
ctrl = makeTuneControlGridconfigureMlr(resolutionon.par.without.desc = 15L"quiet")
psetbm3 = makeParamSetbenchmark(learners makeNumericParam= list("lambda",
lower = -10 makeLearner("regr.cvglmnet", upperalpha = 100, trafolambda = functionc(x)0, exp(xseq(-10, 10, length.out = 150))),
cvl = makeTuneWrapper(learner = lrnmakeLearner("regr.glmnet", resamplingalpha = rdesc0, measureslambda = msrsc(0, controlexp(seq(-10, 10, length.out = ctrl150))), par.sets = pset151)
bm = benchmark(learners = cvl), tasks = tsk, resamplings = rdesc, measures = msrs)
>getBMRAggrPerformances(bm3, bmas.df = TRUE) # task.id learner.id mse.test.mean rsq.test.mean #1 tsk10 regr.cvglmnet 1.0308055 -0.224534550 #2 tsk10 regr.glmnet 1.tuned3685799 -0.669473387 #3 tsk100 regr.cvglmnet 0.90297397996823 -0.34385207031731316 2#4 tsk100 regr.glmnet 1.tuned3092522 -0.656879104 #5 tsk1110 regr.cvglmnet 0.98600338236786 -0.20159950009315037 3#6 tsk1110 regr.glmnet.tuned 0.68364746866745 0.117540454 #7 tsk50 regr.cvglmnet 1.0348319 -0.08630208188568886 4#8 tsk50 regr.glmnet 2.tuned5468091 -2.423461744 #9 tsk500 regr.cvglmnet 0.91591907210185 -0.15177725173851634 5#10 tsk500 regr.glmnet.tuned 0.8874529 6171841 0.04095012296530437
They do basically got the same slightly better than random performance, but glmnet
is good enough to squeeze some information the more features you feed itacross tasks.
getBMRTuneResultssapply(bm, as.df = TRUElapply(getBMRModels(bm3, task.ids = "tsk1110")
# task.id learner.id iter lambda mse.test.mean rsq.test.mean
#1 tsk1110 regr.glmnet.tuned 1 0.239651 0.7234743 0.06932993
#2 tsk1110 regr.glmnet.tuned [[1]][[1]], "[[", 2 0.239651 0.6318552 0.10130075
#3 tsk1110 regr.glmnet.tuned 3 0.239651 0.7202225 ), "[[", 0"lambda.09277869min")
#4 tsk1110 regr.glmnet.tuned # 4[1] 4.172734 0.7169810 539993e-0.08232901
#5 tsk1110 regr.glmnet.tuned 5 0.239651 05 04.7163615 539993e-0.05643168
#6 tsk1110 regr.glmnet.tuned 6 0.239651 0.6655465 0.13894617
#7 tsk1110 regr.glmnet.tuned 7 0.239651 0.7125394 0.14249063
#8 tsk111005 regr.glmnet2.tuned 8442908e-01 01.239651 398738e+00 04.7312063 539993e-0.5697540805
#9 tsk1110 regr.glmnet.tuned # 9[6] 0.239651 000000e+00 04.6895064 539993e-0.03308516
#10 tsk1110 regr.glmnet.tuned 1005 03.239651 195187e-01 02.6370360 793841e-01 04.02805295539993e-05
Notice the lambdas are already transformed. Not a singleSome fold even picked the minimal lambda $\exp(-10)\approx 4.54 \mathbf E-5$ (this is the same behavior with cv.glmnet
in R)$\lambda = 0$.
#EDIT:
After comments by amoeba, it became clear the regularization path is an important step in the glmnet
estimation, so the code now reflects it. This way, most discrepancies vanished.
So, basically, $\lambda>0$ really improves the fit (edit: but not by much!).
Edit: Keep in mind, though, the ridge regularization path makes use of previous parameter estimates when we call glmnet
, but this is beyond my expertise. If we set a really low lambda
in isolation, it'll likely degrade performance.
We picked the best lambda in the most parsimonious way, and we expect it to be the more performant than any other arbitrary selection. Repeating the benchmark with the addition of a glmnet
with lambda
set to a ludicrously small value (1E-100
), we see that our tuning really improves the result.
bm2 = benchmark(learners = list(cvl, makeLearner("regr.glmnet", alpha = 0, lambda = 1E-100)), tasks = tsk, resamplings = rdesc, measures = msrs)
getBMRAggrPerformances(bm2, as.df = TRUE)
# task.id learner.id mse.test.mean rsq.test.mean
#1 tsk10 regr.glmnet.tuned 1.0302354 -0.36840610
#2 tsk10 regr.glmnet 1.2542921 -0.58709603
#3 tsk100 regr.glmnet.tuned 0.8721003 -0.01025020
#4 tsk100 regr.glmnet 2.6139448 -2.56834215
#5 tsk1110 regr.glmnet.tuned 0.6716137 0.26026566
#6 tsk1110 regr.glmnet 1.4569493 -0.76811536
#7 tsk50 regr.glmnet.tuned 0.7851516 0.02185949
#8 tsk50 regr.glmnet 1.8970910 -1.69729756
#9 tsk500 regr.glmnet.tuned 0.8556580 -0.05821649
#10 tsk500 regr.glmnet 1.6703070 -1.02238746
There's an element of randomness involved, but the tuned model always outperform the asymptotically-OLS ridge, often by quite a marging.Edit: notice though when we set lambda
to 0 after running the whole regularization path performance doesn't degrade as such, therefore the regularization path is key to understand what's going on!