Quali sono le differenze tra la regressione di Ridge usando glmnet di R e lo scikit-learn di Python?


11

Sto esaminando la sezione LAB §6.6 su Ridge Regression / Lasso nel libro 'An Introduction to Statistical Learning with Applications in R' di James, Witten, Hastie, Tibshirani (2013).

Più specificamente, sto cercando di applicare il Ridgemodello scikit-learn al set di dati "Hitters" dal pacchetto R "ISLR". Ho creato lo stesso set di funzionalità mostrato nel codice R. Tuttavia, non riesco ad avvicinarmi ai risultati del glmnet()modello. Ho selezionato un parametro di ottimizzazione L2 da confrontare. (argomento 'alfa' in scikit-learn).

Pitone:

regr = Ridge(alpha=11498)
regr.fit(X, y)

http://nbviewer.ipython.org/github/JWarmenhoven/ISL-python/blob/master/Notebooks/Chapter%206.ipynb

R:

Si noti che l'argomento alpha=0in glmnet()significa che dovrebbe essere applicata una penalità L2 (regressione di Ridge). La documentazione avverte di non inserire un singolo valore per lambda, ma il risultato è lo stesso di ISL, dove viene utilizzato un vettore.

ridge.mod <- glmnet(x,y,alpha=0,lambda=11498)

Cosa causa le differenze?

Modifica:
quando si utilizza penalized()dal pacchetto penalizzato in R, i coefficienti sono gli stessi di scikit-learn.

ridge.mod2 <- penalized(y,x,lambda2=11498)

Forse la domanda potrebbe anche essere: 'Qual è la differenza tra glmnet()e penalized()quando si fa la regressione di Ridge?

Nuovo wrapper python per il codice Fortran effettivo utilizzato nel pacchetto R glmnet
https://github.com/civisanalytics/python-glmnet


5
Totalmente sconosciuto con la regressione della cresta glmnet. Ma per impostazione predefinita, la sklearn.linear_model.Ridgestima di intercettazione non standardizzata (standard) e la penalità è tale da ||Xb - y - intercept||^2 + alpha ||b||^2essere minimizzata per b. Ci possono essere fattori 1/2o 1/n_samplesentrambi di fronte alla penalità, rendendo immediatamente i risultati diversi. Per fattorizzare il problema del ridimensionamento della penalità, imposta la penalità su 0 in entrambi i casi, risolvi eventuali discrepanze lì e controlla cosa fa l'aggiunta della penalità. E tra l'IMHO qui è il posto giusto per porre questa domanda.

Risposte:


9

1N


Ecco due riferimenti che dovrebbero chiarire la relazione.

La documentazione di sklearn afferma che linear_model.Ridgeottimizza la seguente funzione obiettivo

|Xβy|22+α|β|22

La carta glmnet afferma che la rete elastica ottimizza la seguente funzione obiettivo

|Xβy|22+λ(12(1α)|β|22+α|β|1)

ααλα

α=0λ=2αsklearnlinear_model.Ridge


E mi è mancato totalmente anche nel commento di @eickenberg. Devo usare standardize = FALSEin glmnet()per ottenere i risultati identici.
Jordi,

@Jordi Dovresti assolutamente standardizzare se utilizzi linear_model.Ridgeper qualsiasi analisi del mondo reale.
Matthew Drury,

Comprendo che il linear_model.Ridgemodello sklearn standardizza automaticamente le funzionalità. La normalizzazione è facoltativa. Mi chiedo perché debba quindi disattivare la standardizzazione glmnet()affinché i modelli producano risultati identici.
Jordi,

10

La risposta di Matthew Drury dovrebbe avere un fattore 1 / N. Più precisamente...

La documentazione glmnet afferma che la rete elastica riduce al minimo la funzione di perdita

1NXβy22+λ(12(1α)β22+αβ1)

La documentazione di sklearn afferma che linear_model.Ridgeriduce al minimo la funzione di perdita

Xβy22+αβ22

che equivale a minimizzare

1NXβy22+αNβ22

Per ottenere la stessa soluzione da glmnet e sklearn, entrambe le loro funzioni di perdita devono essere uguali. Questo significa impostare e in glmnet.α=0λ=2Nαsklearn

library(glmnet)
X = matrix(c(1, 1, 2, 3, 4, 2, 6, 5, 2, 5, 5, 3), byrow = TRUE, ncol = 3)
y = c(1, 0, 0, 1)
reg = glmnet(X, y, alpha = 0, lambda = 2 / nrow(X))
coef(reg)

uscita glmnet: –0.03862100, –0.03997036, –0.07276511, 0.42727955

import numpy as np
from sklearn.linear_model import Ridge
X = np.array([[1, 1, 2], [3, 4, 2], [6, 5, 2], [5, 5, 3]])
y = np.array([1, 0, 0, 1])
reg = Ridge(alpha = 1, fit_intercept = True, normalize = True)
reg.fit(X, y)
np.hstack((reg.intercept_, reg.coef_))

uscita sklearn: –0.03862178, –0.0399697, –0.07276535, 0.42727921


4
Le diverse definizioni di parametri e il loro ridimensionamento utilizzati in diverse librerie sono una fonte comune di confusione.
Aaron Defazio,

1
Non mi sarei aspettato che sia Gung che io avremmo sbagliato.
Michael R. Chernick,

2
Sì, entrambi avete sbagliato. Le tue ragioni per rifiutare la mia modifica chiariscono che entrambi non avete visto il mio commento "Fattore mancante di 1 / N" su stats.stackexchange.com/review/suggested-edits/139985
visitatore

La tua modifica è stata probabilmente respinta perché è cambiata molto di più di quello che rivendichi. Se desideri modificare il mio post e modificare solo il fattore mancante, ti preghiamo di farlo, ma cambiare anche i miei collegamenti, i miei termini e il mio codice è eccessivo. I commenti sul tuo trattamento ingiusto nella tua risposta sono inadeguati e non correlati al contenuto della domanda, rimuovili. La tua formulazione ha anche plagiato la mia risposta, questo non è il modo giusto per rispondere a una modifica rifiutata. Gradiremmo i tuoi preziosi contributi alla nostra comunità, ma ti preghiamo di informarti sulle nostre norme prima di sviscerarci.
Matthew Drury,

1
@visitor Scusami se sono venuto un po 'burbero. Dovrei solo cercare di comunicare che sembri un buon potenziale collaboratore del sito e voglio che tu abbia una buona esperienza. Abbiamo alcune norme sociali, proprio come qualsiasi altro gruppo, e vivrai un'esperienza migliore se ne sarai consapevole. Penso ancora che "la risposta di Matthew Drury sia sbagliata" è piuttosto dura, ci sono sicuramente modi migliori per comunicare che nella mia risposta manca erroneamente un fattore di . "La risposta di X è sbagliata" si legge come un attacco personale. 1N
Matthew Drury,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.