sklearn onehotencoder one labelencoder hot for examples categorical scikit-learn feature-extraction categorical-data

scikit learn - labelencoder - Problema con OneHotEncoder para características categóricas



onehotencoder examples (6)

Quiero codificar 3 características categóricas de 10 características en mis conjuntos de datos. Uso el preprocessing de sklearn.preprocessing para hacerlo de la siguiente manera:

from sklearn import preprocessing cat_features = [''color'', ''director_name'', ''actor_2_name''] enc = preprocessing.OneHotEncoder(categorical_features=cat_features) enc.fit(dataset.values)

Sin embargo, no pude proceder ya que estoy recibiendo este error:

array = np.array(array, dtype=dtype, order=order, copy=copy) ValueError: could not convert string to float: PG

¡¡Me sorprende que se queje de la cadena porque se supone que la convierte !! ¿Me estoy perdiendo de algo?


@Medo,

Encontré el mismo comportamiento y lo encontré frustrante. Como han señalado otros, Scikit-Learn requiere que todos los datos sean numéricos antes de que incluso considere la selección de las columnas proporcionadas en el parámetro categorical_features .

Específicamente, la selección de la columna es manejada por el método _transform_selected() en /sklearn/preprocessing/data.py y la primera línea de ese método es

X = check_array(X, accept_sparse=''csc'', copy=copy, dtype=FLOAT_DTYPES) .

Esta comprobación falla si alguno de los datos en el marco de datos X proporcionado no se puede convertir con éxito en un flotador.

Estoy de acuerdo en que la documentación de sklearn.preprocessing.OneHotEncoder es muy engañosa en ese sentido.


De la documentación:

categorical_features : “all” or array of indices or mask Specify what features are treated as categorical. ‘all’ (default): All features are treated as categorical. array of indices: Array of categorical feature indices. mask: Array of length n_features and with dtype=bool.

los nombres de columna de los datos de pandas no funcionarán. Si sus características categóricas son los números de columna 0, 2 y 6 use:

from sklearn import preprocessing cat_features = [0, 2, 6] enc = preprocessing.OneHotEncoder(categorical_features=cat_features) enc.fit(dataset.values)

También se debe tener en cuenta que si estas características categóricas no están codificadas por etiquetas, debe usar LabelEncoder en estas características antes de usar OneHotEncoder


Hay una solución simple si, como yo, te sientes frustrado por esto. Simplemente use el codificador de categoría OneHotEncoder . Este es un paquete de Sklearn Contrib, por lo que se reproduce muy bien con la API scikit-learn.

Esto funciona como un reemplazo directo y hace la codificación de la etiqueta aburrida para usted.

from category_encoders import OneHotEncoder cat_features = [''color'', ''director_name'', ''actor_2_name''] enc = OneHotEncoder(categorical_features=cat_features) enc.fit(dataset.values)


Puede aplicar ambas transformaciones (de las categorías de texto a las categorías de enteros, luego de las categorías de enteros a los vectores de un solo color) en una sola toma usando la clase LabelBinarizer:

cat_features = [''color'', ''director_name'', ''actor_2_name''] encoder = LabelBinarizer() new_cat_features = encoder.fit_transform(cat_features) new_cat_features

Tenga en cuenta que esto devuelve una matriz NumPy densa de forma predeterminada. Puede obtener una matriz dispersa al pasar sparse_output = True al constructor LabelBinarizer.

Aprendizaje automático de fuentes con Scikit-Learn y TensorFlow


Si el conjunto de datos está en el marco de datos de pandas, usando

pandas.get_dummies

Será más sencillo.

* corregido de pandas.get_getdummies a pandas.get_dummies


Si lees los documentos de OneHotEncoder , verás que la entrada para el fit es "Matriz de entrada de tipo int". Así que necesitas hacer dos pasos para tus datos codificados en caliente.

from sklearn import preprocessing cat_features = [''color'', ''director_name'', ''actor_2_name''] enc = preprocessing.LabelEncoder() enc.fit(cat_features) new_cat_features = enc.transform(cat_features) print new_cat_features # [1 2 0] new_cat_features = new_cat_features.reshape(-1, 1) # Needs to be the correct shape ohe = preprocessing.OneHotEncoder(sparse=False) #Easier to read print ohe.fit_transform(new_cat_features)

Salida :

[[ 0. 1. 0.] [ 0. 0. 1.] [ 1. 0. 0.]]

EDITAR

A partir de la OneHotEncoder 0.20 esto se volvió un poco más fácil, no solo porque OneHotEncoder ahora maneja cadenas de manera agradable, sino también porque podemos transformar varias columnas fácilmente usando ColumnTransformer , vea a continuación un ejemplo

from sklearn.compose import ColumnTransformer from sklearn.preprocessing import LabelEncoder, OneHotEncoder import numpy as np X = np.array([[''apple'', ''red'', 1, ''round'', 0], [''orange'', ''orange'', 2, ''round'', 0.1], [''bannana'', ''yellow'', 2, ''long'', 0], [''apple'', ''green'', 1, ''round'', 0.2]]) ct = ColumnTransformer( [(''oh_enc'', OneHotEncoder(sparse=False), [0, 1, 3]),], # the column numbers I want to apply this to remainder=''passthrough'' # This leaves the rest of my columns in place ) print(ct2.fit_transform(X)) # Notice the output is a string

Salida:

[[''1.0'' ''0.0'' ''0.0'' ''0.0'' ''0.0'' ''1.0'' ''0.0'' ''0.0'' ''1.0'' ''1'' ''0''] [''0.0'' ''0.0'' ''1.0'' ''0.0'' ''1.0'' ''0.0'' ''0.0'' ''0.0'' ''1.0'' ''2'' ''0.1''] [''0.0'' ''1.0'' ''0.0'' ''0.0'' ''0.0'' ''0.0'' ''1.0'' ''1.0'' ''0.0'' ''2'' ''0''] [''1.0'' ''0.0'' ''0.0'' ''1.0'' ''0.0'' ''0.0'' ''0.0'' ''0.0'' ''1.0'' ''1'' ''0.2'']]