Bagaimana saya bisa satu encode panas di Python?

132

Saya memiliki masalah klasifikasi pembelajaran mesin dengan 80% variabel kategori. Haruskah saya menggunakan satu pengkodean panas jika saya ingin menggunakan beberapa classifier untuk klasifikasi? Bisakah saya meneruskan data ke pengklasifikasi tanpa pengkodean?

Saya mencoba melakukan hal berikut untuk pemilihan fitur:

  1. Saya membaca file kereta:

    num_rows_to_read = 10000
    train_small = pd.read_csv("../../dataset/train.csv",   nrows=num_rows_to_read)
    
  2. Saya mengubah jenis fitur kategorikal menjadi 'kategori':

    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. Saya menggunakan satu pengodean panas:

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

Masalahnya adalah bagian 3 sering macet, meskipun saya menggunakan mesin yang kuat.

Jadi, tanpa satu pengkodean panas saya tidak dapat melakukan pemilihan fitur, untuk menentukan pentingnya fitur.

Apa yang kamu sarankan?

avicohen
sumber

Jawaban:

159

Pendekatan 1: Anda dapat menggunakan get_dummies di bingkai data panda.

Contoh 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

Contoh 2:

Berikut ini akan mengubah kolom yang diberikan menjadi satu panas. Gunakan awalan untuk memiliki banyak boneka.

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

Pendekatan 2: Gunakan Scikit-learn

Diberi dataset dengan tiga fitur dan empat sampel, kami membiarkan pembuat enkode menemukan nilai maksimum per fitur dan mentransformasikan data menjadi penyandiaksaraan satu-panas biner.

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

Berikut ini tautan untuk contoh ini: http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html

Sayali Sonawane
sumber
20
pengaturan drop_first=Truedengan get_dummiesmenghilangkan kebutuhan untuk menjatuhkan kolom asli secara terpisah
OverflowingTheGlass
1
Dalam contoh 2, apakah ada cara untuk bergabung dengan kolom baru ke bingkai data tanpa menggunakan gabungan? Saya berurusan dengan dataset yang sangat besar dan mendapatkan MemoryError ketika saya mencoba melakukan itu.
J.Dahlgren
Anda dapat menambahkan kolom baru ke bingkai data tanpa menggunakan gabungan jika Anda memiliki df2 dengan jumlah baris yang sama. Anda dapat menyalin menggunakan: df [“newColname”] = df2 [“col”]
Sayali Sonawane
1
Menggunakan gambar misalnya 2 adalah jahat
villasv
9
@ OverflowingTheGlass- drop-first = True tidak menghapus kolom asli. Itu menjatuhkan tingkat pertama dari fitur kategorikal sehingga Anda berakhir dengan kolom k-1 dan bukan kolom k, k menjadi kardinalitas fitur kategorikal.
Garima Jain
42

Jauh lebih mudah untuk menggunakan Panda untuk penyandian dasar satu panas. Jika Anda mencari lebih banyak opsi yang dapat Anda gunakan scikit-learn.

Untuk pengodean satu-panas dasar dengan Pandas Anda cukup meneruskan frame data Anda ke fungsi get_dummies .

Misalnya, jika saya memiliki kerangka data bernama imdb_movies :

masukkan deskripsi gambar di sini

... dan saya ingin sekali-panas menyandikan kolom Nilai, saya cukup lakukan ini:

pd.get_dummies(imdb_movies.Rated)

masukkan deskripsi gambar di sini

Ini mengembalikan yang baru dataframedengan kolom untuk setiap " level " peringkat yang ada, bersama dengan 1 atau 0 yang menentukan keberadaan peringkat itu untuk pengamatan yang diberikan.

Biasanya, kami ingin ini menjadi bagian dari aslinya dataframe. Dalam hal ini, kami cukup menempelkan bingkai kode boneka baru kami ke bingkai asli menggunakan " pengikat kolom .

