Comment puis-je encoder à chaud en Python?

132

J'ai un problème de classification en machine learning avec 80% de variables catégorielles. Dois-je utiliser un encodage à chaud si je veux utiliser un classificateur pour la classification? Puis-je transmettre les données à un classificateur sans encodage?

J'essaie de faire ce qui suit pour la sélection des fonctionnalités:

  1. J'ai lu le fichier du train:

    num_rows_to_read = 10000
    train_small = pd.read_csv("../../dataset/train.csv",   nrows=num_rows_to_read)
  2. Je change le type des caractéristiques catégorielles en 'catégorie':

    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. J'utilise un encodage à chaud:

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

Le problème est que la 3ème partie reste souvent bloquée, même si j'utilise une machine puissante.

Ainsi, sans le seul encodage à chaud, je ne peux pas faire de sélection de fonctionnalités, pour déterminer l'importance des fonctionnalités.

Que recommandez-vous?

Avicohen
la source

Réponses:

159

Approche 1: Vous pouvez utiliser get_dummies sur le dataframe pandas.

Exemple 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

Exemple 2:

Ce qui suit transformera une colonne donnée en une colonne chaude. Utilisez le préfixe pour avoir plusieurs mannequins.

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

Approche 2: utiliser Scikit-learn

Étant donné un ensemble de données avec trois entités et quatre échantillons, nous laissons l'encodeur trouver la valeur maximale par entité et transformons les données en un encodage binaire one-hot.

>>> 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.]])

Voici le lien pour cet exemple: http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html

Sayali Sonawane
la source
20
le réglage drop_first=Trueavec get_dummiessupprime la nécessité de supprimer la colonne d'origine séparément
OverflowingTheGlass
1
Dans l'exemple 2, existe-t-il un moyen de joindre les nouvelles colonnes au dataframe sans utiliser join? J'ai affaire à un très gros ensemble de données et j'obtiens MemoryError quand j'essaye de faire ça.
J.Dahlgren
Vous pouvez ajouter une nouvelle colonne à dataframe sans utiliser de jointure si vous avez df2 avec le même nombre de lignes. vous pouvez copier en utilisant: df [“newColname”] = df2 [“col”]
Sayali Sonawane
1
Utiliser une image pour l'exemple 2 était maléfique
villasv
9
@ OverflowingTheGlass- drop-first = True ne supprime pas la colonne d'origine. Il supprime le premier niveau de la fonctionnalité catégorielle afin que vous vous retrouviez avec k-1 colonnes au lieu de k colonnes, k étant la cardinalité de la fonctionnalité catégorielle.
Garima Jain
42

Beaucoup plus facile à utiliser Pandas pour l'encodage de base à chaud. Si vous recherchez plus d'options, vous pouvez utiliser scikit-learn.

Pour l'encodage à chaud de base avec Pandas, il vous suffit de passer votre trame de données dans la fonction get_dummies .

Par exemple, si j'ai un dataframe appelé imdb_movies :

entrez la description de l'image ici

... et je veux encoder à chaud la colonne Notée, je fais simplement ceci:

pd.get_dummies(imdb_movies.Rated)

entrez la description de l'image ici

Cela renvoie un nouveau dataframeavec une colonne pour chaque " niveau " de notation qui existe, avec un 1 ou un 0 spécifiant la présence de cette note pour une observation donnée.

Habituellement, nous voulons que cela fasse partie de l'original dataframe. Dans ce cas, nous attachons simplement notre nouveau cadre codé factice sur le cadre d'origine en utilisant " column-binding .

Nous pouvons lier des colonnes à l'aide de la fonction concat de Pandas :

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

entrez la description de l'image ici

Nous pouvons maintenant exécuter une analyse sur notre pleine dataframe.

FONCTION UTILITAIRE SIMPLE

Je recommanderais de vous créer une fonction utilitaire pour le faire rapidement:

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)

Utilisation :

encode_and_bind(imdb_movies, 'Rated')

Résultat :

entrez la description de l'image ici

De plus, selon le commentaire @pmalbu, si vous souhaitez que la fonction supprime le feature_to_encode d'origine, utilisez cette version:

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) 

Vous pouvez encoder plusieurs entités en même temps comme suit:

features_to_encode = ['feature_1', 'feature_2', 'feature_3',
                      'feature_4']
for feature in features_to_encode:
    res = encode_and_bind(train_set, feature)
Cybernétique
la source
1
Je suggérerais de supprimer le feature_to_encode d'origine après avoir concaténé les colonnes terminées à chaud avec le dataframe d'origine.
pmalbu
Ajout de cette option pour répondre. Merci.
Cybernetic
28

