On this page:
1.6.10.1 The data
1.6.10.2 Fitting
1.6.10.3 Predicting
1.6.10.4 Grouped versus separate fits
1.6.10.5 When to use it
9.4.0.2

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))
> fit

#<glmnet:mgaussian λ=0.1 dev=0.9993 nz=1/2>

> (coef fit)

'#(#(1.1833030277982335 1.9476277063433618 0.0)

   #(9.908348486100884 -0.9738138531716809 0.0))

> (deviance-ratio fit)

0.9993142857142854

coef gives one vector per response, the intercept first. The x₁ coefficient is positive for the first response and negative for the second, and x₂ is exactly 0.0 in both. deviance-ratio is a single R² covering all the responses together.

1.6.10.3 Predicting🔗ℹ

predict returns one list per row, with one prediction per response; mgaussian-predict is the same call:

> (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
    (map (match-lambda
           [(list x₁ x₂)
            (define y₁ (+ 1 (* 2 x₁) (* 0.5 x₂)))
            (list y₁ (- 10 x₁))])
         X))

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. Each fit’s coefficients are shown to three decimals, the intercept β₀ first and then β:

> (define (show-coefs coefs)
    (for-each (compose displayln coef-line) (sequence->list coefs)))
> (match-define (list y₁ y₂) (apply map list Y2))
> (define separate (list (lasso X y₁ #:lambda 0.05) (lasso X y₂ #:lambda 0.05)))
> (show-coefs (map coef separate))

β₀ = 1.357, β = (1.959 0.359)

β₀ = 9.898, β = (-0.971 0.000)

> (define grouped (mgaussian-fit X Y2 #:lambda 0.05))
> (show-coefs (coef grouped))

β₀ = 1.340, β = (1.962 0.362)

β₀ = 9.934, β = (-0.986 0.011)

Raise λ and the grouped fit drops x₂ from both responses at once:

> (define grouped-0.2 (mgaussian-fit X Y2 #:lambda 0.2))
> (show-coefs (coef grouped-0.2))

β₀ = 2.265, β = (1.853 0.000)

β₀ = 9.814, β = (-0.947 0.000)

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.