Preguntas Frecuentes

Aquí tratamos de dar algunas respuestas a las preguntas que surgen regularmente en la lista de correo.

¿Cuál es el nombre del proyecto (mucha gente tiende a equivocarse)?

scikit-learn, pero no scikit o SciKit ni sci-kit learn. Tampoco scikits.learn o scikits-learn, que se utilizaban anteriormente.

¿Cómo pronuncias el nombre del proyecto?

sy-kit learn. ¡sci es por ciencia!

¿Por qué scikit?

Hay múltiples scikits, las cuales son cajas de herramientas científicas construidas alrededor de SciPy. Puedes encontrar una lista en https://scikits.appspot.com/scikits. Aparte de la scikit-learn, otra popular es scikit-image.

¿Cómo puedo contribuir a scikit-learn?

Ver Contribuyendo. Antes de querer añadir un nuevo algoritmo, que suele ser un gran y largo cometido, es recomendable comenzar con incidencias conocidas. Por favor, no te pongas en contacto con los colaboradores de scikit-learn directamente para contribuir a scikit-learn.

¿Cuál es la mejor manera de obtener ayuda en el uso de scikit-learn?

Para preguntas generales de aprendizaje automático, por favor usa Cross Validated con la etiqueta [machine-learning]`.

Para preguntas de uso de scikit-learn, por favor usa Stack Overflow con las etiquetas [scikit-learn] y [python]. Puedes usar alternativamente la lista de correo.

Por favor, asegúrate de incluir un fragmento mínimo de código de reproducción (idealmente menos de 10 líneas) que resalte su problema en un conjunto de datos de prueba (por ejemplo de sklearn. atasets o generado aleatoriamente con funciones de numpy.random con una semilla aleatoria fija). Por favor, elimine cualquier línea de código que no sea necesaria para reproducir su problema.

El problema debería ser reproducible copiando el fragmento de código en un terminal de Python con scikit-learn instalado. No olvides incluir las declaraciones de importación.

Puedes encontrar más orientación para escribir un buen fragmento de código de reproducción en:

https://stackoverflow.com/help/mcve

Si tu problema plantea una excepción que no entiendes (incluso después de buscarlo en google), por favor asegúrate de incluir el rastreo completo que se obtiene al ejecutar el script de reproducción.

Para informes de errores o solicitudes de características, utiliza el gestor de incidencias en GitHub.

También hay un canal de scikit-learn Gitter donde se pueden encontrar algunos usuarios y desarrolladores.

Por favor, no envíes un correo electrónico a ningún autor directamente para pedir asistencia, reportar errores o cualquier otra incidencia relacionada con scikit-learn.

¿Cómo debo guardar, exportar o desplegar estimadores para producción?

Ver Persistencia del modelo.

¿Cómo puedo crear un objeto de tipo bunch?

A veces se utilizan objetos de tipo bunch como salida para funciones y métodos. Extienden diccionarios habilitando que los valores sean accedidos por clave, bunch["value_key"], o por un atributo, bunch.value_key.

No deben ser usados como entrada; por lo tanto casi nunca necesitas crear un objeto Bunch, a menos que estés extendiendo la API de scikit-learn.

¿Cómo puedo cargar mis propios conjuntos de datos en un formato utilizable por scikit-learn?

En general, scikit-learn funciona con cualquier dato numérico almacenado como arreglos de numpy o matrices dispersas de scipy. Otros tipos convertibles a arreglos numéricos como DataFrame de pandas también son aceptables.

Para más información sobre cómo cargar tus archivos de datos en estas estructuras de datos utilizables, consulta cargando conjuntos de datos externos.

¿Cuáles son los criterios de inclusión de nuevos algoritmos?

Sólo consideramos algoritmos bien establecidos para la inclusión. Una regla general es al menos 3 años desde la publicación, más de 200 citas y un uso amplio y útil. Una técnica que proporciona una mejora clara (por ejemplo, una estructura de datos mejorada o una técnica de aproximación más eficiente) sobre un método ampliamente utilizado también se considerará para su inclusión.

De los algoritmos o técnicas que cumplen con los criterios anteriores, sólo aquellos que se ajustan bien dentro de la API actual de scikit-learn, que es una interfaz fit, predic/transform y normalmente teniendo una entrada/salida que es un arreglo de numpy o una matriz dispersa, son aceptados.

El colaborador debe apoyar la importancia de la adición propuesta con documentos de investigación y/o implementaciones en otros paquetes similares, demostrar su utilidad a través de casos de uso/aplicaciones comunes y mejoras de rendimiento corroborado, si existen, con pruebas y/o gráficos de rendimiento. Se espera que el algoritmo propuesto supere los métodos que ya están implementados en scikit-learn al menos en algunas áreas.

La inclusión de un nuevo algoritmo acelerando un modelo existente es más fácil si:

  • no introduce nuevos hiper-parámetros (ya que hace que la biblioteca este más preparada en el futuro),

  • es fácil documentar claramente cuando la contribución mejora la velocidad y cuando no lo hace, por ejemplo «cuando n_características >> n_muestras»,

  • las pruebas de rendimiento muestran claramente una aceleración.

Además, ten en cuenta que tu implementación no tiene por qué estar en scikit-learn para ser usada junto con herramientas de scikit-learn. Puedes implementar tu algoritmo favorito de una manera compatible con scikit-learn, cargarlo a GitHub y hacernoslo saber. Estaremos encantados de listarlo en Proyectos Relacionados. Si ya tienes un paquete en GitHub siguiendo la API de scikit-learn, también podrías estar interesado en ver scikit-learn-contrib.

¿Por qué son tan selectivos sobre qué algoritmos incluir en scikit-learn?

El código viene con un costo de mantenimiento, y necesitamos equilibrar la cantidad de código que tenemos con el tamaño del equipo (y añadir a esto el hecho de que la complejidad no es lineal con el número de características). El paquete se basa en desarrolladores principales que utilizan su tiempo libre para corregir errores, mantener el código y revisar contribuciones. Cualquier algoritmo que se agregue necesita atención futura por parte de los desarrolladores, en cuyo momento el autor original podría haber perdido mucho interés. Ver también ¿Cuáles son los criterios de inclusión de nuevos algoritmos?. Para obtener una buena lectura sobre asuntos de mantenimiento a largo plazo en software de código abierto, consulte el Resumen Ejecutivo de Roads and Bridges

¿Por qué eliminaron HMMs de scikit-learn?

Ver ¿Añadirán modelos gráficos o predicción de secuencias a scikit-learn?.

¿Añadirán modelos gráficos o predicción de secuencias a scikit-learn?

No en el futuro previsible. scikit-learn trata de proporcionar una API unificada para las tareas básicas en el aprendizaje automático, con pipelines y meta-algoritmos como la búsqueda en cuadrícula para vincular todo. Los conceptos requeridos, las APIs, los algoritmos y la experiencia requerida para el aprendizaje estructurado son diferentes de lo que ofrece scikit-learn. Si empezáramos a hacer un aprendizaje estructurado arbitrario, tendríamos que rediseñar todo el paquete y el proyecto probablemente se derrumbaría por su propio peso.

Hay dos proyectos con la API similar al de scikit-learn que hacen predicción estructurada:

  • pystruct maneja el aprendizaje estructurado general (se enfoca en los SSVMs en estructuras de grafos arbitrarios con inferencia aproximada; define la noción de muestra como una instancia de la estructura de grafo)

  • seqlearn maneja sólo secuencias (se enfoca en la inferencia exacta; tiene HMMs, pero sobre todo en aras de la integridad; trata un vector de característica como una muestra y utiliza una codificación offset para las dependencias entre vectores de características)

¿Añadirán soporte para GPU?

No, o al menos no en un futuro cercano. La razón principal es que el soporte de GPU introducirá muchas dependencias de software e introducirá incidencias específicas de la plataforma. scikit-learn está diseñado para ser fácil de instalar en una amplia variedad de plataformas. Fuera de redes neuronales, los GPUs no juegan un papel importante en el aprendizaje automático de hoy, y muchas más ganancias en velocidad pueden lograrse a menudo mediante una cuidadosa selección de algoritmos.

¿Soportan PyPy?

En caso de que no lo sepas, PyPy es una implementación alternativa de Python con un compilador integrado just-in-time. Se ha añadido soporte experimental para PyPy3-v5.10+, que requiere Numpy 1.14.0+, y scipy 1.1.0+.

¿Cómo se tratan los datos de cadenas (o árboles, gráficos…)?

los estimadores de scikit-learn asumen que les alimentarán vectores de características de valor real. Esta suposición está codificada en casi toda la biblioteca. Sin embargo, puede alimentar entradas no numéricas a los estimadores de varias maneras.

Si tienes documentos de texto, puedes utilizar las características de frecuencia del término; consulta Extracción de característica de texto para los vectorizadores de texto incorporados. Para extraer más características generales de cualquier tipo de datos, consulta Cargando características desde diccionarios y Hashing de características.

Otro caso común es cuando se tienen datos no numéricos y una métrica de distancia (o similitud) personalizada en estos datos. Los ejemplos incluyen cadenas con distancia de edición (también conocida como distancia Levenshtein; por ejemplo, secuencias de ADN o ARN). Estas pueden ser codificadas como números, pero hacerlo es doloroso y propenso a errores. Trabajar con métricas de distancia en datos arbitrarios puede hacerse de dos maneras.

En primer lugar, muchos estimadores toman matrices de distancia/similitud precalculadas, por lo que si el conjunto de datos no es demasiado grande, se pueden calcular las distancias para todos los pares de entradas. Si el conjunto de datos es grande, puedes utilizar vectores de características con una sola «característica», que es un índice en una estructura de datos separada, y suministrar una función métrica personalizada que busque los datos reales en esta estructura de datos. Por ejemplo, para utilizar DBSCAN con distancias Levenshtein:

>>> from leven import levenshtein       
>>> import numpy as np
>>> from sklearn.cluster import dbscan
>>> data = ["ACCTCCTAGAAG", "ACCTACTAGAAGTT", "GAATATTAGGCCGA"]
>>> def lev_metric(x, y):
...     i, j = int(x[0]), int(y[0])     # extract indices
...     return levenshtein(data[i], data[j])
...
>>> X = np.arange(len(data)).reshape(-1, 1)
>>> X
array([[0],
       [1],
       [2]])
>>> # We need to specify algoritum='brute' as the default assumes
>>> # a continuous feature space.
>>> dbscan(X, metric=lev_metric, eps=5, min_samples=2, algorithm='brute')
... 
([0, 1], array([ 0,  0, -1]))

(Esto utiliza el paquete de distancia de edición de terceros leven.)

Se pueden utilizar trucos similares, con cierto cuidado, para los núcleos de árboles, gráficos, etc.

¿Por qué a veces se produce un fallo o congelación con n_jobs > 1 en OSX o Linux?

Varias herramientas de scikit-learn como GridSearchCV y cross_val_score se basan internamente en el módulo multiprocessing de Python para paralelizar la ejecución en varios procesos de Python pasando n_jobs > 1 como argumento.

El problema es que el multiprocesamiento de Python hace una llamada de sistema con el método fork sin seguirla con una llamada de sistema exec por razones de rendimiento. Muchas bibliotecas como (algunas de sus versiones) Accelerate / vecLib bajo OSX, (algunas de sus versiones) MKL, el OpenMP runtime de GCC, Cuda de nvidia (y probablemente muchos otros), gestionan su propio grupo de subprocesos internos. Tras una llamada a fork, el estado del grupo de subprocesos en el proceso hijo está corrupto: el grupo de subprocesos cree que tiene muchos hilos mientras que sólo el estado principal del subproceso ha sido bifurcado. Es posible cambiar las bibliotecas para hacerlas detectar cuando ocurre un fork y reinicializar el grupo de subprocesos en ese caso: lo hicimos para OpenBLAS (se fusionó en main desde 0.2.10) y hemos contribuido con un patch a OpenMP runtime de GCC (no revisado aún).

Pero al final el verdadero responsable es el multiprocessing de Python, que hace fork sin exec para reducir la sobrecarga de iniciar y usar nuevos procesos Python para computación paralela. Desafortunadamente esto es una violación del estándar POSIX y por lo tanto algunos editores de software como Apple se niegan a considerar la falta de seguridad de bifurcación en Accelerate / vecLib como un error.

En Python 3.4 + ahora es posible configurar multiprocessing para usar los métodos de inicio “forkserver” o “spawn” (en lugar de “fork” por defecto) para administrar los grupos de subprocesos. Para solucionar esta incedencia al usar scikit-learn, puede establecer la variable de entorno JOBLIB_START_METHOD a “forkserver”. Sin embargo, el usuario debe tener en cuenta que el uso del método “forkserver” impide que joblib.Parallel llame a la función definida interactivamente en una sesión de terminal.

Si tienes código personalizado que utiliza multiprocessing directamente en lugar de usarlo a través de joblib puedes activar globalmente el modo “forkserver” para tu programa: Inserta las siguientes instrucciones en tu script principal:

import multiprocessing

# other imports, custom code, load data, define model...

if __name__ == '__main__':
    multiprocessing.set_start_method('forkserver')

    # call scikit-learn utils with n_jobs > 1 here

Puede encontrar más información sobre los nuevos métodos de inicio en el documentación multiprocesamiento.

¿Por qué mi trabajo utiliza más núcleos que los especificados con n_jobs?

Esto es porque n_jobs sólo controla el número de trabajos para rutinas que son paralelizadas con joblib, pero el código paralelo puede provenir de otras fuentes:

  • algunas rutinas pueden ser paralelizadas con OpenMP (para código escrito en C o Cython).

  • scikit-learn depende mucho de numpy, que a su vez puede depender de bibliotecas numéricas como MKL, OpenBLAS o BLIS, que pueden proporcionar implementaciones paralelas.

Para más detalles, por favor consulta nuestras Notas de paralelismo.

¿Por qué no hay soporte para el aprendizaje profundo o de refuerzo / Habrá soporte para el aprendizaje profundo o de refuerzo en scikit-learn?

Tanto el aprendizaje profundo como el aprendizaje por refuerzo requieren un rico vocabulario para definir una arquitectura, y el aprendizaje profundo requiere además GPUs para una computación eficiente. Sin embargo, ninguno de los dos encaja en las restricciones de diseño de scikit-learn; como resultado, el aprendizaje profundo y el aprendizaje por refuerzo están actualmente fuera del alcance de lo que scikit-learn pretende lograr.

Puedes encontrar más información sobre la adición de soporte para la GPU en ¿Agregarán soporte para la GPU?.

Ten en cuenta que scikit-learn actualmente implementa un simple perceptrón multicapa en sklearn.neural_network. Sólo aceptaremos correcciones de errores para este módulo. Si deseas implementar modelos de aprendizaje profundo más complejos, por favor, diríjste a marcos de aprendizaje profundo populares como tensorflow, keras y pytorch.

¿Por qué mi pull request no recibe ninguna atención?

El proceso de revisión de scikit-learn toma una cantidad significativa de tiempo y los contribuyentes no deben verse desalentados por la falta de actividad o revisión de su solicitud de pull. Nos preocupa mucho hacer las cosas bien en primer intento, ya que el mantenimiento y el cambio posterior tiene un alto coste. Rara vez liberamos cualquier código «experimental», por lo que todas nuestras contribuciones estarán sujetas a un alto uso inmediatamente y deben ser de la más alta calidad posible inicialmente.

Además de eso, scikit-learn está limitado en su ancho de banda de revisión; muchos de los revisores y desarrolladores principales están trabajando en scikit-learn por cuanta propia. Si una revisión de su pull request llega con lentitud, es probable porque los revisores están ocupados. Pedimos tu comprensión y te solicitamos que no cierres su pull request o suspendas tu trabajo únicamente por esta razón.

¿Cómo establezco un random_state para una ejecución completa?

Por favor, consulta Control de aleatoriedad.

¿Por qué las variables categóricas necesitan preprocesamiento en scikit-learn, en comparación con otras herramientas?

La mayor parte de scikit-learn asume que los datos están en arreglos de NumPy o matrices dispersas de SciPy de un solo dtype numérico. Estos no representan explícitamente variables categóricas en este momento. Por lo que, a diferencia de los data.frames de R o pandas.DataFrame , se requiere la conversión explícita de características categóricas a valores numéricos, como se explica en Codificación de características categóricas. Ver también Transformador de columna con tipos mixtos para un ejemplo de trabajo con datos heterogéneos (por ejemplo, categóricos y numéricos).

¿Por qué Scikit-learn no funciona directamente con, por ejemplo, pandas.DataFrame?

Los objetos de datos homogéneos de NumPy y SciPy que se esperan actualmente son los más eficientes para procesar la mayoría de las operaciones. También se necesitaría un gran trabajo para soportar los tipos categóricos de Pandas. Por tanto, restringir la entrada a tipos homogéneos reduce el coste de mantenimiento y fomenta el uso de estructuras de datos eficientes.

¿Piensan implementar la transformación para el objetivo y en un pipeline?

Actualmente transformar sólo funciona para las características X en un pipeline. Hay una larga discusión sobre la imposibilidad de transformar y en un pipeline. Sigue en github el tema #4143. Mientras tanto revisa TransformedTargetRegressor, pipegraph, imbalanced-learn. Observa que Scikit-learn ha resuelto el caso en el que y tiene una transformación invertible aplicada antes del entrenamiento e invertida después de la predicción. Scikit-learn pretende resolver los casos de uso en los que y debe transformarse en el momento del entrenamiento y no en el momento de la prueba, para el remuestreo y usos similares, como en imbalanced-learn. En general, estos casos de uso pueden ser resueltos con un estimador meta personalizado en lugar de un Pipeline