美文网首页
3_feature_columns

3_feature_columns

作者: happy_19 | 来源:发表于2018-06-12 20:06 被阅读58次

文本主要记录feature columns的相关内容。feature columns是原始数据鱼Estimator之间的媒介,其内容比较丰富,可以将各种各样的原始数据转换为Estimator可以用的格式。无论如何,深度神经网络可以处理的数据类型一定是数字。但是在实际使用时,原始输入的数据可能并不是数值型的,可能是类别或者其他非数值数据。为了让深度神经网络可以接收并处理各种各样的原始数据,就需要对使用tf.feature_column这个模块来创建模型可使用的各种feature columns。这里主要介绍下图涉及的九个方法:

feature_columns

1. Numeric column

tf.feature_column.numeric_column主要处理的是原始数据是实数(默认为tf.float32),这样的特征值模型可以直接使用,并不需要做其他任何转换。调用方法如下所示:

numeric_feature_column = tf.feature_column.numeric_column(key="SpalLength")

上述调用默认使用tf.float32作为数据类型,也可以通过dtype来指定数据类型,如下所示:

numeric_feature_column = tf.feature_column.numeric_column(
    key="SepalLength",
    dtype=tf.float64)

默认情况下,创建的是一个单值(标量)。可以使用shape参数来指定其他形状,如下所示:

# 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

当我们需要对数值在一定范围内将其分为不同的类型时,就需要创建Bucketized column,主要使用tf.feature_column.bucketized_column。例如以人的年龄数据为例,我们并不以其真实年龄值作为特征值,而是将年龄分为如下几个bucket中:

年龄范围 特征表示
<18 0
>=18 && <30 1
>= 30 && <45 2
>= 45 && < 60 3
>=60 4

示例如下:

# 首先将原始数据转换成numeric column
numeirc_feature_column = tf.feature_column.numeric_column("age")
# 然后,将numeric column转换成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用来实现分类标识列。可以将其视为一同特殊的bucketized column,在bucketized column中一个bucket代表一系列的原始值,在categorical identity column中每个bucket表示唯一的整数。例如,要将2, 4, 6, 7四个数字对应的categorical identity column如下表所示:

原始数值 特征表示
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

有时候,特征的原始输入是字符串,模型并不能处理字符串,这里就需要将字符串映射到数组或者分类值。其中,categorical vocabulate column提供了一种将字符串表示为one-hot向量的方法,如下表所示:

原始字符串 特征表示
kitchenware 0
ele [1
sports 2

这里主要可以通过如下两个接口来实现:

  • 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"]
)

当词汇表非常长的时候,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行,内容如下:

kitchenware
ele
sports

5. Hashed Column

上述处理的类别都是比较少的类别,当类别非常多时,无法为每个词汇单独设置一个one-hot向量。于是就可以使用tf.feature_column.categorical_column_with_hash_bucket将各个类别映射到不同的整数。这种方式不可避免的将不同的类别映射到同一整数,不过这并不会对模型的处理产生负面影响。具体做法是,首先计算原始数据的hash值;然后用hash值对hash_buckets_size取模运算,这样就将原始数据映射到了hash_buckets_size范围内的整数类别中了。如下图所示:

categorical hash bucket
代码如下:
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用来将多个特征组合成一个特征。假设我们希望模型计算佐治亚州亚特兰大的房地产价格。这个城市的房地产价格在不同位置差异很大。在确定对房地产位置的依赖性方面,将纬度和经度表示为单独的特征用处不大;但是,将纬度和经度组合为一个特征则可精确定位位置。假设我们将亚特兰大表示为一个 100x100 的矩形网格区块,按纬度和经度的特征组合标识全部 10000 个区块。借助这种特征组合,模型可以针对与各个区块相关的房价条件进行训练,这比单独的经纬度信号强得多。具体代码如下:

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将每个类别转换成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就不合适了,模型也根本没办法处理(内存存不下了)。这是可以使用embedding column来解决这个问题。embedding column是将多维one-hot向量表示为低维普通向量,其中的元素并不是0和1而是一个确定的数值。同时embedding column的维度要远远小于indicator column,而且可以更加丰富的表现分类的内容。
接下来看一下embedding column和indicator column之间的区别。假设输入样本包含多个不同的词(取自仅有81个词的有限词汇表)。假设数据集在4个不同的样本中提供了如下输入词:

dog
spoon
scissors
guitar

下图分别说明了embedding column和indicator column的处理流程:


embedding_vs_indicator

embedding column中的值是在训练期间进行分配的。embedding column可以增强模型的功能,因为在训练过程中模型学习了类别之间的其他关系。关于embedding后续还会详细介绍。embedding column的维度是由原始类别的个数决定,一般采用如下公式进行确定:

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)

相关文章

  • 3_feature_columns

    文本主要记录feature columns的相关内容。feature columns是原始数据鱼Estimator...

网友评论

      本文标题:3_feature_columns

      本文链接:https://www.haomeiwen.com/subject/cnpheftx.html