Vous pouvez le faire avec numpy.eyeet a en utilisant le mécanisme de sélection des éléments du tableau:

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]

La valeur de retour de indices_to_one_hot(nb_classes, data)est maintenant

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.]]])

Le .reshape(-1)est là pour vous assurer que vous avez le bon format d'étiquettes (vous pourriez aussi avoir [[2], [3], [4], [0]]).

Martin Thoma
la source
1
Cela ne fonctionnera pas pour OHE des colonnes avec une valeur de chaîne.
Abhilash Awasthi
2
@AbhilashAwasthi Bien sûr ... mais pourquoi vous attendez-vous à ce que cela fonctionne alors?
Martin Thoma
22

Tout d'abord, le moyen le plus simple de coder à chaud: utilisez Sklearn.

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

Deuxièmement, je ne pense pas que l'utilisation de pandas pour un encodage à chaud soit aussi simple (non confirmé cependant)

Création de variables factices dans Pandas pour Python

Enfin, est-il nécessaire de faire un encodage à chaud? Un encodage à chaud augmente de manière exponentielle le nombre de fonctionnalités, augmentant considérablement le temps d'exécution de tout classificateur ou de tout autre élément que vous allez exécuter. Surtout lorsque chaque caractéristique catégorielle a plusieurs niveaux. Au lieu de cela, vous pouvez effectuer un codage factice.

L'utilisation d'un codage factice fonctionne généralement bien, pour beaucoup moins de temps d'exécution et de complexité. Un prof avisé m'a dit un jour: «Moins c'est plus».

Voici le code de ma fonction d'encodage personnalisée si vous le souhaitez.

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

EDIT: Comparaison pour être plus claire:

Encodage à chaud: convertissez n niveaux en n-1 colonnes.

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

Vous pouvez voir comment cela fera exploser votre mémoire si vous avez de nombreux types (ou niveaux) différents dans votre fonction catégorielle. Gardez à l'esprit que ce n'est qu'une colonne.

Codage factice:

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

Convertissez plutôt en représentations numériques. Économise considérablement de l'espace sur les fonctionnalités, au prix d'un peu de précision.

Wboy
la source
1
1. J'ai un ensemble de données qui contient 80% de variables catégorielles. À ma connaissance, je dois utiliser un codage à chaud si je veux utiliser un classificateur pour ces données, sinon dans le cas de ne pas faire le codage à chaud, le classificateur ne traitera pas les variables catégorielles de la bonne manière? Existe-t-il une option pour ne pas encoder? 2. Si j'utilise pd.get_dummies (train_small, sparse = True) avec saprse = True - cela ne résout-il pas le problème de mémoire? 3. Comment dois-je aborder un tel problème?
avicohen
Comme je l'ai dit, il y a deux options. 1) Un encodage à chaud -> convertir chaque niveau des fonctionnalités catégorielles en une nouvelle colonne. 2) Codage factice -> convertir chaque colonne en représentations numériques. Je modifierai ma réponse ci-dessus pour être plus claire. Mais vous pouvez simplement exécuter la fonction que j'ai fournie et cela devrait fonctionner
Wboy
17
"au prix d'un peu de précision." Comment pouvez-vous dire «un peu»? Peut-être dans certains cas, mais dans d'autres, la précision pourrait être très affectée. Cette solution aboutit à traiter les caractéristiques qualitatives comme continues, ce qui signifie que votre modèle n'apprendra pas correctement des données.
Josh Morel
2
Comme Josh l'a dit plus haut, dans votre deuxième exemple, vous finissez par dire cela au modèle, mouse > cat > dogmais ce n'est pas le cas. get_dummiesest le moyen le plus simple de transférer des variables catégorielles dans des données conviviales pour les modèles de mon expérience (bien que très limité)
Martin O Leary
5
Cette solution est très dangereuse comme le soulignent d'autres commentaires. Il attribue arbitrairement des ordres et des distances aux variables catégorielles. Cela réduit la flexibilité du modèle de manière aléatoire. Pour les modèles arborescents, un tel codage réduit les possibilités de sous-ensembles. Par exemple, vous ne pouvez obtenir que deux fractionnements possibles maintenant [(0), (1,2)] et [(0,1), (2)], et le fractionnement [(0,2), (1)] est impossible. La perte est beaucoup plus importante lorsque le nombre de catégories est élevé.
Random Certainty
19

Un encodage à chaud avec des pandas est très simple:

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

ÉDITER:

Une autre façon de one_hot en utilisant sklearn 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)
Qy Zuo
la source
14

Vous pouvez utiliser la fonction numpy.eye.

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()

Résultat

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.]]
Dieter
la source
2
Vous venez de copier ma réponse?
Martin Thoma
@Martin Thoma - Je pense que je ne l'ai pas fait
Dieter
5

