1. 程式人生 > 其它 >【學術】獨熱編碼如何在Python中排列資料?

【學術】獨熱編碼如何在Python中排列資料?

機器學習演算法不能直接處理分類資料,分類資料必須轉換為數字。這適用於當你處理一個序列分類型別的問題,並計劃使用深度學習方法,比如長短期迴圈神經網路(RNN)時。

在本教程中,你將瞭解如何將您的輸入或輸出序列資料轉換為一個獨熱編碼(one-hot code),以便在Python中深度學習的序列分類問題中使用。

教程概述

本教程分為四個部分:

1. 獨熱編碼是什麼?

2. 手動獨熱編碼

3. 獨熱編碼和scikit-learn

4. 獨熱編碼與Keras

獨熱編碼是什麼?

獨熱編碼是將分類變量表示為二進位制向量。這首先要求將分類值對映到整數值。它是除了整數1以外其他全都是零值的碼制。

獨熱編碼舉例

假設我們有一系列的標籤,其中有“紅色”和“綠色”。我們可以將“紅色”的整數值賦值為0和“綠色”的整數值賦值為1。只要我們總是把這些數字賦值成這類標籤,那麼這就叫做整數編碼。一致性很重要,因此我們可以稍後對編碼進行轉換,並從整數值中獲得標籤。

接下來,我們可以建立一個二元向量來表示每個整數值。向量的長度為2,為2個可能的整數值。被編碼為0的“紅色”標籤將被表示為二進位制向量[1, 0]。反過來,編碼為1的“綠色”標籤將以二進位制向量0表示。

如果我們有序列:

'red','red','green'

我們可以用整數編碼來表示它:

0,0,1

獨熱編碼為:

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

為什麼用一個獨熱編碼?

獨熱編碼使分類資料的表示變得更有表現力。許多機器學習演算法不能直接使用分類資料。分類必須轉換成數字。這對於分類的輸入和輸出變數來說都是必需的。

我們可以直接使用整數編碼,並在需要的地方進行重新編碼。這可能適用於類別和整數值之間存在自然順序關係的問題,比如溫度“cold”、“warm”和“hot”這類的標籤。在沒有順序關係的情況下,可能會出現一些問題,並且允許這種表現傾向於任何關係,可能會破壞學習解決問題的能力。一個例子可能是標籤上的“dog”和“cat”

在這些情況下,我們希望給網路提供更多的表達能力,以便為每個可能的標籤值學習一個概率數字。這同時也可以幫助解決網路模型的問題。當一個獨熱編碼用於輸出變數時,它可能提供比單個標籤更細緻的預測。

手動獨熱編碼

在本例中,我們假設有一個字母中的字元的示例字串(string),但示例序列不包括所有可能的示例。

我們將使用下列字元的輸入序列:

hello world

我們假設所有可能輸入的“universe(宇宙)”是小寫字母的完整字母表,還有“space(空間)”。因此,我們將以此作為一個藉口來演示如何滾動我們自己的獨熱編碼。

完整的例子如下所列:

from numpyimport argmax
# define input string
data= 'hello world'
print(data)
# define universe of possible input values
alphabet= 'abcdefghijklmnopqrstuvwxyz '
# define a mapping of chars to integers
char_to_int= dict((c, i)for i, cin enumerate(alphabet))
int_to_char= dict((i, c)for i, cin enumerate(alphabet))
# integer encode input data
integer_encoded= [char_to_int[char]for charin data]
print(integer_encoded)
# one hot encode
onehot_encoded= list()
for valuein integer_encoded:
    letter= [0 for _in range(len(alphabet))]
    letter[value]= 1
    onehot_encoded.append(letter)
print(onehot_encoded)
# invert encoding
inverted= int_to_char[argmax(onehot_encoded[0])]
print(inverted)

執行該示例首先列印輸入string。

所有可能輸入的對映都是從char values建立到整數值的。然後,該對映用於對輸入string進行編碼。我們可以看到,在輸入’h’時的第一個字母被編碼為7,或者是在可能輸入值(字母表)陣列中的index 7。

然後將整數編碼轉換為獨熱編碼。一次完成一個整數編碼的字元。一個0值的列表被建立成字母表的長度,這樣任何期望的字元都可以被表示出來。

接下來,特定字元的index標記為1。我們可以看到,第一個字母“h”整數編碼為7,由一個長度為27的二進位制向量和標記為1的7th index表示。

最後,我們對第一個字母的編碼進行轉換,然後列印結果。我們通過使用NumPy argmax()函式查詢具有最大值的二進位制向量的index,然後在字元值變整數的反向查詢表中來使用整數值。

注:輸出被格式化是為了便於閱讀

hello world

[7,4,11,11,14,26,22,14,17,11,3]

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

h

