Scikit-learn: Sugerencia: agregar soporte para regresión logística no penalizada

Creado en 30 abr. 2016  ·  34Comentarios  ·  Fuente: scikit-learn/scikit-learn

LinearRegression proporciona OLS no penalizados, y SGDClassifier , que admite loss="log" , también admite penalty="none" . Pero si desea una regresión logística simple y no penalizada, debe falsificarla configurando C en LogisticRegression en un número grande, o use Logit de statsmodels en lugar de.

Documentation Easy

Comentario más útil

¿Se pregunta por qué querría hacer una regresión logística sin regularización? Debido a que (1) a veces la muestra es lo suficientemente grande en proporción al número de características, la regularización no comprará nada y (2) a veces los coeficientes de mejor ajuste son de interés, en lugar de maximizar la precisión predictiva.

Todos 34 comentarios

tienes que fingirlo configurando C en LogisticRegression en un número grande

¿Cuál es el problema con ese enfoque?

Supuse que es inexacto y más lento que una implementación directa de regresión logística no penalizada. ¿Me equivoco?

Noto que establecer C demasiado alto, como se muestra a continuación, hará que LogisticRegression.fit cuelgue. Pero no sé si esto es un error o simplemente una propiedad inherente del algoritmo y su implementación en una computadora de 64 bits.

import numpy as np
from sklearn.linear_model import LogisticRegression

x = np.matrix([0, 0, 0, 0,  1, 1, 1, 1]).T
y =           [1, 0, 0, 0,  1, 1, 1, 0]

m = LogisticRegression(C = 1e200)
m.fit(x, y)
print m.intercept_, m.coef_

Noto que establecer C demasiado alto, como en el siguiente, hará que LogisticRegression.fit se cuelgue

Sí, esto es de esperar ya que el problema se vuelve mal planteado cuando C es grande. Los solucionadores iterativos son lentos con problemas mal planteados.

En su ejemplo, el algoritmo tarda una eternidad en alcanzar la tolerancia deseada. Necesita aumentar tol o hardcode max_iter .

@mblondel ¿hay alguna alternativa a los "solucionadores iterativos"?
No obtendrá exactamente la opción no regularizada, ¿verdad?

@Kodiólogo, ¿por qué quieres esto?

¿Se pregunta por qué querría hacer una regresión logística sin regularización? Debido a que (1) a veces la muestra es lo suficientemente grande en proporción al número de características, la regularización no comprará nada y (2) a veces los coeficientes de mejor ajuste son de interés, en lugar de maximizar la precisión predictiva.

Sí, esa fue mi pregunta.

(1) no es cierto. Siempre te comprará un solucionador más rápido.

(2) está más en el ámbito del análisis estadístico, que no es realmente el enfoque de scikit-learn. Supongo que podríamos agregar esto, pero no sé qué solucionador usaríamos. Como no estadístico, me pregunto de qué sirven los coeficientes que cambian con un poco de regularización.

No puedo decir mucho sobre (1) ya que la computación no es mi fuerte. Para (2), soy un analista de datos con experiencia en estadística. Sé que scikit-learn se centra en el aprendizaje automático tradicional, pero, en mi opinión, es el mejor paquete de Python para el análisis de datos en este momento, y creo que se beneficiará si no se limita demasiado _demasiado_. (También creo, siguiendo a Larry Wasserman y Andrew Gelman, que la estadística y el aprendizaje automático se beneficiarían mutuamente de entremezclarse más, pero supongo que esa es su propia lata de gusanos). Todos los coeficientes cambiarán con la regularización; eso es lo que hace la regularización.

No me opongo a agregar un solucionador sin regularización. ¿Podemos verificar qué sería bueno, o simplemente fianza y usar l-bfgs y verificar de antemano si está mal acondicionado?

Sí, todos los coeficientes cambian con la regularización. Honestamente, tengo curiosidad por saber qué quieres hacer con ellos después.

