1.6.10 Multi-response Gaussian (grouped)
Source: "glmnet/examples/08-mgaussian.rkt"
The multi-response Gaussian family fits several numeric responses at once. The response is a matrix with one column per response, and the penalty is a grouped lasso across responses: a predictor enters for every response or for none, so all the responses share one set of selected predictors. Each response keeps its own intercept and its own coefficients, and prediction is ŷr = a0r + xβr.
1.6.10.1 The data
Both responses depend on x₁, the first rising with it (y₁ = 1 + 2x₁) and the second falling (y₂ = 10 − x₁); x₂ carries no signal:
> (define X '((1.0 2.0) (2.0 1.0) (3.0 2.0) (4.0 1.0) (5.0 2.0) (6.0 1.0))) > (define Y '((3.0 9.0) (5.0 8.0) (7.0 7.0) (9.0 6.0) (11.0 5.0) (13.0 4.0)))
1.6.10.2 Fitting
> (define fit (mgaussian-fit X Y #:lambda 0.1)) > (mgaussian-result-intercepts fit) '#(1.1833030277982335 9.908348486100884)
> (mgaussian-result-coefficients fit) '#(#(1.9476277063433618 0.0) #(-0.9738138531716809 0.0))
> (mgaussian-result-r-squared fit) 0.9993142857142854
There is one coefficient vector per response. The x₁ coefficient is positive for the first and negative for the second, and x₂ is exactly 0.0 in both. mgaussian-result-r-squared is a single number covering all the responses together.
1.6.10.3 Predicting
mgaussian-predict, which is predict with its defaults, returns one list per row, with one prediction per response:
> (mgaussian-predict fit '((7.0 1.0) (8.0 2.0)))
'((14.816696972201767 3.0916515138991176)
(16.76432467854513 2.117837660727437))
1.6.10.4 Grouped versus separate fits
What the grouping buys shows when a predictor matters for some responses and not others. Give the first response a weak dependence on x₂ and leave the second without one:
> (define Y2 (for/list ([row (in-list X)]) (define x1 (car row)) (define x2 (cadr row)) (list (+ 1 (* 2 x1) (* 0.5 x2)) (- 10 x1))))
Fitting each response on its own with the lasso keeps x₂ for the first and drops it for the second. The grouped fit keeps x₂ for both, with a small coefficient where it does not belong:
> (define (round3 x) (/ (round (* 1000 x)) 1000))
> (define (rounded v) (for/list ([b (in-vector v)]) (round3 b))) > (rounded (elnet-result-coefficients (lasso X (map car Y2) #:lambda 0.05))) '(1.959 0.359)
> (rounded (elnet-result-coefficients (lasso X (map cadr Y2) #:lambda 0.05))) '(-0.971 0.0)
> (map rounded (vector->list (mgaussian-result-coefficients (mgaussian-fit X Y2 #:lambda 0.05)))) '((1.962 0.362) (-0.986 0.011))
Raise λ and the grouped fit drops x₂ from both responses at once:
> (map rounded (vector->list (mgaussian-result-coefficients (mgaussian-fit X Y2 #:lambda 0.2)))) '((1.853 0.0) (-0.947 0.0))
1.6.10.5 When to use it
Use the multi-response family when several outcomes are measured on the same units and are expected to depend on the same predictors: several physiological measurements per subject, or returns on related assets. The shared selection borrows strength across responses. If the responses depend on different predictors, fit them separately.