Python'da bir sıcak kodlamayı nasıl yapabilirim?


132

% 80 kategorik değişkenli bir makine öğrenimi sınıflandırma sorunum var. Sınıflandırma için bir sınıflandırıcı kullanmak istiyorsam tek bir dinamik kodlama kullanmalı mıyım? Verileri kodlama olmadan bir sınıflandırıcıya aktarabilir miyim?

Özellik seçimi için aşağıdakileri yapmaya çalışıyorum:

  1. Tren dosyasını okudum:

    num_rows_to_read = 10000
    train_small = pd.read_csv("../../dataset/train.csv",   nrows=num_rows_to_read)
  2. Kategorik özelliklerin türünü 'kategori' olarak değiştiriyorum:

    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. Tek bir dinamik kodlama kullanıyorum:

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

Sorun şu ki, güçlü bir makine kullanmama rağmen 3. bölüm sık sık takılıyor.

Bu nedenle, tek bir sıcak kodlama olmadan özelliklerin önemini belirlemek için herhangi bir özellik seçimi yapamam.

Ne önerirsiniz?

Yanıtlar:


159

Yaklaşım 1: Pandalar veri çerçevesinde get_dummies kullanabilirsiniz.

Örnek 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

Örnek 2:

Aşağıdaki, belirli bir sütunu bir sıcak sütuna dönüştürecektir. Birden fazla mankene sahip olmak için ön ek kullanın.

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

Yaklaşım 2: Scikit-learn'ü kullanın

Üç özellik ve dört örnek içeren bir veri kümesi verildiğinde, kodlayıcının özellik başına maksimum değeri bulmasına ve verileri ikili tek etkin kodlamaya dönüştürmesine izin veriyoruz.

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

İşte bu örneğin bağlantısı: http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html


20
ayarı drop_first=Trueile get_dummiesuzaklaşmaların ihtiyacını ayrı orijinal sütun bırakın
OverflowingTheGlass

1
Örnek 2'de, birleştirme kullanmadan yeni sütunları veri çerçevesine birleştirmenin bir yolu var mı? Gerçekten büyük bir veri kümesiyle uğraşıyorum ve bunu yapmaya çalıştığımda MemoryError alıyorum.
J.Dahlgren

Aynı sayıda satıra sahip df2'niz varsa, join kullanmadan dataframe'e yeni sütun ekleyebilirsiniz. şunu kullanarak kopyalayabilirsiniz: df [“newColname”] = df2 [“col”]
Sayali Sonawane

1
Örneğin bir görüntü kullanmak kötüydü
villasv

9
@ OverflowingTheGlass- drop-first = True orijinal sütunu kaldırmaz. Kategorik özelliğin ilk düzeyini düşürür, böylece k sütunu yerine k-1 sütunlarıyla sonuçlanırsınız, k kategorik özelliğin temel niteliğidir.
Garima Jain

42

Temel tek etkin kodlama için Pandaları kullanmak çok daha kolay. Daha fazla seçenek arıyorsanız, kullanabilirsiniz scikit-learn.

Pandalar ile temel tek sıcak kodlama için, veri çerçevenizi get_dummies işlevine aktarmanız yeterlidir .

Örneğin, imdb_movies adında bir veri çerçevem ​​varsa :

görüntü açıklamasını buraya girin

... ve Puanlı sütunu tek seferde kodlamak istiyorum, basitçe şunu yapıyorum:

pd.get_dummies(imdb_movies.Rated)

görüntü açıklamasını buraya girin

Bu , var olan dataframeher derecelendirme " düzeyi " için bir sütunun yanı sıra belirli bir gözlem için bu derecelendirmenin varlığını belirten bir 1 veya 0 ile birlikte yeni bir sütun döndürür .

Genellikle bunun orijinalin bir parçası olmasını isteriz dataframe. Bu durumda, yeni sahte kodlu çerçevemizi " sütun bağlama " kullanarak orijinal çerçeveye bağlarız .

