2

カテゴリ機能を離散化するために、LabelEncoder と OneHotEncoder を使用しています。LabelEncoder がデータをアルファベット順にマッピングすることは知っていますが、OneHotEncoder はデータをどのようにマッピングするのでしょうか?

dataFeat上記のように、5 つの異なる列と 4 つの可能なラベルを持つ pandas データフレームがあります。dataFeat = data[['Feat1', 'Feat2', 'Feat3', 'Feat4', 'Feat5']]

Feat1  Feat2  Feat3  Feat4  Feat5
  A      B      A      A      A
  B      B      C      C      C
  D      D      A       A     B
  C      C      A       A     A  

labelencoder私はこのように適用します、

le = preprocessing.LabelEncoder()

intIndexed = dataFeat.apply(le.fit_transform)

これは、LabelEncoder によってラベルがエンコードされる方法です。

Label   LabelEncoded
 A         0
 B         1
 C         2
 D         3

次に、このように OneHotEncoder を適用します

enc = OneHotEncoder(sparse = False)

encModel = enc.fit(intIndexed)

dataFeatY = encModel.transform(intIndexed)

intIndexed.shape = 94,5dataFeatY.shape=94,20

の形に少し混乱していますdataFeatY- それも 95,5 ではないでしょうか?

以下のMhFarahaniの回答に従って、ラベルがどのようにマッピングされているかを確認するためにこれを行いました

import numpy as np

S = np.array(['A', 'B','C','D'])
le = LabelEncoder()
S = le.fit_transform(S)
print(S)

[0 1 2 3]

ohe = OneHotEncoder()
one_hot = ohe.fit_transform(S.reshape(-1,1)).toarray()
print(one_hot.T)

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

これは、ラベルがこのようにマッピングされるということですか、それとも列ごとに異なるということですか? (これは形状が 94,20 であることを説明します)

Label   LabelEncoded    OneHotEncoded
 A         0               1.  0.  0.  0
 B         1               0.  1.  0.  0.
 C         2               0.  0.  1.  0.
 D         3               0.  0.  0.  1.
4

1 に答える 1

8

ワン ホット エンコーディングとは、1 と 0 のベクトルを作成することを意味します。したがって、順序は関係ありません。ではsklearn、最初にカテゴリ データを数値データにエンコードし、次にそれらを にフィードする必要があります。次にOneHotEncoder例を示します。

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder

S = np.array(['b','a','c'])
le = LabelEncoder()
S = le.fit_transform(S)
print(S)
ohe = OneHotEncoder()
one_hot = ohe.fit_transform(S.reshape(-1,1)).toarray()
print(one_hot)

その結果:

[1 0 2]

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

ただしpandas、カテゴリ データを直接変換します。

import pandas as pd
S = pd.Series( {'A': ['b', 'a', 'c']})
print(S)
one_hot = pd.get_dummies(S['A'])
print(one_hot)

出力:

A    [b, a, c]
dtype: object

   a  b  c
0  0  1  0
1  1  0  0
2  0  0  1

マッピング中にわかるように、カテゴリ特徴ごとにベクトルが作成されます。ベクトルの要素は、カテゴリ特徴の位置で 1 になり、それ以外の場所では 0 になります。シリーズに 2 つのカテゴリ機能しかない場合の例を次に示します。

S = pd.Series( {'A': ['a', 'a', 'c']})
print(S)
one_hot = pd.get_dummies(S['A'])
print(one_hot)

結果:

A    [a, a, c]
dtype: object

   a  c
0  1  0
1  1  0
2  0  1

新しい質問に答える編集

この質問から始めましょう: なぜワンホットエンコーディングを実行するのですか? ['a','b','c'] のようなカテゴリ データを整数 [1,2,3] にエンコードする場合 (たとえば、LableEncoder を使用)、カテゴリ データのエンコードに加えて、次のようにいくつかの重みを与えます。 1 < 2 < 3. このエンコード方法は、RandomForest などの一部の機械学習手法では問題ありません。しかし、多くの機械学習手法では、この場合、それぞれ 1、2、3 でエンコードした場合、'a' < 'b' < 'c' であると想定されます。この問題を回避するために、データ内の一意のカテゴリ変数ごとに列を作成できます。つまり、カテゴリ変数ごとに新しい機能を作成します (ここでは、'a' に 1 列、'b' に 1 列、'c' に 1 列)。

