Estoy tratando de duplicar los resultados de sklearn
la biblioteca de regresión logística usando el glmnet
paquete en R.
A partir de la documentación desklearn
regresión logística , está tratando de minimizar la función de costo bajo penalización l2
De las viñetas de glmnet
, su implementación minimiza una función de costo ligeramente diferente
Con algunos ajustes en la segunda ecuación, y al configurar ,
que difiere de la sklearn
función de costo solo por un factor de si se establece , por lo que esperaba la misma estimación de coeficiente de los dos paquetes. Pero son diferentes. Estoy usando el conjunto de datos del tutorial idre de UCLA , prediciendo en admit
base a gre
, gpa
y rank
. Hay 400 observaciones, entonces con , .
#python sklearn
df = pd.read_csv("https://stats.idre.ucla.edu/stat/data/binary.csv")
y, X = dmatrices('admit ~ gre + gpa + C(rank)', df, return_type = 'dataframe')
X.head()
> Intercept C(rank)[T.2] C(rank)[T.3] C(rank)[T.4] gre gpa
0 1 0 1 0 380 3.61
1 1 0 1 0 660 3.67
2 1 0 0 0 800 4.00
3 1 0 0 1 640 3.19
4 1 0 0 1 520 2.93
model = LogisticRegression(fit_intercept = False, C = 1)
mdl = model.fit(X, y)
model.coef_
> array([[-1.35417783, -0.71628751, -1.26038726, -1.49762706, 0.00169198,
0.13992661]])
# corresponding to predictors [Intercept, rank_2, rank_3, rank_4, gre, gpa]
> # R glmnet
> df = fread("https://stats.idre.ucla.edu/stat/data/binary.csv")
> X = as.matrix(model.matrix(admit~gre+gpa+as.factor(rank), data=df))[,2:6]
> y = df[, admit]
> mylogit <- glmnet(X, y, family = "binomial", alpha = 0)
> coef(mylogit, s = 0.0025)
6 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -3.984226893
gre 0.002216795
gpa 0.772048342
as.factor(rank)2 -0.530731081
as.factor(rank)3 -1.164306231
as.factor(rank)4 -1.354160642
El R
resultado está de alguna manera cerca de la regresión logística sin regularización, como se puede ver aquí . ¿Me estoy perdiendo algo o estoy haciendo algo obviamente mal?
Actualización: también intenté usar el LiblineaR
paquete R
para llevar a cabo el mismo proceso, pero obtuve otro conjunto diferente de estimaciones ( liblinear
también es el solucionador sklearn
):
> fit = LiblineaR(X, y, type = 0, cost = 1)
> print(fit)
$TypeDetail
[1] "L2-regularized logistic regression primal (L2R_LR)"
$Type
[1] 0
$W
gre gpa as.factor(rank)2 as.factor(rank)3 as.factor(rank)4 Bias
[1,] 0.00113215 7.321421e-06 5.354841e-07 1.353818e-06 9.59564e-07 2.395513e-06
Actualización 2: desactivar la estandarización en glmnet
dado:
> mylogit <- glmnet(X, y, family = "binomial", alpha = 0, standardize = F)
> coef(mylogit, s = 0.0025)
6 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -2.8180677693
gre 0.0034434192
gpa 0.0001882333
as.factor(rank)2 0.0001268816
as.factor(rank)3 -0.0002259491
as.factor(rank)4 -0.0002028832
Respuestas:
la regresión logística de sklearn no estandariza las entradas por defecto, lo que cambia el significado del término de regularización ; probablemente glmnet lo hace.L2
Especialmente porque su
gre
término está en una escala tan grande como las otras variables, esto cambiará los costos relativos de usar las diferentes variables para los pesos.Tenga en cuenta también que al incluir un término de intercepción explícito en las características, está regularizando la intercepción del modelo. Esto generalmente no se hace, ya que significa que su modelo ya no es covariante para cambiar todas las etiquetas por una constante.
fuente
glmnet
permite desactivar la estandarización de las entradas, pero los coeficientes estimados son aún más diferentes, ver arriba. Además, incluí explícitamente el término de intercepciónsklearn
porqueglmnet
incluye uno automáticamente, por lo que esto es para asegurarse de que la entrada a ambos modelos sea la misma.X
y pasefit_intercept=True
(el valor predeterminado) aLogisticRegression
. Sin embargo, probablemente también esté sucediendo algo más.[-1.873, -0.0606, -1.175, -1.378, 0.00182, 0.2435]
porsklearn
y[-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]
paraglmnet
en orden de[Intercept, rank_2, rank_3, rank_4, gre, gpa]
. Mi preocupación es que difieren tanto en magnitud como en el impacto positivo / negativo de la probabilidad, por lo que sin saber por qué difieren, es difícil elegir uno para interpretar. Y si por casualidad hay un error en una de las implementaciones, es particularmente importante que sepa en cuál confiar.La respuesta de Dougal es correcta, usted regulariza la intersección
sklearn
pero no en R. Asegúrese de usarlasolver='newton-cg'
ya que el solucionador predeterminado ('liblinear'
) siempre regulariza la intersección.cf https://github.com/scikit-learn/scikit-learn/issues/6595
fuente
solver='newton-cg'
realizado a partir de los resultadossklearn
ystatsmodels
consistente. Muchas gracias.También debe usar el
L1_wt=0
argumento junto conalpha
infit_regularized()
call.Este código en
statsmodels
:es equivalente al siguiente código de
sklearn
:¡Espero eso ayude!
fuente