Pandas concat işlevini kullanarak sütun bağlayabiliriz :

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

görüntü açıklamasını buraya girin

Şimdi tam olarak bir analiz yapabiliriz dataframe.

BASİT YARDIMCI FONKSİYON

Bunu hızlı bir şekilde yapmak için kendinize bir yardımcı program işlevi yapmanızı tavsiye ederim :

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)

Kullanım :

encode_and_bind(imdb_movies, 'Rated')

Sonuç :

görüntü açıklamasını buraya girin

Ayrıca, @pmalbu açıklamasına göre, işlevin orijinal feature_to_encode'u kaldırmasını istiyorsanız, bu sürümü kullanı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) 

Aşağıdaki gibi aynı anda birden fazla özelliği kodlayabilirsiniz:

features_to_encode = ['feature_1', 'feature_2', 'feature_3',
                      'feature_4']
for feature in features_to_encode:
    res = encode_and_bind(train_set, feature)

1
Bir sıcak uçlu sütunu orijinal veri çerçevesiyle birleştirdikten sonra orijinal feature_to_encode'u bırakmanızı öneririm.
pmalbu

Cevaplamak için bu seçenek eklendi. Teşekkürler.
Cybernetic

28

Bunu numpy.eyeve a dizi öğesi seçim mekanizmasını kullanarak yapabilirsiniz :

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]

Dönüş değeri indices_to_one_hot(nb_classes, data)şimdi

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

.reshape(-1)(Ayrıca sahip olabilir lütfen doğru etiketler formata sahip orada yapmaktır [[2], [3], [4], [0]]).


1
Bu, dize değerine sahip sütunların OHE'si için çalışmayacaktır.
Abhilash Awasthi

2
@AbhilashAwasthi Elbette ... ama o zaman neden çalışmasını bekliyorsunuz?
Martin Thoma

22

İlk olarak, tek bir sıcak kodlamanın en kolay yolu: Sklearn kullanın.

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

İkinci olarak, pandaları tek bir sıcak kodlamada kullanmanın bu kadar basit olduğunu düşünmüyorum (yine de onaylanmamış)

Python için Pandalarda kukla değişkenler oluşturma

Son olarak, bir sıcak kodlamanız gerekli mi? Tek bir sıcak kodlama, özelliklerin sayısını katlanarak artırarak herhangi bir sınıflandırıcının veya çalıştıracağınız herhangi bir şeyin çalışma süresini büyük ölçüde artırır. Özellikle her kategorik özelliğin birçok düzeyi olduğunda. Bunun yerine sahte kodlama yapabilirsiniz.

Sahte kodlama kullanmak, çok daha az çalışma süresi ve karmaşıklık için genellikle iyi çalışır. Bilge bir profesör bana "Az Daha Çoktur" demişti.

İsterseniz özel kodlama işlevimin kodu burada.

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

DÜZENLE: Daha net olması için karşılaştırma:

Tek sıcak kodlama: n seviyeleri n-1 sütuna dönüştür.

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

Kategorik özelliğinizde birçok farklı tür (veya düzey) varsa, bunun hafızanızı nasıl patlatacağını görebilirsiniz. Unutmayın, bu sadece BİR sütun.

Sahte Kodlama:

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

Bunun yerine sayısal gösterimlere dönüştürün. Biraz doğruluk pahasına özellik alanından büyük ölçüde tasarruf sağlar.


1
1.% 80 kategorik değişken içeren bir veri setim var. Anladığım kadarıyla, bu veriler için bir sınıflandırıcı kullanmak istiyorsam bir sıcak kodlama kullanmalıyım, yoksa bir sıcak kodlamayı yapmadığımda sınıflandırıcı kategorik değişkenleri doğru şekilde ele almaz? Kodlamama seçeneği var mı? 2. Saprse = True ile pd.get_dummies (train_small, sparse = True) kullanırsam, bu bellek sorununu çözmez mi? 3. Böyle bir soruna nasıl yaklaşmalıyım?
avicohen

