Estoy tratando de duplicar los resultados de sklearnla biblioteca de regresión logística usando el glmnetpaquete 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 sklearnfunció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 admitbase a gre, gpay 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 Rresultado 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 LiblineaRpaquete Rpara llevar a cabo el mismo proceso, pero obtuve otro conjunto diferente de estimaciones ( liblineartambié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 glmnetdado:
> 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
greté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
glmnetpermite 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ónsklearnporqueglmnetincluye uno automáticamente, por lo que esto es para asegurarse de que la entrada a ambos modelos sea la misma.Xy 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]porsklearny[-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]paraglmneten 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
sklearnpero 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 resultadossklearnystatsmodelsconsistente. Muchas gracias.También debe usar el
L1_wt=0argumento junto conalphainfit_regularized()call.Este código en
statsmodels:es equivalente al siguiente código de
sklearn:¡Espero eso ayude!
fuente