Estoy tratando de entender por qué el resultado de la regresión logística de estas dos bibliotecas da resultados diferentes.
Estoy usando el conjunto de datos del tutorial idre de UCLA , prediciendo en admit
base a gre
, gpa
y rank
. rank
se trata como variable categórica, por lo que primero se convierte en variable ficticia con rank_1
descarte. También se agrega una columna de intercepción.
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
# Output from scikit-learn
model = LogisticRegression(fit_intercept = False)
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]
# Output from statsmodels
logit = sm.Logit(y, X)
logit.fit().params
> Optimization terminated successfully.
Current function value: 0.573147
Iterations 6
Intercept -3.989979
C(rank)[T.2] -0.675443
C(rank)[T.3] -1.340204
C(rank)[T.4] -1.551464
gre 0.002264
gpa 0.804038
dtype: float64
La salida de statsmodels
es la misma que se muestra en el sitio web idre, pero no estoy seguro de por qué scikit-learn produce un conjunto diferente de coeficientes. ¿Minimiza alguna función de pérdida diferente? ¿Existe alguna documentación que indique la implementación?
fuente
glmnet
paquete en R, pero no pude obtener el mismo coeficiente. glmnet tiene una función de coste ligeramente diferente en comparación con sklearn , pero incluso si fijoalpha=0
englmnet
(es decir, sólo utilice L2-penal) y el conjunto1/(N*lambda)=C
, todavía no consigo el mismo resultado?glmnet
entrelambda
y establezco la nueva constante en la fuente del log-verosimilitud, que es1/(N*lambda)
igual a eso ensklearn
, las dos funciones de costo se vuelven idénticas, ¿o me estoy perdiendo algo?penalty='none'
.Otra diferencia es que ha configurado fit_intercept = False, que efectivamente es un modelo diferente. Puede ver que Statsmodel incluye la intercepción. No tener una intercepción seguramente cambia los pesos esperados en las características. Pruebe lo siguiente y vea cómo se compara:
model = LogisticRegression(C=1e9)
fuente