Oye,
¿Cuál es el estado de este tema? Me interesaría mucho una regresión logística no sancionada. De esta manera, los valores p significarán algo estadísticamente hablando. De lo contrario, tendré que seguir usando R 😢 para tales casos de uso ...
Gracias,
Alex

¿O modelos estatales?

¿Qué solucionadores sugiere implementar? ¿En qué se diferenciaría de los solucionadores que ya tenemos con C -> infty?

¿Qué solucionadores sugiere implementar? ¿En qué se diferenciaría de los solucionadores que ya tenemos con C -> infty?

Puede intentar buscar en R o modelos de estadísticas para obtener ideas. No estoy familiarizado con sus métodos, pero son razonablemente rápidos y no usan ninguna regularización.

Sí, statsmodels también hace el trabajo si usa el algoritmo QR para la inversión de la matriz. Mi caso de uso gira en torno a la interpretabilidad del modelo. Para el rendimiento, definitivamente usaría la regularización.

No creo que necesitemos agregar ningún nuevo solucionador ... La regresión logística no disfruta de una solución de forma cerrada, lo que significa que statsmodel debe usar un solucionador iterativo de algún tipo también (mi conjetura serían mínimos cuadrados repetidos iterativos, pero No lo he comprobado). Configurar C=np.inf (o equivalentemente alpha = 0 ) debería funcionar en principio con nuestros solucionadores actuales. Mi recomendación sería cambiar al solucionador L-BFGS o Newton-CG, ya que liblinear puede ser muy lento en esta configuración. Quizás podamos agregar una opción solver="auto" y cambiar automáticamente a una de estas cuando C=np.inf o equivalentemente penalty="none" ?

estamos cambiando el solucionador predeterminado a lbfgs en # 10001 fwiw

Para las personas que realmente quieren una regresión logística no regularizada (como yo). He tenido que conformarme con el uso de statsmodels y hacer una clase contenedora que imite la API de SKLearn.

¿Alguna actualización sobre esto? Este es un gran obstáculo para mi voluntad de recomendar scikit-learn a la gente. Tampoco es del todo obvio para las personas que provienen de otras bibliotecas que scikit-learn realiza la regularización de forma predeterminada y que no hay forma de deshabilitarlo.

Sugerencias de @shermstats ¿cómo mejorar la documentación al respecto? Estoy de acuerdo en que puede que no sea muy obvio.
¿L-bfgs permite C=np.inf ?

Puede especificar C=np.inf , aunque le dará el mismo resultado que C=large value . En el ejemplo que probé, dio un mejor ajuste que statsmodel y statsmodel no pudo converger con la mayoría de las otras semillas aleatorias:

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
import statsmodels.api as sm

X, y = make_classification(random_state=2)
lr = LogisticRegression(C=np.inf, solver='lbfgs').fit(X, y)


logit = sm.Logit(y, X)
res = logit.fit()
Optimization terminated successfully.
         Current function value: 0.167162
         Iterations 10
from sklearn.metrics import log_loss
log_loss(y, lr.predict_proba(X))
log_loss(y, res.predict(X))
0.16197793224715606
0.16716164149746823

Entonces, yo diría que deberíamos documentar que puede obtener un modelo no penalizado configurando C grande o np.inf.

Sugeriría agregar a la cadena de documentos y la guía del usuario
"El modelo LogisticRegregression está penalizado de forma predeterminada. Puede obtener un modelo no penalizado configurando C = np.inf y solver = 'lbfgs'."

dio un mejor ajuste que statsmodel y statsmodel no pudo converger con la mayoría de las otras semillas aleatorias

R's glm es más maduro y puede hacer una mejor comparación.

Sugeriría agregar a la cadena de documentos y la guía del usuario
"El modelo LogisticRegregression está penalizado de forma predeterminada. Puede obtener un modelo no penalizado configurando C = np.inf y solver = 'lbfgs'."

¿Por qué no agregar allow penalty = "none" a la SGDClassifier ?