Kita dapat mengikat kolom dengan menggunakan fungsi concat Pandas :

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

masukkan deskripsi gambar di sini

Kita sekarang dapat menjalankan analisis secara penuh dataframe.

FUNGSI UTILITAS SEDERHANA

Saya akan merekomendasikan menjadikan diri Anda fungsi utilitas untuk melakukan ini dengan cepat:

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)

Penggunaan :

encode_and_bind(imdb_movies, 'Rated')

Hasil :

masukkan deskripsi gambar di sini

Juga, sesuai komentar @pmalbu, jika Anda ingin fungsi untuk menghapus feature_to_encode asli maka gunakan versi ini:

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) 

Anda dapat menyandikan beberapa fitur sekaligus sebagai berikut:

features_to_encode = ['feature_1', 'feature_2', 'feature_3',
                      'feature_4']
for feature in features_to_encode:
    res = encode_and_bind(train_set, feature)
Berhubung dgn sibernetika
sumber
1
Saya akan menyarankan untuk menghapus feature_to_encode asli setelah Anda menggabungkan satu kolom yang berakhir panas dengan kerangka data asli.
pmalbu
Menambahkan opsi ini untuk menjawab. Terima kasih.
Cybernetic
28

Anda dapat melakukannya dengan numpy.eyedan menggunakan mekanisme pemilihan elemen array:

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]

Nilai kembalian dari indices_to_one_hot(nb_classes, data)sekarang

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

Ada di .reshape(-1)sana untuk memastikan Anda memiliki format label yang tepat (Anda mungkin juga punya [[2], [3], [4], [0]]).

Martin Thoma
sumber
1
Ini tidak akan berfungsi untuk OHE kolom dengan nilai string.
Abhilash Awasthi
2
@AbhilashAwasthi Tentu ... tapi mengapa Anda berharap itu bekerja?
Martin Thoma
22

Pertama, cara termudah untuk satu encode panas: gunakan Sklearn.

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

Kedua, saya tidak berpikir menggunakan panda ke satu kode panas adalah sesederhana itu (belum dikonfirmasi)

Membuat variabel dummy dalam panda untuk python

Terakhir, apakah perlu bagi Anda untuk satu encode panas? Satu pengkodean panas secara eksponensial meningkatkan jumlah fitur, secara drastis meningkatkan waktu berjalan dari setiap classifier atau apa pun yang akan Anda jalankan. Terutama ketika setiap fitur kategorikal memiliki banyak tingkatan. Sebagai gantinya Anda dapat melakukan pengkodean dummy.

Menggunakan penyandian dummy biasanya bekerja dengan baik, untuk waktu dan kerumitan yang jauh lebih sedikit. Seorang profesor yang bijak pernah mengatakan kepada saya, 'Less is More'.

Ini kode untuk fungsi penyandian khusus saya jika Anda mau.

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: Perbandingan menjadi lebih jelas:

Pengkodean satu-panas: mengonversi n level ke n-1 kolom.

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

Anda dapat melihat bagaimana ini akan meledak memori Anda jika Anda memiliki banyak jenis (atau level) yang berbeda dalam fitur kategorikal Anda. Perlu diingat, ini hanya SATU kolom.

Pengodean Dummy:

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

Konversi ke representasi numerik saja. Sangat menghemat ruang fitur, dengan biaya sedikit akurasi.

