Tengo una máquina de aprendizaje problema de clasificación con el 80% de las variables categóricas. Debo usar una bañera de codificación si quiero usar algunos clasificador para la clasificación? Puedo pasar los datos a un clasificador sin la codificación?

Estoy tratando de hacer lo siguiente para la selección de características:

  1. He leído el tren de archivo:

    num_rows_to_read = 10000
    train_small = pd.read_csv("../../dataset/train.csv",   nrows=num_rows_to_read)
  2. Puedo cambiar el tipo de categoría características a ‘categoría’:

    non_categorial_features = ['orig_destination_distance',
                              'srch_adults_cnt',
                              'srch_children_cnt',
                              'srch_rm_cnt',
                              'cnt']
    
    for categorical_feature in list(train_small.columns):
        if categorical_feature not in non_categorial_features:
            train_small[categorical_feature] = train_small[categorical_feature].astype('category')
  3. Yo uso una bañera de codificación:

    train_small_with_dummies = pd.get_dummies(train_small, sparse=True)

El problema es que el 3 ‘ parte a menudo se atascan, aunque yo estoy usando una fuerte máquina.

Por lo tanto, sin una bañera de codificación ya no puedo hacer la selección de características, para determinar la importancia de las características.

¿Qué recomienda usted?

InformationsquelleAutor avicohen | 2016-05-18

