Artículo original escrito por Davis David
Artículo original Machine Learning in Python – The Top New Scikit-Learn 0.24 Features You Should Know
Traducido y adaptado por andres-torres

Scikit-learn es uno de los open-source y bibliotecas de aprendizaje automático más populares en Python.

La biblioteca scikit-learn contiene muchas herramientas eficientes para aprendizaje automático y modelado estadístico, incluyendo clasificación, regresión, agrupación, y reducción de dimensionalidad.

Varios científicos de datos, ingenieros de aprendizaje automático e investigadores dependen de esta biblioteca para sus proyectos. Personalmente, me encanta usar scikit-learn porque ofrece muchísima flexibilidad, siendo además fácil de comprender debido a una documentación que ofrece una multitud de ejemplos.

En este artículo, estaré feliz de compartir contigo las cinco nuevas características en scikit-learn 0.24.

Instalemos la última versión de la biblioteca Scikit-Learn.

Primero que nada, asegúrate de instalar la última versión (con pip):

pip install --upgrade scikit-learn

Si estás usando Anaconda, emplea el siguiente comando:

conda install -c conda-forge scikit-learn

Nota:Esta versión soporta las versiones de Python 3.6 hasta 3.9.

Ahora, veamos las nuevas características.

Error Porcentual Absoluto Medio.

Esta nueva versión de scikit-learn introduce una nueva métrica de evaluación para un problema de regresión llamado Error Porcentual Absoluto Medio, conocido en inglés como "Mean Absolute Percentage Error" (MAPE). Anteriormente teníamos que calcularlo así.

np.mean(np.abs((y_test — preds)/y_test))

Ahora simplemente llamas a la función mean_absolute_percentage_error   a partir del módulo de sklearn.metrics.

Con esto puedes evaluar que tan bien funciona tu modelo.

Por ejemplo:

from sklearn.metrics import mean_absolute_percentage_error
y_true = [3, -0.5, 2, 7]
y_pred = [2.5, 0.0, 2, 8]

print(mean_absolute_percentage_error(y_true, y_pred))

0.3273809523809524

Nota: Recuerda que la función en sí, no expresa su resultado cómo un porcentaje en el rango [0, 100]. En su lugar, el resultado se representa en un rango de  [0, 1].  El mejor valor posible es 0.0.

OneHotEncoder resuelve la insuficiencia de datos.

OneHot Encoder , a grosso modo consiste en reemplazar una variable categórica por una variable binaria (0,1) mediante una transformación. Este puede resolver la falta de datos en caso de presentarse en una hoja de datos, puesto que trata cualquier valor faltante cómo una categoría. Veamos un ejemplo para entender más a detalle de qué se trata.

Primero importa pandas, numpy y scikit-learn:

import pandas as pd 
import numpy as np
from sklearn.preprocessing import OneHotEncoder

Crea un simple marco de datos con variables categóricas que posean valores faltantes:

# intialise data of lists.
datos = {'nivel_educacion':['primaria', 'segundaria', 'pregrado', np.nan,'master',np.nan]}
  
# Create DataFrame
df = pd.DataFrame(datos)
  
# imprime el resultado.
print(df)
image-26
Resultado

Cómo puedes ver, tenemos dos valores nulos en nuestra columna de educación.

A continuación creamos la instancia de OneHotEncoder:

ohe = OneHotEncoder()

Luego ajustamos y transformamos nuestros datos:

ohe.fit_transform(df).toarray()
zVaxL0LohRUpfDQhznRQ9z3y5tj1-pn3531g0

Nuestra columna de educación ha sido transformada y todos los valores nulos han sido incluidos en una nueva categoría (Observa la última columna en el arreglo).

Nuevo método para selección de variables.

SequentialFeatureSelector es un nuevo método de selección de caracteristicas en scikit-learn. Existen dos formas de selección de variables, las definiciones técnicas son las siguientes: forward selection y backward selection.

Forward Selection (selección hacia adelante)