@Kodiologist No me opongo a agregar penalty="none" pero no estoy seguro de cuál es el beneficio de agregar una opción redundante.
Y creo que agradeceríamos las comparaciones con glm. No estoy muy familiarizado con glm, por lo que probablemente no sea una buena persona para realizar la comparación. Sin embargo, estamos optimizando la pérdida de registros, por lo que realmente no debería haber diferencia. Tal vez implementen diferentes solucionadores, por lo que tener un punto de referencia sería bueno.

No me opongo a agregar penalty="none" pero no estoy seguro de cuál es el beneficio de agregar una opción redundante.

  1. Se vuelve más claro cómo obtener un modelo no penalizado.
  2. Se vuelve más claro para el lector qué está tratando de hacer el código que usa un modelo no penalizado.
  3. Permite a sklearn cambiar su implementación de modelos no regularizados en el futuro sin romper el código de las personas.

Si cree que aumenta la capacidad de descubrimiento, podemos agregarlo, y 3 es un punto válido (aunque en realidad no podemos cambiar eso sin depreciaciones probablemente, vea el cambio actual del solucionador).
¿Quieres enviar un PR?

No tengo los trajes redondos para eso; perdón.

@Kodiologist al menos me enseñaste un modismo que no conocía;)

Así que abierto para los contribuyentes: agregue penalty='none' como opción. También es posible que compruebe qué solucionadores admiten esto / son eficientes con esto (probablemente liblinear no lo sea) y limítese a esos solucionadores.

Sugeriría agregar a la cadena de documentos y la guía del usuario
"El modelo LogisticRegregression está penalizado de forma predeterminada. Puede obtener un modelo no penalizado configurando C = np.inf y solver = 'lbfgs'."

Esto me suena razonable. También sugeriría poner en negrita la primera oración porque es legítimamente tan sorprendente para las personas que provienen de otros entornos de aprendizaje automático o análisis de datos.

@shermstats Entonces @Kodiologist sugirió agregar penalty="none" para hacerlo más explícito, que sería solo un alias para C=np.inf . Para mí tiene sentido hacer esto más explícito de esta manera. ¿Tienes pensamientos sobre eso?
Entonces eso sería lo que está en la documentación. Y estoy de acuerdo en que audaz podría ser una buena idea.
Creo que para alguien con experiencia en ML esto es (¿tal vez?) Esperado, para alguien con experiencia en estadísticas, esto parece muy sorprendente.

¡Exactamente! Tengo experiencia en estadísticas y he trabajado con muchas personas de estadísticas que vienen de R o incluso con interfaces de apuntar y hacer clic, y este comportamiento nos sorprende mucho. Creo que, por ahora, penalty=None (no estoy seguro de "none" frente a None ) es una buena solución. En el futuro, deberíamos tener un solucionador separado que se llame automáticamente para la regresión logística no penalizada para evitar los problemas que describió @mblondel .

Lo siento, ¿a qué problema te refieres? Estamos cambiando a l-bfgs de forma predeterminada, y también podemos cambiar internamente el solucionador a l-bfgs automáticamente si alguien especifica penalty='none' (a menudo, None es un token especial que usamos para los parámetros obsoletos, pero nos hemos detenido Aún así, 'ninguno' sería más consistente con el resto de la biblioteca).
Necesitamos solver="auto" todos modos, por lo que cambiar el solucionador en función de la penalización no debería ser un problema.

Este problema , que se refiere a que el algoritmo iterativo se vuelve muy lento para C grandes. No soy un experto en análisis numérico, pero si l-bfgs evita que se ralentice, entonces parece la solución correcta. penalty='none' también parece la forma correcta de manejar esto.

@shermstats sí, con l-bfgs esto no parece ser un problema. Sin embargo, no he ejecutado evaluaciones comparativas extensas y no tendré tiempo para hacerlo. Si alguien quiere ejecutar evaluaciones comparativas, sería de gran ayuda.

Si se va a incluir penalización = 'ninguno', sugiero agregar a la guía del usuario la misma advertencia sobre X colineal que para OLS (en particular para características codificadas en caliente).

¿Fue útil esta página
0 / 5 - 0 calificaciones