Dediğim gibi iki seçenek var. 1) Bir sıcak kodlama -> kategorik özelliklerdeki her seviyeyi yeni bir sütuna dönüştürün. 2) Sahte kodlama -> her sütunu sayısal gösterimlere dönüştürün. Daha net olması için yukarıdaki cevabımı düzenleyeceğim. Ancak sağladığım işlevi çalıştırabilirsiniz ve çalışmalıdır
Wboy

17
"biraz doğruluk pahasına." Nasıl "biraz" dersin? Belki bazı durumlarda, ancak diğerlerinde doğruluk çok zarar görebilir. Bu çözüm, nitel özelliklerin sürekli olarak ele alınmasıyla sonuçlanır, bu da modelinizin verilerden düzgün bir şekilde öğrenmeyeceği anlamına gelir.
Josh Morel

2
Josh'un yukarıda dediği gibi, ikinci örneğinizde modele bunu söylüyorsunuz mouse > cat > dogama durum böyle değil. get_dummiesdeneyimimden (çok sınırlı da olsa) kategorik değişkenleri model dostu verilere aktarmanın en basit yoludur
Martin O Leary

5
Bu çözüm, diğer bazı yorumların da işaret ettiği gibi çok tehlikelidir. Kategorik değişkenlere keyfi olarak emirler ve mesafeler atar. Bunu yapmak, model esnekliğini rastgele bir şekilde azaltır. Ağaç tabanlı modeller için, bu tür kodlama olası alt küme olasılıklarını azaltır. Örneğin, şu anda yalnızca iki olası bölme elde edebilirsiniz [(0), (1,2)] ve [(0,1), (2)] ve bölme [(0,2), (1)] imkansız. Kategori sayısı yüksek olduğunda kayıp çok daha önemlidir.
Random Certainty

19

Pandalarla tek bir sıcak kodlama çok kolaydır:

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

DÜZENLE:

Sklearn kullanarak one_hot için başka bir yol 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)

14

Numpy.eye işlevini kullanabilirsiniz.

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

Sonuç

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

2
Az önce cevabımı kopyaladın mı?
Martin Thoma

@Martin Thoma - Sanırım, yapmadım
Dieter

5

pandas as, söz konusu sütun / ların bir sıcak kodlamasını elde etmek için "get_dummies" yerleşik işlevine sahiptir.

tek çalışırken kodlama için tek satırlı kod:

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

4

İşte DictVectorizerPandas DataFrame.to_dict('records')yöntemini kullanan bir çözüm .

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

3

Tek sıcak kodlama, değerleri gösterge değişkenlerine dönüştürmekten biraz daha fazlasını gerektirir. Tipik olarak makine öğrenimi süreci, bu kodlamayı birkaç kez doğrulama veya test veri kümelerine uygulamanızı ve oluşturduğunuz modeli gerçek zamanlı gözlemlenen verilere uygulamanızı gerektirir. Modeli oluşturmak için kullanılan eşlemeyi (dönüşümü) saklamalısınız. İyi bir çözüm, DictVectorizerveya LabelEncoder(ardından gelir get_dummies. Kullanabileceğiniz bir işlev:

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)

Bu, bir panda veri çerçevesi üzerinde çalışır ve veri çerçevesinin her sütunu için bir eşleme oluşturup geri döndürür. Yani buna şöyle diyorsunuz:

train_data, le_dict = oneHotEncode2(train_data)

Daha sonra test verileri üzerinde eğitimden geri dönen sözlüğü geçerek arama yapılır:

test_data, _ = oneHotEncode2(test_data, le_dict)

