長短期記憶(LSTM)系列_LSTM的資料準備(2)——如何編寫OneHotEncoder(熱編碼)序列資料
導讀:
什麼是熱編碼,原意是OneHotEncoder,OneHotEncoder就是把一些有意義的文字或符號轉換成及其能讀懂的語言。
我們有時想對一系列有意義的資料進行處理或者預測,但這種有意義的資料不一定是數字,有可能是英文,漢字,標記,我們可以對其分類,然後用特定的數字編碼(代替)他們。而不同的編碼方式有著不同的表現力。
OneHotEncoder的工作示例
讓我們用一個有效的例子來具體化。
假設我們有一系列標籤,其值為“紅色”和“綠色”。
我們可以將'red'指定為0的整數值,將'green'指定為整數值1.只要我們總是將這些數字指定給這些標籤,就稱為整數編碼。一致性很重要,以便我們可以稍後反轉編碼並從整數值返回標籤,例如在進行預測時。
接下來,我們可以建立一個二進位制向量來表示每個整數值。對於2個可能的整數值,向量的長度為2。
編碼為0的“紅色”標籤將用二進位制向量[1,0]表示,其中第零個索引用值1標記。反過來,編碼為1的“綠色”標籤將用二進位制向量[0,1],其中第一個索引標記為值1。
如果我們有序列:
1 |
'red', 'red', 'green' |
我們可以用整數編碼來表示它:
1 |
0, 0, 1 |
和熱門編碼:
1 2 3 |
[1, 0] [1, 0] [0, 1] |
為什麼要使用OneHotEncoder?
OneHotEncoder允許分類資料的表示更具表現力。
許多機器學習演算法無法直接使用分類資料。必須將類別轉換為數字。這對於分類的輸入和輸出變數都是必需的。
我們可以直接使用整數編碼,在需要的地方重新調整。這可能適用於類別之間存在自然序數關係的問題,反過來又是整數值,例如溫度“冷”,“暖”和“熱”的標籤。
當沒有順序關係並且允許表示依賴任何這樣的關係可能有損於學習解決問題時可能存在問題。一個例子可能是標籤'dog'和'cat'
在這些情況下,我們希望為網路提供更具表現力的能力,以便為每個可能的標籤值學習類似概率的數字。這有助於使問題更容易網路建模。當
手動OneHotEncoder
在這個例子中,我們假設我們有一個字母字母的示例字串,但示例序列並未涵蓋所有可能的示例。
我們將使用以下字元的輸入序列:
1 |
hello world |
我們將假設所有可能輸入的範圍是小寫字元和空格的完整字母表。因此,我們將以此為藉口演示如何推出自己的熱編碼。
下面列出了完整的示例。
from numpy import argmax
# 定義一個編碼字串
data = 'hello world'
print(data)
# 定義輸入值得所有分類型別
alphabet = 'abcdefghijklmnopqrstuvwxyz '
# define a mapping of chars to integers
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# 轉換成整形編碼輸入
integer_encoded = [char_to_int[char] for char in data]
print(integer_encoded)
# 編碼過程
onehot_encoded = list()
for value in integer_encoded:
letter = [0 for _ in range(len(alphabet))]
letter[value] = 1
onehot_encoded.append(letter)
print(onehot_encoded)
# 逆轉換第一行資料
inverted = int_to_char[argmax(onehot_encoded[0])]
從char值到整數值建立所有可能輸入的對映。然後使用該對映對輸入字串進行編碼。我們可以看到輸入'h'中的第一個字母編碼為7,或者可能輸入值(字母表)陣列中的索引7。首先執行該示例列印輸入字串。
然後將整數編碼轉換為OneHotEncoder。這是一次完成一個整數編碼字元。將建立0值的列表作為字母表的長度,以便可以表示任何預期的字元。
接下來,特定字元的索引標記為1.我們可以看到編碼為7的第一個字母'h'整數由長度為27且第7個索引標記為1的二進位制向量表示。
最後,我們反轉第一個字母的編碼並列印結果。我們通過使用NumPy argmax()函式定位具有最大值的二進位制向量中的索引,然後在字元值的反向查詢表中使用整數值來實現此操作。
注意:輸出格式化是為了便於閱讀。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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庫自動執行此對映。
OneHotEncoder與scikit學習
在此示例中,我們假設您具有以下3個標籤的輸出序列:
1 2 3 |
"cold" "warm" "hot" |
10個時間步驟的示例序列可以是:
1 |
cold, cold, warm, cold, hot, hot, warm, cold, warm, hot |
這首先需要整數編碼,例如1,2,3。這之後是整數的一個熱編碼到具有3個值的二進位制向量,例如[1,0,0]。
該序列提供序列中每個可能值的至少一個示例。因此,我們可以使用自動方法來定義標籤到整數和整數到二進位制向量的對映。
在本例中,我們將使用scikit-learn庫中的編碼器。具體來說,LabelEncoder用於建立標籤的整數編碼,而OneHotEncoder用於建立整數編碼值的OneHotEncoder。
下面列出了完整的示例。
from numpy import array
from numpy import argmax
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# 定義一個例項
data = ['cold', 'cold', 'warm', 'cold', 'hot', 'hot', 'warm', 'cold', 'warm', 'hot']
values = array(data)
print(values)
# 轉換成整形編碼
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(values)
print(integer_encoded)
# 轉換成向量編碼
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)
# 逆轉換第一行資料
inverted = label_encoder.inverse_transform([argmax(onehot_encoded[0, :])])
print(inverted)
訓練資料包含所有可能示例的集合,因此我們可以依賴整數和OneHotEncoder變換來建立標籤到編碼的完整對映。首先執行該示例將列印標籤序列。接下來是標籤的整數編碼,最後是OneHotEncoder。
預設情況下,OneHotEncoder類將返回更有效的稀疏編碼。這可能不適合某些應用程式,例如與Keras深度學習庫一起使用。在這種情況下,我們通過設定sparse = False引數來禁用稀疏返回型別。
如果我們在這個3值熱編碼中接收到預測,我們可以輕鬆地將變換反轉回原始標籤。
首先,我們可以使用argmax()NumPy函式來定位具有最大值的列的索引。然後可以將其饋送到LabelEncoder以計算反向變換回文字標籤。
這在示例的結尾處被證明,其中第一個熱編碼示例的逆變換返回到標籤值'cold'。
再次注意,輸入的格式是為了便於閱讀。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
['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'] |
在下一個例子中,我們看看如何直接對一個整數值序列進行熱編碼。
OneHotEncoder與Keras
您可能有一個已經整數編碼的序列。
在進行一些縮放之後,您可以直接使用整數。或者,您可以直接對整數進行熱編碼。如果整數沒有真正的序數關係並且實際上只是標籤的佔位符,這一點很重要。
Keras庫提供了一個名為to_categorical()的函式,您可以將其用於OneHotEncoder整數資料。
在這個例子中,我們有4個整數值[0,1,2,3],我們有以下10個數字的輸入序列:
1 |
data = [1, 3, 2, 0, 3, 2, 2, 1, 0, 1] |
序列有一個所有已知值的示例,因此我們可以直接使用to_categorical()函式。或者,如果序列從0開始(從0開始)並且不代表所有可能的值,我們可以指定num_classes引數to_categorical(num_classes = 4)。
下面列出了此功能的完整示例。
from numpy import argmax
# 定義一個編碼字串
data = 'hello world'
print(data)
# 定義輸入值得所有分類型別
alphabet = 'abcdefghijklmnopqrstuvwxyz '
# define a mapping of chars to integers
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# 轉換成整形編碼輸入
integer_encoded = [char_to_int[char] for char in data]
print(integer_encoded)
# 編碼過程
onehot_encoded = list()
for value in integer_encoded:
letter = [0 for _ in range(len(alphabet))]
letter[value] = 1
onehot_encoded.append(letter)
print(onehot_encoded)
# 逆轉換第一行資料
inverted = int_to_char[argmax(onehot_encoded[0])]
然後將整數編碼為二進位制向量並列印。我們可以看到第一個整數值1被編碼為[0,1,0,0]就像我們期望的那樣。首先執行示例定義並列印輸入序列。
然後,我們通過在序列中的第一個值上使用NumPy argmax()函式來反轉編碼,該函式返回第一個整數的期望值1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[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 |