既然我們已經瞭解瞭如何從頭開始滾動自己的獨熱編碼,那麼讓我們看看如何使用scikit-learn庫來自動執行這個對映,在輸入序列完全捕獲了預期的輸入值範圍的情況下。

獨熱編碼和scikit-learn

在本例中,我們將假設您有以下3個標籤的輸出序列:

"cold"
"warm"
"hot"

10個時間步長的示例序列可能是:

cold, cold, warm, cold, hot, hot, warm, cold, warm, hot

這首先需要一個整數編碼,比如1、2、3。然後是整數獨熱編碼的整數到一個有3個值的二元向量,比如[1, 0, 0]。序列至少提供了序列中每個可能值的一個例子。因此,我們可以使用自動的方法來定義標籤的對映到整數和整數到二進位制的向量。

在本例中,我們將使用來自scikit-learn庫的編碼器,具體來說,建立一個標籤的整數編碼的LabelEncoder和用OneHotEncoder 來建立整數編碼值的獨熱編碼。

完整的示例如下所示:

from numpyimport array
from numpyimport argmax
from sklearn.preprocessingimport LabelEncoder
from sklearn.preprocessingimport OneHotEncoder
# define example
data= ['cold','cold','warm','cold','hot','hot','warm','cold','warm','hot']
values= array(data)
print(values)
# integer encode
label_encoder= LabelEncoder()
integer_encoded= label_encoder.fit_transform(values)
print(integer_encoded)
# binary encode
onehot_encoder= OneHotEncoder(sparse=False)
integer_encoded= integer_encoded.reshape(len(integer_encoded),1)
onehot_encoded= onehot_encoder.fit_transform(integer_encoded)
print(onehot_encoded)
# invert first example
inverted= label_encoder.inverse_transform([argmax(onehot_encoded[0, :])])
print(inverted)

執行示例首先列印標籤序列。這之後是標籤的整數編碼,最後是一個獨熱編碼。培訓資料包含所有可能示例的集合,因此我們可以依賴於整數和獨熱編碼轉換,從而建立一個完整的分類到編碼的對映。

預設情況下,OneHotEncoder類將返回更高效的sparse編碼。這可能不適用於某些應用程式,例如使用Keras深度學習庫。在這種情況下,我們通過設定sparse = False引數來禁用sparse返回型別。

如果我們在這個3-value的獨熱編碼中收到一個預測,我們可以很容易地將變換反轉回原始標記。首先,我們可以使用argmax()NumPy函式來定位具有最大值的列的索引。然後可以將其輸入到LabelEncoder中,以計算返回到文字標籤的逆轉換。示例末尾演示了第一個獨熱編碼示例的逆轉換返回到標籤值“cold”的過程。

再次強調,輸入是為了可讀性而格式化的。

['cold' 'cold' 'warm' 'cold' 'hot' 'hot' 'warm' 'cold' 'warm' 'hot']

[0 0 2 0 1 1 2 0 2 1]

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

['cold']

在下一個例子中,我們來看一下如何直接對整數值進行獨熱編碼。

獨熱編碼與Keras

你可能有一個已經被編碼成整數的序列。在縮放之後,你可以直接處理整數。另一種方法是,可以直接對整數進行編碼。如果這些整數沒有真正的順序關係,並且只是標計的佔位符,那麼這一點很重要。Keras庫提供了一個名為to_categorical()的函式,你可以使用獨熱編碼的整數資料。

在這個例子中,我們有4個整數值[0,1,2,3],我們有以下10個數字的輸入序列:

data= [1,3,2,0,3,2,2,1,0,1]

該序列具有所有已知值的示例,因此我們可以直接使用to_categorical()函式。或者,如果序列基於0(從0開始)並且不代表所有可能的值,那麼我們可以指定num_classes引數to_categoryical(num_classes = 4)

以下列出了此功能的完整示例:

from numpyimport array
from numpyimport argmax
from keras.utilsimport to_categorical
# define example
data= [1,3,2,0,3,2,2,1,0,1]
data= array(data)
print(data)
# one hot encode
encoded= to_categorical(data)
print(encoded)
# invert encoding
inverted= argmax(encoded[0])
print(inverted)

執行該示例首先定義並列印輸入序列。然後,這些整數被編碼為二進位制向量,並被打印出來。我們可以看到,第一個整數值1被編碼為[0, 1, 0, 0],就像我們期望的那樣。然後,我們在序列的第一個值中使用NumPy argmax()函式來反轉編碼,為第一個整數返回到期望值1。

[1 3 2 0 3 2 2 1 0 1]

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

1

在本教程中,你發現如何使用Python中獨熱編碼對你的分類序列資料進行深度學習編碼。

具體來說,你學到了:

  • 什麼是整數編碼和獨熱編碼,為什麼它們在機器學習中是必需的。
  • 如何在Python中動手計算一個整數編碼和獨熱編碼。
  • 如何使用scikit-learn和Keras庫來自動對Python中的序列資料進行編碼。