文本主要記錄feature columns
的相關(guān)內(nèi)容撰茎。feature columns
是原始數(shù)據(jù)魚Estimator之間的媒介银酬,其內(nèi)容比較豐富洛姑,可以將各種各樣的原始數(shù)據(jù)轉(zhuǎn)換為Estimator可以用的格式蒜鸡。無論如何蜓洪,深度神經(jīng)網(wǎng)絡(luò)可以處理的數(shù)據(jù)類型一定是數(shù)字纤勒。但是在實際使用時,原始輸入的數(shù)據(jù)可能并不是數(shù)值型的隆檀,可能是類別或者其他非數(shù)值數(shù)據(jù)摇天。為了讓深度神經(jīng)網(wǎng)絡(luò)可以接收并處理各種各樣的原始數(shù)據(jù),就需要對使用tf.feature_column
這個模塊來創(chuàng)建模型可使用的各種feature columns
恐仑。這里主要介紹下圖涉及的九個方法:
1. Numeric column
tf.feature_column.numeric_column
主要處理的是原始數(shù)據(jù)是實數(shù)(默認為tf.float32)泉坐,這樣的特征值模型可以直接使用,并不需要做其他任何轉(zhuǎn)換裳仆。調(diào)用方法如下所示:
numeric_feature_column = tf.feature_column.numeric_column(key="SpalLength")
上述調(diào)用默認使用tf.float32作為數(shù)據(jù)類型腕让,也可以通過dtype
來指定數(shù)據(jù)類型,如下所示:
numeric_feature_column = tf.feature_column.numeric_column(
key="SepalLength",
dtype=tf.float64)
默認情況下歧斟,創(chuàng)建的是一個單值(標(biāo)量)纯丸∑危可以使用shape參數(shù)來指定其他形狀,如下所示:
# Represent a 10-element vector in which each cell contains a tf.float32.
vector_feature_column = tf.feature_column.numeric_column(
key="Bowling",
shape=10,
)
# Represent a 10x5 matrix in which each cell contains a tf.float32.
matrix_feature_column = tf.feature_column.numeric_column(
key="MyMatrix",
shape=[10, 5],
)
2. Bucketized column
當(dāng)我們需要對數(shù)值在一定范圍內(nèi)將其分為不同的類型時液南,就需要創(chuàng)建Bucketized column壳猜,主要使用tf.feature_column.bucketized_column
。例如以人的年齡數(shù)據(jù)為例滑凉,我們并不以其真實年齡值作為特征值统扳,而是將年齡分為如下幾個bucket中:
年齡范圍 | 特征表示 |
---|---|
<18 | 0 |
>=18 && <30 | 1 |
>= 30 && <45 | 2 |
>= 45 && < 60 | 3 |
>=60 | 4 |
示例如下:
# 首先將原始數(shù)據(jù)轉(zhuǎn)換成numeric column
numeirc_feature_column = tf.feature_column.numeric_column("age")
# 然后,將numeric column轉(zhuǎn)換成buckeized column
bucketized_feature_column = tf.feature_column.bucketized_column(
source_column = numeric_feature_column,
boundries = [18, 30, 45, 60]
)
這里需要注意的是要分成5個buckets畅姊,boundries
需要指定4個分界就可以了咒钟。
3. Categorical identity column
tf.feature_column.categorical_column_with_identity
用來實現(xiàn)分類標(biāo)識列∪粑矗可以將其視為一同特殊的bucketized column朱嘴,在bucketized column中一個bucket代表一系列的原始值,在categorical identity column中每個bucket表示唯一的整數(shù)粗合。例如萍嬉,要將2, 4, 6, 7四個數(shù)字對應(yīng)的categorical identity column如下表所示:
原始數(shù)值 | 特征表示 |
---|---|
2 | 0 |
4 | 1 |
6 | 2 |
7 | 3 |
示例代碼如下:
identity_feature_column = tf.feature_column.categorical_column_with_identity(
key = "my_feature",
num_buckets = 4,
)
4. Categorical vocabulate column
有時候,特征的原始輸入是字符串隙疚,模型并不能處理字符串壤追,這里就需要將字符串映射到數(shù)組或者分類值。其中供屉,categorical vocabulate column提供了一種將字符串表示為one-hot向量的方法行冰,如下表所示:
原始字符串 | 特征表示 |
---|---|
kitchenware | 0 |
ele | [1 |
sports | 2 |
這里主要可以通過如下兩個接口來實現(xiàn):
tf.feature_column.categorical_column_with_vocabulary_list
-
tf.feature_column.categorical_column_with_vocabulary_file
示例代碼如下:
vocabulary_feature_column = tf.feature_column.categorical_column_with_vocabulary_list(
key = "my_feature",
vocabulary_list = ["kitchenware", "ele", "sports"]
)
當(dāng)詞匯表非常長的時候,vocabulary_list將會是一個非常長的list伶丐。這里就可以改用tf.feature_column.categorical_column_with_vocabulary_file
悼做,tensorflow會從一個單獨的文件中獲取詞匯列表,代碼如下:
vocabulary_feature_column = tf.feature_column.categorical_column_with_vocabulary_file(
key = "my_feature",
vocabulary_file = "vocabulary_file.txt",
vocabulary_size = 3,
其中vocabulary_file.txt
中每一個單詞占一行哗魂,一共3行肛走,內(nèi)容如下:
kitchenware
ele
sports
5. Hashed Column
上述處理的類別都是比較少的類別,當(dāng)類別非常多時啡彬,無法為每個詞匯單獨設(shè)置一個one-hot向量羹与。于是就可以使用tf.feature_column.categorical_column_with_hash_bucket
將各個類別映射到不同的整數(shù)。這種方式不可避免的將不同的類別映射到同一整數(shù)庶灿,不過這并不會對模型的處理產(chǎn)生負面影響纵搁。具體做法是,首先計算原始數(shù)據(jù)的hash值往踢;然后用hash值對hash_buckets_size
取模運算腾誉,這樣就將原始數(shù)據(jù)映射到了hash_buckets_size
范圍內(nèi)的整數(shù)類別中了。如下圖所示:
代碼如下:
hash_feature_column = tf.feature_column.categorical_column_with_hash_bucket(
key = "my_feature",
hash_buckets_size = 100,
)
6. Crossed column
tf.feature_column.crossed_columns
用來將多個特征組合成一個特征。假設(shè)我們希望模型計算佐治亞州亞特蘭大的房地產(chǎn)價格利职。這個城市的房地產(chǎn)價格在不同位置差異很大趣效。在確定對房地產(chǎn)位置的依賴性方面,將緯度和經(jīng)度表示為單獨的特征用處不大猪贪;但是跷敬,將緯度和經(jīng)度組合為一個特征則可精確定位位置。假設(shè)我們將亞特蘭大表示為一個 100x100 的矩形網(wǎng)格區(qū)塊热押,按緯度和經(jīng)度的特征組合標(biāo)識全部 10000 個區(qū)塊西傀。借助這種特征組合,模型可以針對與各個區(qū)塊相關(guān)的房價條件進行訓(xùn)練桶癣,這比單獨的經(jīng)緯度信號強得多拥褂。具體代碼如下:
def make_dataset(latitude, longitude, labels):
assert latitude.shape == longitude.shape == labels.shape
features = {'latitude': latitude.flatten(),
'longitude': longitude.flatten()}
labels=labels.flatten()
return tf.data.Dataset.from_tensor_slices((features, labels))
# Bucketize the latitude and longitude usig the `edges`
latitude_bucket_fc = tf.feature_column.bucketized_column(
tf.feature_column.numeric_column('latitude'),
list(atlanta.latitude.edges))
longitude_bucket_fc = tf.feature_column.bucketized_column(
tf.feature_column.numeric_column('longitude'),
list(atlanta.longitude.edges))
# Cross the bucketized columns, using 5000 hash bins.
crossed_lat_lon_fc = tf.feature_column.crossed_column(
[latitude_bucket_fc, longitude_bucket_fc], 5000)
fc = [
latitude_bucket_fc,
longitude_bucket_fc,
crossed_lat_lon_fc]
# Build and train the Estimator.
est = tf.estimator.LinearRegressor(fc, ...)
crossed column可以對任意特這個進行組合,除了categorical_column_with_hash_bucket
牙寞,因為crossed_column
會對輸入進行hash處理饺鹃。簡單來說其處理過程是這樣的,將原特征組合在一起间雀,然后計算hash悔详,最后對hash值取hash_bucket_size
模。
7. Indicator and embedding column
類別值 | one-hot表示 |
---|---|
0 | [1, 0, 0, 0] |
1 | [0, 1, 0, 0] |
2 | [0, 0, 1, 0] |
3 | [0, 0, 0, 1] |
indicator column和embedding column并不直接處理特征惹挟,而是將分類視為輸入伟端。
indicator column將每個類別轉(zhuǎn)換成one-hot向量,如下表所示
類別值 | one-hot表示 |
---|---|
0 | [1, 0, 0, 0] |
1 | [0, 1, 0, 0] |
2 | [0, 0, 1, 0] |
3 | [0, 0, 0, 1] |
示例代碼如下:
categorical_column = = tf.feature_column.categorical_column_with_vocabulary_list(
key = "my_feature",
vocabulary_list = ["kitchenware", "ele", "sports"]
)
indicator_column = tf.feature_column.indicator_column(categorical_column)
如果我們的輸入有百萬甚至億級的類別時匪煌,使用indicator column就不合適了,模型也根本沒辦法處理(內(nèi)存存不下了)党巾。這是可以使用embedding column來解決這個問題萎庭。embedding column是將多維one-hot向量表示為低維普通向量,其中的元素并不是0和1而是一個確定的數(shù)值齿拂。同時embedding column的維度要遠遠小于indicator column驳规,而且可以更加豐富的表現(xiàn)分類的內(nèi)容。
接下來看一下embedding column和indicator column之間的區(qū)別署海。假設(shè)輸入樣本包含多個不同的詞(取自僅有81個詞的有限詞匯表)吗购。假設(shè)數(shù)據(jù)集在4個不同的樣本中提供了如下輸入詞:
dog
spoon
scissors
guitar
下圖分別說明了embedding column和indicator column的處理流程:
embedding column中的值是在訓(xùn)練期間進行分配的。embedding column可以增強模型的功能砸狞,因為在訓(xùn)練過程中模型學(xué)習(xí)了類別之間的其他關(guān)系捻勉。關(guān)于embedding后續(xù)還會詳細介紹。embedding column的維度是由原始類別的個數(shù)決定刀森,一般采用如下公式進行確定:
embedding_dimensions = number_of_categories**0.25
代碼示例如下所示:
categorical_column = ... # Create any categorical column
# Represent the categorical column as an embedding column.
# This means creating a one-hot vector with one element for each category.
embedding_column = tf.feature_column.embedding_column(
categorical_column=categorical_column,
dimension=dimension_of_embedding_vector)