pandas comme a la fonction intégrée "get_dummies" pour obtenir un encodage à chaud de cette colonne / s particulière.

code d'une ligne pour un encodage à chaud:

df=pd.concat([df,pd.get_dummies(df['column name'],prefix='column name')],axis=1).drop(['column name'],axis=1)
Arshdeep Singh
la source
4

Voici une solution utilisant DictVectorizeret la DataFrame.to_dict('records')méthode Pandas .

>>> 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.]])
Josh Morel
la source
3

Le codage à chaud nécessite un peu plus que la conversion des valeurs en variables indicatrices. En règle générale, le processus de ML vous oblige à appliquer ce codage plusieurs fois à des ensembles de données de validation ou de test et à appliquer le modèle que vous construisez à des données observées en temps réel. Vous devez stocker le mappage (transformation) qui a été utilisé pour construire le modèle. Une bonne solution utiliserait le DictVectorizerou LabelEncoder(suivi de get_dummies. Voici une fonction que vous pouvez utiliser:

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)

Cela fonctionne sur une trame de données pandas et pour chaque colonne de la trame de données, il crée et renvoie un mappage. Donc, vous l'appelleriez comme ceci:

train_data, le_dict = oneHotEncode2(train_data)

Puis sur les données de test, l'appel se fait en passant le dictionnaire renvoyé par l'entraînement:

test_data, _ = oneHotEncode2(test_data, le_dict)

Une méthode équivalente consiste à utiliser DictVectorizer. Un article connexe sur le même est sur mon blog. Je le mentionne ici car il fournit un raisonnement derrière cette approche sur l'utilisation simple du post get_dummies (divulgation: c'est mon propre blog).

Tukeys
la source
3

Vous pouvez transmettre les données au classificateur catboost sans codage. Catboost gère lui-même les variables catégorielles en effectuant un codage de moyenne expansible one-hot et target.

Garima Jain
la source
3

Vous pouvez également effectuer les opérations suivantes. Remarque pour ce qui suit, vous ne devez pas utiliser pd.concat.

import pandas as pd 
# intialise data of lists. 
data = {'Color':['Red', 'Yellow', 'Red', 'Yellow'], 'Length':[20.1, 21.1, 19.1, 18.1],
       'Group':[1,2,1,2]} 

# Create DataFrame 
df = pd.DataFrame(data) 

for _c in df.select_dtypes(include=['object']).columns:
    print(_c)
    df[_c]  = pd.Categorical(df[_c])
df_transformed = pd.get_dummies(df)
df_transformed

Vous pouvez également remplacer les colonnes explicites par catégorielles. Par exemple, ici je change le ColoretGroup

import pandas as pd 
# intialise data of lists. 
data = {'Color':['Red', 'Yellow', 'Red', 'Yellow'], 'Length':[20.1, 21.1, 19.1, 18.1],
       'Group':[1,2,1,2]} 

# Create DataFrame 
df = pd.DataFrame(data) 
columns_to_change = list(df.select_dtypes(include=['object']).columns)
columns_to_change.append('Group')
for _c in columns_to_change:
    print(_c)
    df[_c]  = pd.Categorical(df[_c])
df_transformed = pd.get_dummies(df)
df_transformed
sushmit
la source
2

Je sais que je suis en retard à cette fête, mais le moyen le plus simple d'encoder à chaud une trame de données de manière automatisée est d'utiliser cette fonction:

def hot_encode(df):
    obj_df = df.select_dtypes(include=['object'])
    return pd.get_dummies(df, columns=obj_df.columns).values
Rambatino
la source
1

J'ai utilisé ceci dans mon modèle acoustique: cela aide probablement dans votre modèle.

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,))
yunus
la source
0

Pour ajouter à d'autres questions, laissez-moi vous expliquer comment je l'ai fait avec une fonction Python 2.0 utilisant 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 ligne n_values = np.max(y_) + 1pourrait être codée en dur pour que vous utilisiez le bon nombre de neurones au cas où vous utiliseriez des mini-lots par exemple.

Projet de démonstration / tutoriel où cette fonction a été utilisée: https://github.com/guillaume-chevalier/LSTM-Human-Activity-Recognition

Guillaume Chevalier
la source
0

Cela fonctionne pour moi:

pandas.factorize( ['B', 'C', 'D', 'B'] )[0]

Production:

[0, 1, 2, 0]
Scottlittle
la source
0

Cela peut et devrait être aussi simple que:

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)}

Utilisation:

ohe=OneHotEncoder(["A","B","C","D"])
print(ohe.A)
print(ohe.D)
Ofek Ron
la source
0

