美文网首页
Tensorflow特征列

Tensorflow特征列

作者: YANWeichuan | 来源:发表于2018-08-02 15:22 被阅读0次

    特征列

    特征列是将原始数据转换成机器能识别处理的一种格式。特征列在输入数据(由 input_fn 返回)与模型之间架起了桥梁。

    在鸢尾花的识别实例中

    # Feature columns describe how to use the input.
    my_feature_columns = []
    for key in train_x.keys():
        my_feature_columns.append(tf.feature_column.numeric_column(key=key))
    print(my_feature_columns)
    

    打印my_feature_columns的结果:

    [
    _NumericColumn(key='SepalLength', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None), 
    _NumericColumn(key='SepalWidth', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None), 
    _NumericColumn(key='PetalLength', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None),
     _NumericColumn(key='PetalWidth', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=None)
    ]
    

    Tensorflow支持的特征列

    数值列 - tf.feature_column.numeric_column

    定义

    
    tf.feature_column.numeric_column(
        key,
        shape=(1,),
        default_value=None,
        dtype=tf.float32,
        normalizer_fn=None
    )
    

    测试代码

    import tensorflow as tf
    
    test = {'test': [[0.], [1.], [2.], [3.], [4.], [5.]]}
    column = tf.feature_column.numeric_column(key = 'test')
    tensor = tf.feature_column.input_layer(test,[column])
    
    with tf.Session() as session:
        print(session.run([tensor]))
    

    输出结果

    [array([[0.],
           [1.],
           [2.],
           [3.],
           [4.],
           [5.]], dtype=float32)]
    

    分桶列 - tf.feature_column.bucketized_column

    以表示房屋建造年份的原始数据为例。我们并非以标量数值列表示年份,而是将年份分成下列四个分桶:

    将年份数据分成四个分桶

    实际表示的意义如下表

    日期范围 表示
    < 1960 年 [1, 0, 0, 0]
    >= 1960 年但 < 1980 年 [0, 1, 0, 0]
    >= 1980 年但 < 2000 年 [0, 0, 1, 0]
    > 2000 年 [0, 0, 0, 1]

    定义

    tf.feature_column.bucketized_column(
        source_column,
        boundaries
    )
    

    实验代码

    import tensorflow as tf
    
    year={"year":[1958, 1978, 1981, 1999, 2005]}
    
    numeric_feature_column = tf.feature_column.numeric_column("year")
    bucketized_feature_column = tf.feature_column.bucketized_column(
        source_column = numeric_feature_column,
        boundaries = [1960, 1980, 2000])
    
    tensor = tf.feature_column.input_layer(year,[bucketized_feature_column])
    
    with tf.Session() as session:
        print(session.run([tensor]))
    

    输出结果

    [array([[1., 0., 0., 0.],
           [0., 1., 0., 0.],
           [0., 0., 1., 0.],
           [0., 0., 1., 0.],
           [0., 0., 0., 1.]], dtype=float32)]
    

    请注意,指定一个三元素边界矢量可创建一个四元素分桶矢量。

    分类标识列 - tf.feature_column.categorical_column_with_identity

    分类标识列映射是一种独热编码。正常情况下,我们要表示分类,4类可以用0,1,2,3这样的数字序列来表示。也可以用向量来表示, 将对应的位置为1,其他位置为0, 例如1表示为[0,1, 0, 0],3表示为[0,0, 0, 1]。

    用向量表示的背后的优势是啥呢?是空间上的距离均等,在数据处理时获得相等的权重。如0,1,2,3表示,0和1之间的距离是1,0和3之间的距离3,而用向量表示后任意两个之间的距离为根号2。

    定义

    tf.feature_column.categorical_column_with_identity(
        key,
        num_buckets,
        default_value=None
    )
    

    测试代码

    import tensorflow as tf
    
    test = {'cat': [1,3,2,0,3]}
    
    column = tf.feature_column.categorical_column_with_identity(
        key='cat',
        num_buckets=4)
    
    indicator = tf.feature_column.indicator_column(column)
    tensor = tf.feature_column.input_layer(test, [indicator])
    
    with tf.Session() as session:
        print(session.run([tensor]))
    

    输出结果

    [array([[0., 1., 0., 0.],
           [0., 0., 0., 1.],
           [0., 0., 1., 0.],
           [1., 0., 0., 0.],
           [0., 0., 0., 1.]], dtype=float32)]
    

    分类词汇列 - tf.feature_column.categorical_column_with_vocabulary_list

    在分类标识列中,我们将数字直接表示为向量。我们不能直接向模型中输入字符串。相反,我们必须首先将字符串映射到数值或分类值。分类词汇列提供了一种将字符串表示为独热矢量的好方法。例如:

    定义

    tf.feature_column.categorical_column_with_vocabulary_list(
        key,
        vocabulary_list,
        dtype=None,
        default_value=-1,
        num_oov_buckets=0
    )
    

    示例代码

    import tensorflow as tf
    
    test = {"test": ["kitchenware", "electronics", "sport", "shirt"]}
    
    vocabulary_feature_column = tf.feature_column.categorical_column_with_vocabulary_list(
            key="test",
            vocabulary_list=["kitchenware", "electronics", "sports"])
    
    indicator = tf.feature_column.indicator_column(vocabulary_feature_column)
    tensor = tf.feature_column.input_layer(test, [indicator])
    
    with tf.Session() as session:
        session.run(tf.global_variables_initializer())
        session.run(tf.tables_initializer())
        print(session.run([tensor]))
    

    输出结果

    [array([[1., 0., 0.],
           [0., 1., 0.],
           [0., 0., 0.],
           [0., 0., 0.]], dtype=float32)]
    

    注意最后一个向量为[0, 0, 0, 0],因为shirt不在vocabulary_list里面

    当词汇表很长时,需要输入的内容太多了。对于此类情况,请改为调用 tf.feature_column.categorical_column_with_vocabulary_file,以便将词汇放在单独的文件中。例如:

    vocabulary_feature_column =
        tf.feature_column.categorical_column_with_vocabulary_file(
            key="test",
            vocabulary_file="product_class.txt",
            vocabulary_size=3)
    

    哈希处列

    前面介绍的方法只能处理比较少的类别。但是通常,类别的数量非常大,以至于无法为每个词汇或整数设置单独的类别,因为这会消耗太多内存。对于此类情况,我们可以反问自己:“我愿意为我的输入设置多少类别?”实际上,,tf.feature_column.categorical_column_with_hash_bucke 函数使您能够指定类别的数量。对于这种类型的特征列,模型会计算输入的哈希值,然后使用模运算符将其置于其中一个 hash_bucket_size 类别中。

    定义

    tf.feature_column.categorical_column_with_hash_bucket(
        key,
        hash_bucket_size,
        dtype=tf.string
    )
    

    示例代码

    import tensorflow as tf
    
    test = {'chars': ['a','c','b','d','e','f','g','b']}  
    
    column = tf.feature_column.categorical_column_with_hash_bucket(
            key='chars',
            hash_bucket_size=5,
        )
    
    indicator = tf.feature_column.indicator_column(column)
    tensor = tf.feature_column.input_layer(test, [indicator])
    
    with tf.Session() as session:
        session.run(tf.global_variables_initializer())
        session.run(tf.tables_initializer())
        print(session.run([tensor]))
    

    输出结果

    [array([[0., 0., 0., 0., 1.],
           [0., 0., 1., 0., 0.],
           [0., 0., 1., 0., 0.],
           [1., 0., 0., 0., 0.],
           [0., 1., 0., 0., 0.],
           [0., 0., 1., 0., 0.],
           [0., 0., 0., 0., 1.],
           [0., 0., 1., 0., 0.]], dtype=float32)]
    

    组合列 - tf.feature_column.crossed_column

    通过将多个特征组合为一个特征称为特征组合,模型可学习每个特征组合的单独权重。将一个城市的纬度和经度表示为单独的特征用处不大;但是,将纬度和经度组合为一个特征则可精确定位位置。假设我们将亚特兰大表示为一个 100x100 的矩形网格区块,按纬度和经度的特征组合标识全部 10000 个区块。借助这种特征组合,模型可以针对与各个区块相关的房价条件进行训练,这比单独的经纬度信号强得多。

    定义

    tf.feature_column.crossed_column(
        keys,
        hash_bucket_size,
        hash_key=None
    )
    

    示例代码

    import tensorflow as tf
    
    featrues = {
            'longtitude': [19,61,30,9,45],
            'latitude': [45,40,72,81,24]
        }
    
    longtitude = tf.feature_column.numeric_column('longtitude')
    latitude = tf.feature_column.numeric_column('latitude')
    
    longtitude_b_c = tf.feature_column.bucketized_column(longtitude, [33,66])
    latitude_b_c  = tf.feature_column.bucketized_column(latitude,[33,66])
    
    column = tf.feature_column.crossed_column([longtitude_b_c, latitude_b_c], 12)
    
    indicator = tf.feature_column.indicator_column(column)
    tensor = tf.feature_column.input_layer(featrues, [indicator])
    
    with tf.Session() as session:
        session.run(tf.global_variables_initializer())
        session.run(tf.tables_initializer())
        print(session.run([tensor]))
    

    输出结果

    [array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
           [0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
           [0., 0., 1., 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., 1., 0., 0., 0., 0., 0., 0.]], dtype=float32)]
    

    嵌入列 - tf.feature_column.embedding_column

    指标列将每个类别视为独热矢量中的一个元素,其中匹配类别的值为 1,其余类别为 0。当数据数量特别大是,这个向量非常大,变得不容易处理。

    嵌入列并非将数据表示为很多维度的独热矢量,而是将数据表示为低维度普通矢量,其中每个单元格可以包含任意数字,而不仅仅是 0 或 1。通过使每个单元格能够包含更丰富的数字,嵌入列包含的单元格数量远远少于指标列。

    假设我们的输入样本包含多个不同的字词(取自仅有 81 个字词的有限词汇表)。我们进一步假设数据集在 4 个不同的样本中提供了下列输入字词:

    为什么示例中的嵌入矢量大小为 3?下面的“公式”提供了关于嵌入维度数量的一般经验法则(类别数量开4次方):
    embedding_dimensions = number_of_categories**0.25

    定义:

    tf.feature_column.embedding_column(
        categorical_column,
        dimension,
        combiner='mean',
        initializer=None,
        ckpt_to_load_from=None,
        tensor_name_in_ckpt=None,
        max_norm=None,
        trainable=True
    )
    

    示例代码

    import tensorflow as tf
    
    features = {'pets': ['dog','cat','rabbit','pig','mouse']}  
    
    pets_f_c = tf.feature_column.categorical_column_with_vocabulary_list(
        'pets',
        ['cat','dog','rabbit','pig'], 
        dtype=tf.string, 
        default_value=-1)
    
    column = tf.feature_column.embedding_column(pets_f_c, 3)
    tensor = tf.feature_column.input_layer(features, [column])
    
    with tf.Session() as session:
        session.run(tf.global_variables_initializer())
        session.run(tf.tables_initializer())
        print(session.run([tensor]))
    

    输出结果:

    [array([[ 0.73085886, -0.47090757,  0.2534118 ],
           [-0.1105554 , -0.4139628 ,  0.13513751],
           [ 1.0573914 ,  0.00786706,  0.00665331],
           [-0.36653328,  0.4501444 ,  0.98030204],
           [ 0.        ,  0.        ,  0.        ]], dtype=float32)]
    

    总结

    参考

    https://tensorflow.google.cn/get_started/feature_columns
    https://www.jianshu.com/p/fceb64c790f3

    相关文章

      网友评论

          本文标题:Tensorflow特征列

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