預處理的作用主要在於將難以表達的string或者陣列轉換成模型容易訓練的向量表示,其中轉化過程大多是形成一張查詢表用來查詢。
常見的預處理方式包括:
-
class Discretization: Buckets data into discrete ranges.
-
class Hashing: Implements categorical feature hashing, also known as "hashing trick".
-
class IntegerLookup: Maps integers from a vocabulary to integer indices.
-
class Normalization: Feature-wise normalization of the data.
-
class StringLookup: Maps strings from a vocabulary to integer indices.
接下來,本文將介紹下這些常用的預處理方式的作用和內容
Discretization
離散化層。該層將其輸入資料的每個元素放入幾個連續的範圍之一,並輸出一個整數索引,指示每個元素位於哪個範圍。這個索引也就是索引編號,透過分桶邊界值判斷輸入的數字屬於哪個分桶,以此給出桶號。
換句話說,它的作用在於將連續的數值特徵轉換為整數分類特徵。
在2.5版本的tf當中,該層的入參只有一個分桶邊界bins,用法為:
tf.keras.layers.experimental.preprocessing.Discretization(
bins, **kwargs
)
在2.11版本的tf當中,Discretization層被定義為
tf.keras.layers.Discretization(
bin_boundaries=None,
num_bins=None,
epsilon=0.01,
output_mode='int',
sparse=False,
**kwargs
)
其中多了一個epsilon,用來作為誤差容忍度,通常是一個接近於零的小分數(例如0.01)。較大的epsilon值會增加分位數近似,從而導致更多不相等的桶,但可以提高效能和資源消耗。
另外還多了一個output_mode:
-
"int":直接返回離散化的bin索引。
-
"one_hot":將輸入中的每個元素編碼到與num_bins大小相同的陣列中,在輸入的bin索引處包含一個1。如果最後一個維度的大小為1,則對該維度進行編碼。如果最後一個維度的大小不是1,則將為編碼後的輸出追加一個新維度。
-
"multi_hot":將輸入中的每個樣本編碼到與num_bins大小相同的單個陣列中,為樣本中出現的每個bin索引索引包含一個1。將最後一個維度作為樣本維度,如果輸入形狀為(…, sample_length),輸出形狀將是(…, num_tokens)。
-
"count":作為"multi_hot",但int陣列包含bin索引在示例中出現次數的計數。
舉一個現有的官方的例子:
>>> input = np.array([[-1.5, 1.0, 3.4, .5], [0.0, 3.0, 1.3, 0.0]])
>>> layer = tf.keras.layers.experimental.preprocessing.Discretization(
... bins=[0., 1., 2.])
>>> layer(input)
<tf.Tensor: shape=(2, 4), dtype=int32, numpy=
array([[0, 1, 3, 1],
[0, 3, 2, 0]], dtype=int32)>
在這個例子中,傳入的引數 bins=[0., 1., 2.]
代表著該層以0、1、2 作為數值邊界進行分桶,所以整體的查詢表大概如下所示:
bin | <0 | 0~1 | 1~2 | >2 |
---|---|---|---|---|
index | 0 | 1 | 2 | 3 |
結合著官方的例子,處於邊界值上的數值,會被歸於前一個桶。比如第一行第二個數字數值為1,會被分桶成編號為1。
其中Discretization層呼叫了bucket進行分桶
要注意的是,這些層是不可訓練的。它們的狀態在訓練期間沒有設定;它必須在訓練之前設定,或者透過從預先計算的常數初始化它們,或者透過在資料上“調整”它們。