Élargir la réponse de @Martin Thoma

def one_hot_encode(y):
    """Convert an iterable of indices to one-hot encoded labels."""
    y = y.flatten() # Sometimes not flattened vector is passed e.g (118,1) in these cases
    # the function ends up creating a tensor e.g. (118, 2, 1). flatten removes this issue
    nb_classes = len(np.unique(y)) # get the number of unique classes
    standardised_labels = dict(zip(np.unique(y), np.arange(nb_classes))) # get the class labels as a dictionary
    # which then is standardised. E.g imagine class labels are (4,7,9) if a vector of y containing 4,7 and 9 is
    # directly passed then np.eye(nb_classes)[4] or 7,9 throws an out of index error.
    # standardised labels fixes this issue by returning a dictionary;
    # standardised_labels = {4:0, 7:1, 9:2}. The values of the dictionary are mapped to keys in y array.
    # standardised_labels also removes the error that is raised if the labels are floats. E.g. 1.0; element
    # cannot be called by an integer index e.g y[1.0] - throws an index error.
    targets = np.vectorize(standardised_labels.get)(y) # map the dictionary values to array.
    return np.eye(nb_classes)[targets]
mcagriardic
la source
0

Réponse courte

Voici une fonction pour effectuer un encodage à chaud sans utiliser numpy, pandas ou autres packages. Il prend une liste d'entiers, de booléens ou de chaînes (et peut-être d'autres types aussi).

import typing


def one_hot_encode(items: list) -> typing.List[list]:
    results = []
    # find the unique items (we want to unique items b/c duplicate items will have the same encoding)
    unique_items = list(set(items))
    # sort the unique items
    sorted_items = sorted(unique_items)
    # find how long the list of each item should be
    max_index = len(unique_items)

    for item in items:
        # create a list of zeros the appropriate length
        one_hot_encoded_result = [0 for i in range(0, max_index)]
        # find the index of the item
        one_hot_index = sorted_items.index(item)
        # change the zero at the index from the previous line to a one
        one_hot_encoded_result[one_hot_index] = 1
        # add the result
        results.append(one_hot_encoded_result)

    return results

Exemple:

one_hot_encode([2, 1, 1, 2, 5, 3])

# [[0, 1, 0, 0],
#  [1, 0, 0, 0],
#  [1, 0, 0, 0],
#  [0, 1, 0, 0],
#  [0, 0, 0, 1],
#  [0, 0, 1, 0]]
one_hot_encode([True, False, True])

# [[0, 1], [1, 0], [0, 1]]
one_hot_encode(['a', 'b', 'c', 'a', 'e'])

# [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0], [0, 0, 0, 1]]

Réponse longue (er)

Je sais qu'il y a déjà beaucoup de réponses à cette question, mais j'ai remarqué deux choses. Premièrement, la plupart des réponses utilisent des packages comme numpy et / ou pandas. Et c'est une bonne chose. Si vous écrivez du code de production, vous devriez probablement utiliser des algorithmes robustes et rapides comme ceux fournis dans les packages numpy / pandas. Mais, dans un souci d'éducation, je pense que quelqu'un devrait fournir une réponse qui a un algorithme transparent et pas seulement une implémentation de l'algorithme de quelqu'un d'autre. Deuxièmement, j'ai remarqué que de nombreuses réponses ne fournissent pas une implémentation robuste de l'encodage à chaud car elles ne répondent pas à l'une des exigences ci-dessous. Voici quelques-unes des exigences (telles que je les vois) pour une fonction d'encodage à chaud utile, précise et robuste:

Une fonction d'encodage à chaud doit:

  • gérer une liste de différents types (par exemple des entiers, des chaînes, des flottants, etc.) en entrée
  • gérer une liste d'entrée avec des doublons
  • retourne une liste de listes correspondant (dans le même ordre que) aux entrées
  • retourne une liste de listes où chaque liste est la plus courte possible

J'ai testé de nombreuses réponses à cette question et la plupart d'entre elles échouent à l'une des exigences ci-dessus.

Floyd
la source
0

Essaye ça:

!pip install category_encoders
import category_encoders as ce

categorical_columns = [...the list of names of the columns you want to one-hot-encode ...]
encoder = ce.OneHotEncoder(cols=categorical_columns, use_cat_names=True)
df_train_encoded = encoder.fit_transform(df_train_small)

df_encoded.head ()

La trame de données résultante df_train_encodedest la même que l'original, mais les fonctionnalités catégorielles sont désormais remplacées par leurs versions encodées à chaud.

Plus d'informations category_encoders ici .

Andrea Araldo
la source
-1

Ici, j'ai essayé avec cette approche:

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)
Aaditya Ura
la source