Wboy
sumber
1
1. Saya memiliki kumpulan data yang memiliki 80% variabel kategori. Untuk pemahaman saya, saya harus menggunakan satu pengkodean panas jika saya ingin menggunakan classifier untuk data ini, kalau tidak dalam melakukan salah satu pengkodean panas, classifier tidak akan memperlakukan variabel kategori dengan cara yang benar? Apakah ada opsi untuk tidak menyandikan? 2. Jika saya menggunakan pd.get_dummies (train_small, sparse = True) dengan saprse = True - bukankah itu memecahkan masalah memori? 3. Bagaimana saya harus mendekati masalah seperti itu?
avicohen
Seperti yang saya katakan, ada dua opsi. 1) Satu hot encode -> konversi setiap level dalam fitur kategorikal ke kolom baru. 2) Pengkodean Dummy -> konversi setiap kolom ke representasi numerik. Saya akan mengedit jawaban saya di atas agar lebih jelas. Tetapi Anda hanya dapat menjalankan fungsi yang saya sediakan dan seharusnya berfungsi
Wboy
17
"Dengan mengorbankan sedikit akurasi." Bagaimana Anda bisa mengatakan "sedikit"? Mungkin dalam beberapa kasus, tetapi dalam kasus lain, akurasinya bisa sangat menyakitkan. Solusi ini menghasilkan memperlakukan fitur kualitatif sebagai kontinu yang berarti model Anda tidak akan belajar dari data dengan benar.
Josh Morel
2
Seperti yang dikatakan Josh di atas, dalam contoh kedua Anda, Anda akhirnya memberi tahu model itu mouse > cat > dogtetapi ini tidak terjadi. get_dummiesadalah cara paling mudah untuk mentransfer variabel kategori ke dalam data model yang ramah dari pengalaman saya (walaupun sangat terbatas)
Martin O Leary
5
Solusi ini sangat berbahaya seperti yang ditunjukkan oleh beberapa komentar lain. Ini sewenang-wenang memberikan pesanan dan jarak ke variabel kategori. Melakukannya mengurangi fleksibilitas model secara acak. Untuk model berbasis pohon, pengkodean seperti itu mengurangi kemungkinan kemungkinan pengaturan ulang. Misalnya, Anda hanya bisa mendapatkan dua kemungkinan perpecahan sekarang [(0), (1,2)] dan [(0,1), (2)], dan pemisahan [(0,2), (1)] adalah mustahil. Kerugiannya jauh lebih signifikan ketika jumlah kategori tinggi.
Kepastian Acak
19

Satu penyandian panas dengan panda sangat mudah:

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

EDIT:

Cara lain untuk one_hot menggunakan sklearn's 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
sumber
14

Anda dapat menggunakan fungsi 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()

Hasil

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.]]
Diet
sumber
2
Apakah Anda baru menyalin jawaban saya?
Martin Thoma
@Martin Thoma - saya pikir, saya tidak
Dieter
5

panda sebagai memiliki fungsi inbuilt "get_dummies" untuk mendapatkan satu pengkodean panas dari kolom / s tertentu.

satu kode baris untuk satu-hot-encoding:

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

Berikut adalah solusi menggunakan DictVectorizerdan DataFrame.to_dict('records')metode 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
sumber
3

Pengkodean satu-panas memerlukan sedikit lebih banyak daripada mengonversi nilai ke variabel indikator. Biasanya proses ML mengharuskan Anda untuk menerapkan pengkodean ini beberapa kali untuk validasi atau menguji kumpulan data dan menerapkan model yang Anda buat untuk data yang diamati secara waktu nyata. Anda harus menyimpan pemetaan (transformasi) yang digunakan untuk membangun model. Solusi yang baik akan menggunakan DictVectorizeratau LabelEncoder(diikuti oleh get_dummies. Berikut adalah fungsi yang dapat Anda gunakan:

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)

Ini bekerja pada bingkai data panda dan untuk setiap kolom dari kerangka data yang dibuatnya dan mengembalikan pemetaan kembali. Jadi Anda akan menyebutnya seperti ini:

train_data, le_dict = oneHotEncode2(train_data)

Kemudian pada data uji, panggilan dilakukan dengan melewati kamus yang dikembalikan dari pelatihan:

test_data, _ = oneHotEncode2(test_data, le_dict)

Metode yang setara adalah menggunakan DictVectorizer. Posting terkait juga ada di blog saya. Saya menyebutkannya di sini karena memberikan beberapa alasan di balik pendekatan ini daripada hanya menggunakan posting get_dummies (pengungkapan: ini adalah blog saya sendiri).