Eşdeğer bir yöntem kullanmaktır DictVectorizer. Blogumda aynı konuyla ilgili bir gönderi var. Bu yaklaşımın arkasında basitçe get_dummies postası (açıklama: bu benim kendi blogum) üzerinden bazı nedenler sağladığından burada bahsediyorum .


3

Verileri kodlamadan catboost sınıflandırıcısına aktarabilirsiniz. Catboost, tek etkin ve hedef genişleyen ortalama kodlama gerçekleştirerek kategorik değişkenleri kendisi yönetir.


3

Aşağıdakileri de yapabilirsiniz. Aşağıdakiler için kullanmanız gerekmediğini unutmayın 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

Açık sütunları kategorik olarak da değiştirebilirsiniz. Örneğin, burada ColorveGroup

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

2

Bu partiye geç kaldığımı biliyorum, ancak bir veri çerçevesini otomatik bir şekilde kodlamanın en basit yolu bu işlevi kullanmaktır:

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

1

Bunu akustik modelimde kullandım: muhtemelen bu, modelinize yardımcı olur.

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

0

Diğer sorulara eklemek için, Numpy kullanarak bir Python 2.0 işlevi ile nasıl yaptığımı anlatayım:

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

Çizgi n_values = np.max(y_) + 1Örneğin mini gruplar kullanmanız durumunda, çok sayıda nöron kullanmanız için sabit kodlanmış olabilir.

Bu işlevin kullanıldığı demo projesi / öğretici: https://github.com/gu Guillaume-chevalier/LSTM-Human-Activity- Recognition


0

Bu benim için çalışıyor:

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

Çıktı:

[0, 1, 2, 0]

0

Olabilir ve şu kadar kolay olmalıdır:

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

Kullanım:

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

0

@Martin Thoma'nın cevabını genişletmek

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]

0

Kısa cevap

Burada bir sıcak-kodlama yapmak için bir fonksiyonudur olmadan numpy, panda veya diğer paketleri kullanarak. Tam sayıların, mantıksal değerlerin veya dizelerin (ve belki başka türlerin de) bir listesini alır.

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

Misal:

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

Uzun (er) Cevap

Bu sorunun zaten birçok cevabı olduğunu biliyorum ama iki şeyi fark ettim. İlk olarak, cevapların çoğu uyuşmuş ve / veya pandalar gibi paketler kullanıyor. Ve bu iyi bir şey. Üretim kodu yazıyorsanız, muhtemelen numpy / pandas paketlerinde sağlananlar gibi sağlam, hızlı algoritmalar kullanıyor olmalısınız. Ancak, eğitim adına, birisinin sadece bir başkasının algoritmasının bir uygulaması değil, şeffaf bir algoritmaya sahip bir cevap vermesi gerektiğini düşünüyorum. İkincisi, yanıtların birçoğunun, aşağıdaki gereksinimlerden birini karşılamadığı için tek sıcak kodlamanın sağlam bir uygulamasını sağlamadığını fark ettim. Yararlı, doğru ve sağlam bir etkin kodlama işlevi için bazı gereksinimler (gördüğüm kadarıyla) aşağıda verilmiştir:

Tek sıcak kodlama işlevi şunları yapmalıdır:

  • giriş olarak çeşitli türlerin listesini (ör. tamsayılar, dizeler, kayan değerler, vb.)
  • yinelenen bir girdi listesini işlemek
  • girişlere karşılık gelen (aynı sırada) listelerin bir listesini döndürür
  • her listenin olabildiğince kısa olduğu bir liste listesi döndür

Bu sorunun yanıtlarının çoğunu test ettim ve çoğu yukarıdaki gereksinimlerden birinde başarısız oldu.


0

Bunu dene:

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

Ortaya çıkan veri çerçevesi df_train_encoded çerçevesi orijinal ile aynıdır, ancak kategorik özellikler artık tek çalışırken kodlanmış sürümleriyle değiştirilmiştir.

category_encoders Burada daha fazla bilgi .


-1

İşte bu yaklaşımı denedim:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.