En palabras simples, el método de Forward Selection interactivamente encuentra la nueva característica y luego la añade al conjunto de características previamente seleccionadas.

Es decir, que comenzamos con cero características y luego encontramos una característica que maximiza la puntuación de validación cruzada de un estimador. La característica seleccionada es añadida al conjunto de variables y el proceso es repetido hasta lograr el número deseado de variables seleccionadas.

Backward Selection (selección hacia atrás)

Esta segunda selección sigue la misma idea que la anterior, pero en una dirección diferente. Aquí empieza con todas las características y luego remueve una característica del conjunto hasta que alcanzar el número deseado de características seleccionadas.

Ejemplos:

Importa los paquetes más importantes:

from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris

Utiliza un conjunto de datos  que forma parte de los ejemplos que proporciona scikit-learn. Define los nombres de sus variables:

X, y = load_iris(return_X_y=True, as_frame=True)
feature_names = X.columns

Crea la instancia de un estimador (En este caso por K-Nearest Neighbors):

knn = KNeighborsClassifier(n_neighbors=3)

Crea la instancia responsable de seleccionar las variables (SequentialFeatureSelector), fijando el número de variables a seleccionar igual a 2, y la dirección “backward”:

sfs = SequentialFeatureSelector(knn, n_features_to_select=2,direction='backward')

Finalmente ajusta las variables seleccionadas:

sfs.fit(X,y)

Para mostrar las variables necesitaremos:

print("Features selected by backward sequential selection: "f{feature_names[sfs.get_support()].tolist()}")

Nuevos métodos para ajustar Hiperparámetros.

Cuando se trata de ajustar Hiperparámetros, GridSearchCV y RandomizedSearchCv en Scikit-learn han sido la primera elección en Data Science.

Sin embargo, en esta nueva versión, tenemos dos nuevas clases para ajustar Hiperparámetros; HalvingGridSearchCV y HalvingRandomSearchCV.

HalvingGridSearchCV y HalvingRandomSearchCV usan un nuevo algorithmo llamado successive halving, para encontrar los hiperparámetros óptimos.  

¿Cómo funciona el algorithmo successive halving?

En la primera iteración, se entrena una combinación de hiperparámetros en un subconjunto de observaciones, (datos de entrenamiento).

Luego en la próxima iteración, se selecciona solamente la combinación de hiperparámetros que tuvieron un buen desempeño en la primera iteración. De este modelo serán entrenados nuevamente solo que en número de observación más extenso.

Por último, se repite este proceso de selección en cada iteración hasta que selecciona la mejor combinación de hiperparámetros en la última iteración.

Nota: Todas estas clases de Scikit-learn son todavía experimentales:

Ejemplo:

Importamos los paquetes importantes:

from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.experimental import enable_halving_search_cv  
from sklearn.model_selection import HalvingRandomSearchCV
from scipy.stats import randint

Ya que estas clases son todavía experimentales, para usarlas, importamos explícitamente, es decir, usamos import enable_halving_search_cv.

Creamos un conjunto de datos para clasificación usando el método make_classification:

X, y = make_classification(n_samples=1000)

Creamos la instancia del estimador. Usando un clasificador basado en bosques aleatorios, es decir, Random Forest Classifier:

clf = RandomForestClassifier(n_estimators=20)

Creamos la distribución del parámetro para el ajuste:

param_dist = {"max_depth": [3, None],
              "max_features": randint(1, 11),
              "min_samples_split": randint(2, 11),
              "bootstrap": [True, False],
              "criterion": ["gini", "entropy"]}

Definiendo con rsh la instancia de clase HalvingGridSearchCV con nuestro RandomForestClassifier(estimator=clf) como estimador, obtendremos la lista de distribuciones de nuestros parámetros:

rsh = HalvingRandomSearchCV(
    estimator=clf,
    param_distributions=param_dist,
    cv = 5,
    factor=2,
    min_resources = 20)

Hay dos parámetros muy importantes en HalvingRandomSearchCV a tomar en cuenta.

  1. factor — Determina la proporción de la combinación de hiperparámetros que son seleccionados para cada iteración subsecuente. Por ejemplo, factor=3 significa que solo un tercio de los candidatos son seleccionados para la nueva iteración.
  2. min_resources  es el total de recursos (número de observaciones) asignadas en la primera iteración para cada combinación de hiperparámetros.

Finalmente, podemos ajustar los parámetros del objeto de búsqueda (rsh) que hemos creado en nuestro conjunto de datos.

rsh.fit(X,y)

Podemos ver los resultados luego de haber entrenado nuestros datos:

  1. El número de iteraciones
print(rsh.n_iterations_ )

que es 6.

2. El número de parámetros candidatos a ser evaluados en cada iteración.

print(rsh.n_candidates_ )

Los cuales son [50, 25, 13, 7, 4, 2].

3. El número de recursos a utilizados en cada iteración:

print(rsh.n_resources_)

que es [20, 40, 80, 160, 320, 640].

4. Los parámetros que proporcionan los mejores resultados:

print(rsh.best_params_)

Resultando:

{‘bootstrap’: False,
‘criterion’: ‘entropy’,
‘max_depth’: None,
‘max_features’: 5,
‘min_samples_split’: 2}

Nuevo meta-estimador de entrenamiento automático para aprendizaje semi-supervisado.

Scikit-learn 0.24 ha introducido una nueva implementación de auto-entrenamiento para aprendizaje semi-supervisado llamado SelfTrainingClassifier. Puedes utilizar el clasificador de autoaprendizaje con cualquier clasificador supervisado que retorne estimaciones de probabilidad para cada clase.

Esto significa que cualquier clasificador supervisado puede funcionar como un clasificador semi-supervisado, con el propósito de facilitar el aprendizaje de observaciones de datos no etiquetados, (datos no etiquetados).

Nota: Los valores no etiquetados en la columna de destino devén tener un valor de -1.

Entendamos más cómo funciona.

Una vez importados los elementos importantes, definimos una semilla aleatoria con Numpy,  luego procedemos a llamar a nuestro conjunto de datos anterior.  Finalmente, empleamos nuestro clasificador semi-supervisado con los valores no etiquetados (datos no etiquetados).

import numpy as np
from sklearn import datasets
from sklearn.semi_supervised import SelfTrainingClassifier
from sklearn.svm import SVC
rng = np.random.RandomState(42)
iris = datasets.load_iris()
random_unlabeled_points = rng.rand(iris.target.shape[0]) < 0.3
iris.target[random_unlabeled_points] = -1

Cómo puedes ver, los valores no etiquetados en el arreglo se expresan con valor de -1.

zVaxL0LohRUpfDQhznRQ9z3y5tj1-jcah31ok

Creando una instancia del estimador supervisado:

svc = SVC(probability=True, gamma="auto")

Por otra parte, creando una instancia del nuevo SelfTrainingClassifier, añadiendo svc como nuestro estimador:

self_training_model = SelfTrainingClassifier(base_estimator=svc)

Finalmente, ajustamos nuestro modelo y sus correspondientes valores no etiquetados:

self_training_model.fit(iris.data, iris.target)

Resultado:

SelfTrainingClassifier(base_estimator=SVC(gamma=’auto’, probability=True))

Reflexiones finales acerca de Scikit-Learn 0.24

Cómo mencioné, scikit-learn permanece cómo uno de los  de los open-source y bibliotecas de aprendizaje automático más populares en Python. Posee todas las herramientas necesarias para construir un proyecto de aprendizaje automático de extremo a extremo.

También puedes implementar las nuevas funciones presentadas en este artículo en tu propio proyecto de aprendizaje automático.

Felicitaciones ?? llegaste al final de este artículo. Espero que hayas aprendido algo nuevo que te ayude en tu proyecto de aprendizaje automático o ciencia de datos.

¡Feliz aprendizaje!