Tukeys
sumber
3

Anda dapat meneruskan data ke penglasifikasi catboost tanpa penyandian. Catboost menangani variabel kategorikal itu sendiri dengan melakukan pengkodean rata-rata satu-panas dan perluasan target.

Garima Jain
sumber
3

Anda dapat melakukan hal berikut juga. Catatan untuk di bawah ini Anda tidak harus menggunakan 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

Anda juga dapat mengubah kolom eksplisit menjadi kategorikal. Sebagai contoh, di sini saya mengubah ColordanGroup

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
sumber
2

Saya tahu saya terlambat ke pesta ini, tetapi cara paling sederhana untuk memanaskan kode data secara otomatis adalah dengan menggunakan fungsi ini:

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

Saya menggunakan ini dalam model akustik saya: mungkin ini membantu dalam model Anda.

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
sumber
0

Untuk menambah pertanyaan lain, izinkan saya memberikan bagaimana saya melakukannya dengan fungsi Python 2.0 menggunakan 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

Jalur ini n_values = np.max(y_) + 1bisa berupa kode keras bagi Anda untuk menggunakan jumlah neuron yang baik jika Anda menggunakan mini-batch misalnya.

Demo proyek / tutorial di mana fungsi ini telah digunakan: https://github.com/guillaume-chevalier/LSTM-Human-Activity-Recognition

Guillaume Chevalier
sumber
0

Ini bekerja untuk saya:

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

Keluaran:

[0, 1, 2, 0]
scottlittle
sumber
0

Itu bisa dan harus semudah:

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

Penggunaan:

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

Memperluas jawaban @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
sumber
0

Jawaban singkat

Berikut adalah fungsi untuk melakukan satu-hot-encoding tanpa menggunakan numpy, panda, atau paket lainnya. Dibutuhkan daftar bilangan bulat, boolean, atau string (dan mungkin tipe lainnya juga).

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

Contoh:

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

Panjang (er) Jawaban

Saya tahu sudah ada banyak jawaban untuk pertanyaan ini, tetapi saya memperhatikan dua hal. Pertama, sebagian besar jawaban menggunakan paket seperti numpy dan / atau panda. Dan ini adalah hal yang baik. Jika Anda menulis kode produksi, Anda mungkin harus menggunakan algoritma yang kuat dan cepat seperti yang disediakan dalam paket numpy / panda. Tetapi, demi pendidikan, saya pikir seseorang harus memberikan jawaban yang memiliki algoritma transparan dan bukan hanya implementasi algoritma orang lain. Kedua, saya perhatikan bahwa banyak jawaban tidak memberikan implementasi yang kuat dari pengodean satu-panas karena tidak memenuhi salah satu persyaratan di bawah ini. Berikut adalah beberapa persyaratan (seperti yang saya lihat) untuk fungsi pengkodean satu panas yang bermanfaat, akurat, dan kuat:

Fungsi pengkodean satu-panas harus:

  • menangani daftar berbagai jenis (misalnya bilangan bulat, string, float, dll.) sebagai input
  • menangani daftar input dengan duplikat
  • mengembalikan daftar daftar yang sesuai (dalam urutan yang sama seperti) ke input
  • mengembalikan daftar daftar di mana setiap daftar sesingkat mungkin

Saya menguji banyak jawaban untuk pertanyaan ini dan kebanyakan dari mereka gagal pada salah satu persyaratan di atas.

Floyd
sumber
0

Coba ini:

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

Kerangka data yang dihasilkan df_train_encodedsama dengan aslinya, tetapi fitur kategorikal sekarang diganti dengan versi satu-panas-disandikan.

Informasi lebih lanjut di category_encoders sini .

Andrea Araldo
sumber
-1

Di sini saya mencoba dengan pendekatan ini:

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
sumber