あなたの例の配列の場合、1 つのホット エンコーダーは次のようになります。

features ->  A   B   C   D 

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

4 つのカテゴリ変数 "A"、"B"、"C"、"D" があります。したがって、OneHotEncoder は (4,) 配列を (4,4) に設定して、各カテゴリ変数 (新しい特徴になります) に対して 1 つのベクトル (または列) を持ちます。「A」は配列の 0 要素であるため、最初の列のインデックス 0 は 1 に設定され、残りは 0 に設定されます。同様に、2 番目のベクトル (列) は機能「B」に属し、「B」は配列のインデックス 1 では、「B」ベクトルのインデックス 1 が 1 に設定され、残りはゼロに設定されます。同じことが残りの機能にも当てはまります。

配列を変更させてください。ラベルエンコーダーの仕組みをよりよく理解するのに役立つかもしれません:

S = np.array(['D', 'B','C','A'])
S = le.fit_transform(S)
enc = OneHotEncoder()
encModel = enc.fit_transform(S.reshape(-1,1)).toarray()
print(encModel)

結果は次のとおりです。ここで、最初の列は「A」であり、配列の最後の要素 (インデックス = 3) であるため、最初の列の最後の要素は 1 になります。

features ->  A   B   C   D
          [[ 0.  0.  0.  1.]
           [ 0.  1.  0.  0.]
           [ 0.  0.  1.  0.]
           [ 1.  0.  0.  0.]]

あなたのパンダのデータフレームに関してdataFeat、あなたはどのように機能するかについての最初のステップでも間違っていますLableEncoder。適用するLableEncoderと、その時点で各列に収まり、エンコードされます。次に、次の列に移動し、その列に新しいフィットを作成します。これがあなたが得るべきものです:

from sklearn.preprocessing import LabelEncoder
df =  pd.DataFrame({'Feat1': ['A','B','D','C'],'Feat2':['B','B','D','C'],'Feat3':['A','C','A','A'],
                    'Feat4':['A','C','A','A'],'Feat5':['A','C','B','A']})
print('my data frame:')
print(df)

le = LabelEncoder()
intIndexed = df.apply(le.fit_transform)
print('Encoded data frame')
print(intIndexed)

結果:

my data frame:
  Feat1 Feat2 Feat3 Feat4 Feat5
0     A     B     A     A     A
1     B     B     C     C     C
2     D     D     A     A     B
3     C     C     A     A     A

Encoded data frame
   Feat1  Feat2  Feat3  Feat4  Feat5
0      0      0      0      0      0
1      1      0      1      1      2
2      3      2      0      0      1
3      2      1      0      0      0

最初の列Feat1の「A」は 0 にエンコードされますが、2 番目の列Feat2の「B」要素は 0 であることに注意してください。これは、LableEncoder各列に適合し、個別に変換するために発生します。('B', 'C', 'D') の 2 番目の列では、変数 'B' がアルファベット順で上位にあることに注意してください。

そして最後に、これがあなたが探しているものですsklearn

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder

encoder = OneHotEncoder()
label_encoder = LabelEncoder()
data_lable_encoded = df.apply(label_encoder.fit_transform).as_matrix()
data_feature_onehot = encoder.fit_transform(data_lable_encoded).toarray()
print(data_feature_onehot)

これにより、次のことが得られます。

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

を使用pandasすると、結果を比較でき、うまくいけばより良い直感が得られます。

encoded = pd.get_dummies(df)
print(encoded)

結果:

     Feat1_A  Feat1_B  Feat1_C  Feat1_D  Feat2_B  Feat2_C  Feat2_D  Feat3_A  \
0        1        0        0        0        1        0        0        1   
1        0        1        0        0        1        0        0        0   
2        0        0        0        1        0        0        1        1   
3        0        0        1        0        0        1        0        1   

     Feat3_C  Feat4_A  Feat4_C  Feat5_A  Feat5_B  Feat5_C  
0        0        1        0        1        0        0  
1        1        0        1        0        0        1  
2        0        1        0        0        1        0  
3        0        1        0        1        0        0  

これはまったく同じです。

于 2016-08-17T05:09:00.460 に答える