16 Comentarios

  1. 120

    Método 1: puede utilizar get_dummies sobre pandas dataframe.

    Ejemplo 1:

    import pandas as pd
    s = pd.Series(list('abca'))
    pd.get_dummies(s)
    Out[]: 
         a    b    c
    0  1.0  0.0  0.0
    1  0.0  1.0  0.0
    2  0.0  0.0  1.0
    3  1.0  0.0  0.0

    Ejemplo 2:

    El siguiente va a transformar una determinada columna de a uno caliente. El uso del prefijo tener varios maniquíes.

    import pandas as pd
    
    df = pd.DataFrame({
              'A':['a','b','a'],
              'B':['b','a','c']
            })
    df
    Out[]: 
       A  B
    0  a  b
    1  b  a
    2  a  c
    
    # Get one hot encoding of columns B
    one_hot = pd.get_dummies(df['B'])
    # Drop column B as it is now encoded
    df = df.drop('B',axis = 1)
    # Join the encoded df
    df = df.join(one_hot)
    df  
    Out[]: 
           A  a  b  c
        0  a  0  1  0
        1  b  1  0  0
        2  a  0  0  1

    Método 2: Utilizar Scikit-learn

    Dado un conjunto de datos con características de tres y cuatro muestras, dejamos que el codificador de encontrar el máximo valor de cada característica y transformar los datos a un archivo binario de una bañera de codificación.

    >>> from sklearn.preprocessing import OneHotEncoder
    >>> enc = OneHotEncoder()
    >>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])   
    OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)
    >>> enc.n_values_
    array([2, 3, 4])
    >>> enc.feature_indices_
    array([0, 2, 5, 9], dtype=int32)
    >>> enc.transform([[0, 1, 1]]).toarray()
    array([[ 1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.]])

    Aquí está el enlace para este ejemplo: http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html

    • configuración de drop_first=True con get_dummies elimina la necesidad de colocar el original de la columna por separado
    • En el ejemplo 2, hay una manera de unirse a las nuevas columnas para el dataframe sin el uso de unirse? Estoy lidiando con un gran conjunto de datos y obtener MemoryError cuando intento hacer eso.
    • Usted puede añadir una nueva columna a dataframe sin el uso de unirse si usted tiene df2 con el mismo número de filas. usted puede copiar el uso de : df[«newColname»]= df2[«col»]
    • El uso de una imagen, por ejemplo, 2 malo
    • drop-primero= True no quitar la columna original. Cae el primer nivel de la categoría de función, con el fin de terminar con k-1 columnas, en lugar de k columnas, k ser la cardinalidad de la categoría de función.
  2. 21

    Usted puede hacerlo con numpy.ojo y utilizando el elemento de la matriz mecanismo de selección:

    import numpy as np
    nb_classes = 6
    data = [[2, 3, 4, 0]]
    
    def indices_to_one_hot(data, nb_classes):
        """Convert an iterable of indices to one-hot encoded labels."""
        targets = np.array(data).reshape(-1)
        return np.eye(nb_classes)[targets]

    El valor de retorno de indices_to_one_hot(nb_classes, data) es ahora

    array([[[ 0.,  0.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  1.,  0.],
            [ 1.,  0.,  0.,  0.,  0.,  0.]]])

    La .reshape(-1) está ahí para asegurarse de que usted tiene el derecho de etiquetas de formato (también podría tener [[2], [3], [4], [0]]).

    • Esto no funcionará para OHE de las columnas con la cadena de valor.
    • Seguro … pero, ¿por qué esperar a trabajar entonces?
  3. 19

    En primer lugar, la manera más fácil a uno caliente codificar: el uso de Sklearn.

    http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html

    En segundo lugar, no creo que el uso de los pandas a uno caliente codificar es así de simple (aunque sin confirmar)

    Creación de variables ficticias en los pandas para python

    Por último, es necesario que a uno caliente codificar? Caliente una codificación aumenta exponencialmente el número de características, aumentando drásticamente el tiempo de ejecución de cualquier clasificador o cualquier otra cosa que se va a ejecutar. Sobre todo cuando cada categórica función tiene muchos niveles. En su lugar se puede hacer de maniquí de codificación.

    Utilizando el maniquí de codificación generalmente funciona bien, por mucho menos tiempo de ejecución y la complejidad. Un sabio profesor me dijo una vez, ‘Menos es Más’.

    Aquí está el código para mi costumbre de codificación de la función si desea.

    from sklearn.preprocessing import LabelEncoder
    
    #Auto encodes any dataframe column of type category or object.
    def dummyEncode(df):
            columnsToEncode = list(df.select_dtypes(include=['category','object']))
            le = LabelEncoder()
            for feature in columnsToEncode:
                try:
                    df[feature] = le.fit_transform(df[feature])
                except:
                    print('Error encoding '+feature)
            return df

    EDICIÓN: Comparación para ser más claro:

    De una bañera de codificación: convertir los niveles de n a n-1 columnas.

    Index  Animal         Index  cat  mouse
      1     dog             1     0     0
      2     cat       -->   2     1     0
      3    mouse            3     0     1

    Se puede ver cómo esto va a explotar su memoria si tiene muchos tipos diferentes (o niveles) en su categórica característica. Tenga en cuenta que esta es sólo UNA columna.

    Ficticio De Codificación:

    Index  Animal         Index  Animal
      1     dog             1      0   
      2     cat       -->   2      1 
      3    mouse            3      2

    Convertir a representaciones numéricas en su lugar. Mucho se ahorra espacio de características, a un costo de un poco de precisión.

    • 1. Tengo un conjunto de datos que tiene el 80% de las variables categóricas. A mi entender, debo usar una bañera de codificación si se desea utilizar un clasificador para este tipo de datos, más en el caso de no hacer el uno caliente de la codificación de la clasificador de no tratar las variables categóricas en el camino correcto? Hay una opción de no codificar? 2. Si yo uso la ep.get_dummies(train_small, sparse=True) con el saprse=True – ¿eso no resuelve el problema de memoria? 3. ¿Cómo debo abordar un problema?
    • Como ya he dicho, hay dos opciones. 1) Una caliente codificar –> convertir cada nivel en categorías de características en una nueva columna. 2)Dummy de codificación –> convertir cada columna de representaciones numéricas. Voy a editar mi respuesta anterior para ser más claro. Pero usted puede simplemente ejecutar la función que he proporcionado y debería funcionar
    • Algo está claro para mí: si yo uso la ep.get_dummies, convierte cada nivel en categorías de características en una nueva columna. Sin embargo usted dice ficticio sólo son los niveles? A mi entender, si yo no uso una bañera de codificación voy a perder algunos de los significados de los datos y el algoritmo no tratar la estoy correctamente?
    • Creo que eres la incomprensión de mí. Los niveles es el número de valores únicos en una categoría de la columna. por ejemplo, [perro,gato,ratón,perro] –> niveles = 3. Así que si usted desea caliente codificar una columna, obtendrá n-1 columnas de n niveles. Maniquí de codificación simplemente convierte los niveles de representaciones numéricas en la misma columna. así que [perro,gato,ratón,perro] –> [0,1,2,0]
    • es sólo la etiqueta de codificación. No es un caliente de codificación, que se logra a través de la creación ficticia de la característica. En sk-learn de una bañera de codificación se logra mediante el uso de sklearn.preprocessing.OneHotEncoder clase o llamando get_dummies método de pandas DataFrame.
    • ¿Has probado get_dummies método sin sparse parámetro predeterminado es falso?
    • Sí, lo sé, si revisan mi respuesta que es lo que me dijo. Me estaba explicando ficticio de codificación (codificación de etiqueta).
    • «en el costo de un poco de precisión». ¿Cómo puedes decir que «un poco»? Tal vez en algunos casos, pero en otros, la exactitud puede ser mucho daño. Esta solución resultados en el tratamiento de las características cualitativas como continua, lo que significa que su modelo no va a aprender a partir de los datos correctamente.
    • Como Josh dijo anteriormente, en el segundo ejemplo se terminan diciendo que el modelo que mouse > cat > dog pero este no es el caso. get_dummies es la más sencilla de transferir las variables categóricas en el modelo de datos sencillo de usar, desde mi experiencia (aunque de manera muy limitada)
    • Puedo hablar con ninguna autoridad, pero creo que el maniquí de codificación y una bañera de codificación son lo mismo (sinónimos). Creo que el maniquí de codificación de Wboy muestra no es en realidad ficticia de la codificación. No tiene un nombre distinto de ‘transformar’ perro/gato/ratón en un ranking variable ordinal, lo que distorsiona el significado original. Por favor me corrija si estoy equivocado. los pandas get_dummies() yo creo que va a dejar con una bañera de codificación
    • Esta solución es muy peligroso, como se ha señalado por algunos otros comentarios. Se asigna arbitrariamente los pedidos y las distancias para las variables categóricas. Al hacerlo, reduce modelo de flexibilidad en una forma aleatoria. Para el árbol de base de modelos, tales codificación reduce posible subconjunto de posibilidades. Por ejemplo, usted sólo puede tener dos posibles escisiones ahora [(0), (1,2)] y [(0,1),(2)], y los de split [(0,2), (1)] es imposible. La pérdida es mucho más significativo cuando el número de categorías es alta.

  4. 16

    Una bañera de codificación con los pandas es muy fácil:

    def one_hot(df, cols):
        """
        @param df pandas DataFrame
        @param cols a list of columns to encode 
        @return a DataFrame with one-hot encoding
        """
        for each in cols:
            dummies = pd.get_dummies(df[each], prefix=each, drop_first=False)
            df = pd.concat([df, dummies], axis=1)
        return df

    EDICIÓN:

    Otra forma de one_hot utilizando sklearn del LabelBinarizer :

    from sklearn.preprocessing import LabelBinarizer 
    label_binarizer = LabelBinarizer()
    label_binarizer.fit(all_your_labels_list) # need to be global or remembered to use it later
    
    def one_hot_encode(x):
        """
        One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
        : x: List of sample Labels
        : return: Numpy array of one-hot encoded labels
        """
        return label_binarizer.transform(x)
  5. 13

    Mucho más fácil el uso de los Pandas para básica de una bañera de codificación. Si usted está buscando para obtener más opciones que se pueden utilizar scikit-learn.

    Para básica de una bañera de codificación con Pandas simplemente pasar el marco de datos en el get_dummies función.

    Por ejemplo, si tengo un dataframe llamado imdb_movies:

    ¿Cómo puedo caliente una codificar en Python?

    …y quiero una bañera de codificar la intensidad Nominal de la columna, yo simplemente hacer esto:

    pd.get_dummies(imdb_movies.Rated)

    ¿Cómo puedo caliente una codificar en Python?

    Este devuelve un nuevo dataframe con una columna para cada «nivel» de la clasificación que existe, junto con un 1 o 0 especificando la presencia de que la calificación de una determinada observación.

    Generalmente, queremos que esto sea parte de la original dataframe. En este caso nos basta con conectar nuestro nuevo maniquí de imagen codificada en el marco original utilizando «columna de unión.

    Podemos columna se unen mediante el uso de los Pandas concat función:

    rated_dummies = pd.get_dummies(imdb_movies.Rated)
    pd.concat([imdb_movies, rated_dummies], axis=1)

    ¿Cómo puedo caliente una codificar en Python?

    Ahora podemos ejecutar el análisis en nuestra completa dataframe.

    SIMPLE FUNCIÓN DE UTILIDAD DE

    Yo recomendaría hacer una función de utilidad de para hacer esto rápidamente:

    def encode_and_bind(original_dataframe, feature_to_encode):
        dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
        res = pd.concat([original_dataframe, dummies], axis=1)
        return(res)

    Uso:

    encode_and_bind(imdb_movies, 'Rated')

    Resultado:

    ¿Cómo puedo caliente una codificar en Python?

    También, como por @pmalbu comentario, si desea que la función quitar el original feature_to_encode, a continuación, utilizar esta versión:

    def encode_and_bind(original_dataframe, feature_to_encode):
        dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
        res = pd.concat([original_dataframe, dummies], axis=1)
        res = res.drop([feature_to_encode], axis=1)
        return(res) 
    • Yo sugeriría dejar caer el original feature_to_encode después de concatenar el uno caliente terminó columnas con el original dataframe.
    • Añadido esta opción de respuesta. Gracias.
  6. 12

    Puede utilizar numpy.la función del ojo.

    import numpy as np
    
    def one_hot_encode(x, n_classes):
        """
        One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
        : x: List of sample Labels
        : return: Numpy array of one-hot encoded labels
         """
        return np.eye(n_classes)[x]
    
    def main():
        list = [0,1,2,3,4,3,2,1,0]
        n_classes = 5
        one_hot_list = one_hot_encode(list, n_classes)
        print(one_hot_list)
    
    if __name__ == "__main__":
        main()

    Resultado

    D:\Desktop>python test.py
    [[ 1.  0.  0.  0.  0.]
     [ 0.  1.  0.  0.  0.]
     [ 0.  0.  1.  0.  0.]
     [ 0.  0.  0.  1.  0.]
     [ 0.  0.  0.  0.  1.]
     [ 0.  0.  0.  1.  0.]
     [ 0.  0.  1.  0.  0.]
     [ 0.  1.  0.  0.  0.]
     [ 1.  0.  0.  0.  0.]]
    • ¿Usted acaba de copiar mi respuesta?
    • Thoma – creo, yo no
  7. 3

    De una bañera de codificación requiere poco más que convertir los valores a variables indicadoras. Normalmente ML proceso requiere la aplicación de esta codificación varias veces a la validación o prueba de conjuntos de datos y aplicando el modelo se construye en tiempo real a los datos observados. Se debe almacenar la cartografía (transformación) que se utilizó para construir el modelo. Una buena solución sería utilizar la DictVectorizer o LabelEncoder (seguido por get_dummies. Aquí es una función que se puede utilizar:

    def oneHotEncode2(df, le_dict = {}):
        if not le_dict:
            columnsToEncode = list(df.select_dtypes(include=['category','object']))
            train = True;
        else:
            columnsToEncode = le_dict.keys()   
            train = False;
    
        for feature in columnsToEncode:
            if train:
                le_dict[feature] = LabelEncoder()
            try:
                if train:
                    df[feature] = le_dict[feature].fit_transform(df[feature])
                else:
                    df[feature] = le_dict[feature].transform(df[feature])
    
                df = pd.concat([df, 
                                  pd.get_dummies(df[feature]).rename(columns=lambda x: feature + '_' + str(x))], axis=1)
                df = df.drop(feature, axis=1)
            except:
                print('Error encoding '+feature)
                #df[feature]  = df[feature].convert_objects(convert_numeric='force')
                df[feature]  = df[feature].apply(pd.to_numeric, errors='coerce')
        return (df, le_dict)

    Esto funciona en un pandas dataframe y para cada columna de la dataframe crea y devuelve un mapeo de la espalda. Por lo que se podría llamar las cosas como esta:

    train_data, le_dict = oneHotEncode2(train_data)

    A continuación, en los datos de prueba, se realiza la llamada al pasar el diccionario de regresar de formación:

    test_data, _ = oneHotEncode2(test_data, le_dict)

    Un método equivalente es el uso de DictVectorizer. Un post sobre el mismo en mi blog. Lo menciono aquí, ya que proporciona un razonamiento detrás de este enfoque con respecto a simplemente utilizando get_dummies post (divulgación: este es mi propio blog).

  8. 3

    Aquí es una solución de uso de DictVectorizer y los Pandas DataFrame.to_dict('records') método.

    >>> import pandas as pd
    >>> X = pd.DataFrame({'income': [100000,110000,90000,30000,14000,50000],
                          'country':['US', 'CAN', 'US', 'CAN', 'MEX', 'US'],
                          'race':['White', 'Black', 'Latino', 'White', 'White', 'Black']
                         })
    
    >>> from sklearn.feature_extraction import DictVectorizer
    >>> v = DictVectorizer()
    >>> qualitative_features = ['country','race']
    >>> X_qual = v.fit_transform(X[qualitative_features].to_dict('records'))
    >>> v.vocabulary_
    {'country=CAN': 0,
     'country=MEX': 1,
     'country=US': 2,
     'race=Black': 3,
     'race=Latino': 4,
     'race=White': 5}
    
    >>> X_qual.toarray()
    array([[ 0.,  0.,  1.,  0.,  0.,  1.],
           [ 1.,  0.,  0.,  1.,  0.,  0.],
           [ 0.,  0.,  1.,  0.,  1.,  0.],
           [ 1.,  0.,  0.,  0.,  0.,  1.],
           [ 0.,  1.,  0.,  0.,  0.,  1.],
           [ 0.,  0.,  1.,  1.,  0.,  0.]])
  9. 3

    pandas como se ha incorporado la función de «get_dummies» para obtener una bañera de codificación de esa columna/s.

    una línea de código para uno-caliente-codificación:

    df=pd.concat([df,pd.get_dummies(df['column name'],prefix='column name')],axis=1).drop(['column name'],axis=1)
  10. 2

    Sé que llego tarde a esta fiesta, pero la forma más sencilla de caliente codificar un dataframe en forma automatizada es el uso de esta función:

    def hot_encode(df):
        obj_df = df.select_dtypes(include=['object'])
        return pd.get_dummies(df, columns=obj_df.columns).values
  11. 2

    Puede pasar los datos a catboost clasificador sin codificación. Catboost identificadores de variables categóricas a sí mismo mediante la realización de un caliente y objetivo de la expansión de la media de la codificación.

  12. 0

    Para agregar a otras preguntas, permítanme dar como yo lo hice con un Python 2.0 la función con Numpy:

    def one_hot(y_):
        # Function to encode output labels from number indexes 
        # e.g.: [[5], [0], [3]] --> [[0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0]]
    
        y_ = y_.reshape(len(y_))
        n_values = np.max(y_) + 1
        return np.eye(n_values)[np.array(y_, dtype=np.int32)]  # Returns FLOATS

    La línea n_values = np.max(y_) + 1 podría ser codificado para el uso de un buen número de neuronas en el caso de que el uso de mini-lotes, por ejemplo.

    Proyecto Demo/tutorial donde esta función se ha utilizado:
    https://github.com/guillaume-chevalier/LSTM-Human-Activity-Recognition

  13. 0

    He utilizado este en mi modelo acústico:
    probablemente, esto ayuda en la ur modelo.

    def one_hot_encoding(x, n_out):
        x = x.astype(int)  
        shape = x.shape
        x = x.flatten()
        N = len(x)
        x_categ = np.zeros((N,n_out))
        x_categ[np.arange(N), x] = 1
        return x_categ.reshape((shape)+(n_out,))
  14. 0

    Puede y debe ser fácil como :

    class OneHotEncoder:
        def __init__(self,optionKeys):
            length=len(optionKeys)
            self.__dict__={optionKeys[j]:[0 if i!=j else 1 for i in range(length)] for j in range(length)}

    Uso :

    ohe=OneHotEncoder(["A","B","C","D"])
    print(ohe.A)
    print(ohe.D)
  15. -1

    Aquí he intentado con este enfoque :

    import numpy as np
    #converting to one_hot
    
    
    
    
    
    def one_hot_encoder(value, datal):
    
        datal[value] = 1
    
        return datal
    
    
    def _one_hot_values(labels_data):
        encoded = [0] * len(labels_data)
    
        for j, i in enumerate(labels_data):
            max_value = [0] * (np.max(labels_data) + 1)
    
            encoded[j] = one_hot_encoder(i, max_value)
    
        return np.array(encoded)

Dejar respuesta

Please enter your comment!
Please enter your name here