tfidftransformer sklearn one learning labelencoder hot fit_transform python encoding scikit-learn one-hot

python - sklearn - scikit-learn: una codificación en caliente de características categóricas de cadenas



sklearn learning curve (3)

He enfrentado este problema muchas veces y encontré una solución en este libro en su página 100:

Podemos aplicar ambas transformaciones (desde categorías de texto a categorías enteras, luego de categorías enteras a vectores únicos) en una sola toma usando la clase LabelBinarizer:

y el código de muestra está aquí:

from sklearn.preprocessing import LabelBinarizer encoder = LabelBinarizer() housing_cat_1hot = encoder.fit_transform(data) housing_cat_1hot

y como resultado: tenga en cuenta que esto devuelve una matriz NumPy densa por defecto. En su lugar, puede obtener una matriz dispersa pasando sparse_output = True al constructor LabelBinarizer.

Y puede encontrar más información sobre LabelBinarizer, aquí en la documentación oficial de sklearn

Estoy tratando de realizar una codificación en caliente de un conjunto de datos triviales.

data = [[''a'', ''dog'', ''red''] [''b'', ''cat'', ''green'']]

¿Cuál es la mejor manera de preprocesar estos datos con Scikit-Learn?

Al primer instinto, miraría hacia OneHotEncoder de Scikit -Learn. Pero el codificador en caliente no admite cadenas como características; solo discretiza enteros.

Entonces usaría un LabelEncoder , que codificaría las cadenas en enteros. Pero luego debe aplicar el codificador de etiquetas en cada una de las columnas y almacenar cada uno de estos codificadores de etiquetas (así como las columnas sobre las que se aplicaron). Y esto se siente extremadamente torpe.

Entonces, ¿cuál es la mejor manera de hacerlo en Scikit-Learn?

Por favor, no sugieras pandas.get_dummies . Eso es lo que generalmente uso hoy en día para codificaciones en caliente. Sin embargo, está limitado en el hecho de que no puede codificar su conjunto de entrenamiento / prueba por separado.


Muy buena pregunta.

Sin embargo, en cierto sentido, es un caso privado de algo que surge (al menos para mí) bastante a menudo: dadas sklearn etapas de sklearn aplicables a subconjuntos de la matriz X , me gustaría aplicar (posiblemente varias) dada la matriz completa . Aquí, por ejemplo, tiene una etapa que sabe ejecutar en una sola columna y desea aplicarla tres veces, una por columna.

Este es un caso clásico para usar el patrón de diseño compuesto .

Aquí hay un (esbozo de) una etapa reutilizable que acepta un diccionario mapeando un índice de columna en la transformación para aplicarlo:

class ColumnApplier(object): def __init__(self, column_stages): self._column_stages = column_stages def fit(self, X, y): for i, k in self._column_stages.items(): k.fit(X[:, i]) return self def transform(self, X): X = X.copy() for i, k in self._column_stages.items(): X[:, i] = k.transform(X[:, i]) return X

Ahora, para usarlo en este contexto, comenzando con

X = np.array([[''a'', ''dog'', ''red''], [''b'', ''cat'', ''green'']]) y = np.array([1, 2]) X

solo lo usaría para asignar cada índice de columna a la transformación que desea:

multi_encoder = / ColumnApplier(dict([(i, preprocessing.LabelEncoder()) for i in range(3)])) multi_encoder.fit(X, None).transform(X)

Una vez que desarrollas esa etapa (no puedo publicar la que uso), puedes usarla una y otra vez para varias configuraciones.


Para su información, esto va a estar en producción en sklearn muy pronto: consulte https://github.com/scikit-learn/scikit-learn/pull/9151

In [30]: cat = CategoricalEncoder() In [31]: X = np.array([[''a'', ''b'', ''a'', ''c''], [0, 1, 0, 1]], dtype=object).T In [32]: cat.fit_transform(X).toarray() Out[32]: array([[ 1., 0., 0., 1., 0.], [ 0., 1., 0., 0., 1.], [ 1., 0., 0., 1., 0.], [ 0., 0., 1., 0., 1.]])

Si instala la rama principal, debería poder hacerlo.

Otra forma de hacerlo es usar category_encoders.

Aquí hay un ejemplo:

%pip install category_encoders import category_encoders as ce le = ce.OneHotEncoder(return_df=False,impute_missing=False,handle_unknown="ignore") X = np.array([[''a'', ''dog'', ''red''], [''b'', ''cat'', ''green'']]) le.fit_transform(X) array([[1, 0, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1]])